Branch data Line data Source code
1 : : /* Get section at specific index. 2 : : Copyright (C) 2005, 2008, 2015 Red Hat, Inc. 3 : : This file is part of elfutils. 4 : : Contributed by Ulrich Drepper <drepper@redhat.com>, 2005. 5 : : 6 : : This file is free software; you can redistribute it and/or modify 7 : : it under the terms of either 8 : : 9 : : * the GNU Lesser General Public License as published by the Free 10 : : Software Foundation; either version 3 of the License, or (at 11 : : your option) any later version 12 : : 13 : : or 14 : : 15 : : * the GNU General Public License as published by the Free 16 : : Software Foundation; either version 2 of the License, or (at 17 : : your option) any later version 18 : : 19 : : or both in parallel, as here. 20 : : 21 : : elfutils is distributed in the hope that it will be useful, but 22 : : WITHOUT ANY WARRANTY; without even the implied warranty of 23 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 : : General Public License for more details. 25 : : 26 : : You should have received copies of the GNU General Public License and 27 : : the GNU Lesser General Public License along with this program. If 28 : : not, see <http://www.gnu.org/licenses/>. */ 29 : : 30 : : #ifdef HAVE_CONFIG_H 31 : : # include <config.h> 32 : : #endif 33 : : 34 : : #include <assert.h> 35 : : #include <stddef.h> 36 : : #include <stdlib.h> 37 : : 38 : : #include "libelfP.h" 39 : : 40 : : #ifndef LIBELFBITS 41 : : # define LIBELFBITS 32 42 : : #endif 43 : : 44 : : 45 : : Elf_Scn * 46 : 1100 : elfw2(LIBELFBITS,offscn) (Elf *elf, ElfW2(LIBELFBITS,Off) offset) 47 : : { 48 [ - + ]: 1100 : if (elf == NULL) 49 : : return NULL; 50 : : 51 [ - + ]: 1100 : if (unlikely (elf->kind != ELF_K_ELF)) 52 : : { 53 : 0 : __libelf_seterrno (ELF_E_INVALID_HANDLE); 54 : 0 : return NULL; 55 : : } 56 : : 57 : 1100 : Elf_ScnList *runp = &elf->state.ELFW(elf,LIBELFBITS).scns; 58 : : 59 : : /* If we have not looked at section headers before, 60 : : we might need to read them in first. */ 61 [ + - ]: 1100 : if (runp->cnt > 0 62 [ + + ]: 1100 : && unlikely (runp->data[0].shdr.ELFW(e,LIBELFBITS) == NULL) 63 [ - + ]: 2 : && unlikely (elfw2(LIBELFBITS,getshdr) (&runp->data[0]) == NULL)) 64 : : return NULL; 65 : : 66 : 1100 : rwlock_rdlock (elf->lock); 67 : : 68 : 1100 : Elf_Scn *result = NULL; 69 : : 70 : : /* Find the section in the list. */ 71 : 1100 : while (1) 72 : : { 73 [ + + ]: 22034 : for (unsigned int i = 0; i < runp->cnt; ++i) 74 [ + + ]: 21986 : if (runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_offset == offset) 75 : : { 76 : 1142 : result = &runp->data[i]; 77 : : 78 : : /* If this section is empty, the following one has the same 79 : : sh_offset. We presume the caller is looking for a nonempty 80 : : section, so keep looking if this one is empty. */ 81 [ + - ]: 1142 : if (runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_size != 0 82 [ + + ]: 1142 : && runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_type != SHT_NOBITS) 83 : 1052 : goto out; 84 : : } 85 : : 86 : 48 : runp = runp->next; 87 [ - + ]: 48 : if (runp == NULL) 88 : : { 89 : 48 : __libelf_seterrno (ELF_E_INVALID_OFFSET); 90 : 48 : break; 91 : : } 92 : : } 93 : : 94 : : out: 95 : : rwlock_unlock (elf->lock); 96 : : 97 : : return result; 98 : : } 99 : : INTDEF(elfw2(LIBELFBITS,offscn))