Branch data Line data Source code
1 : : /* Get section at specific index. 2 : : Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2015 Red Hat, Inc. 3 : : This file is part of elfutils. 4 : : Contributed by Ulrich Drepper <drepper@redhat.com>, 1998. 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 : : 41 : : Elf_Scn * 42 : 37368711 : elf_getscn (Elf *elf, size_t idx) 43 : : { 44 [ - + ]: 37368711 : if (elf == NULL) 45 : : return NULL; 46 : : 47 [ - + ]: 37368711 : if (unlikely (elf->kind != ELF_K_ELF)) 48 : : { 49 : 0 : __libelf_seterrno (ELF_E_INVALID_HANDLE); 50 : 0 : return NULL; 51 : : } 52 : : 53 : 37368711 : rwlock_rdlock (elf->lock); 54 : : 55 : 37368711 : Elf_Scn *result = NULL; 56 : : 57 : : /* Find the section in the list. */ 58 : 37368711 : Elf_ScnList *runp = (elf->class == ELFCLASS32 59 : : || (offsetof (struct Elf, state.elf32.scns) 60 : : == offsetof (struct Elf, state.elf64.scns)) 61 : : ? &elf->state.elf32.scns : &elf->state.elf64.scns); 62 : : 63 : : /* Section zero is special. It always exists even if there is no 64 : : "first" section. And it is needed to store "overflow" values 65 : : from the Elf header. */ 66 [ + + + + : 37368711 : if (idx == 0 && runp->cnt == 0 && runp->max > 0) + - ] 67 : : { 68 : 2 : Elf_Scn *scn0 = &runp->data[0]; 69 [ + - ]: 2 : if (elf->class == ELFCLASS32) 70 : : { 71 : 2 : scn0->shdr.e32 = calloc (1, sizeof (Elf32_Shdr)); 72 [ - + ]: 2 : if (scn0->shdr.e32 == NULL) 73 : : { 74 : 0 : __libelf_seterrno (ELF_E_NOMEM); 75 : 0 : goto out; 76 : : } 77 : : } 78 : : else 79 : : { 80 : 0 : scn0->shdr.e64 = calloc (1, sizeof (Elf64_Shdr)); 81 [ # # ]: 0 : if (scn0->shdr.e64 == NULL) 82 : : { 83 : 0 : __libelf_seterrno (ELF_E_NOMEM); 84 : 0 : goto out; 85 : : } 86 : : } 87 : 2 : scn0->elf = elf; 88 : 2 : scn0->shdr_flags = ELF_F_DIRTY | ELF_F_MALLOCED; 89 : 2 : scn0->list = elf->state.elf.scns_last; 90 : 2 : scn0->data_read = 1; 91 : 2 : runp->cnt = 1; 92 : : } 93 : : 94 : 41684631 : while (1) 95 : : { 96 [ + + ]: 41684631 : if (idx < runp->max) 97 : : { 98 [ + - ]: 37368627 : if (idx < runp->cnt) 99 : 37368627 : result = &runp->data[idx]; 100 : : else 101 : 0 : __libelf_seterrno (ELF_E_INVALID_INDEX); 102 : : break; 103 : : } 104 : : 105 : 4316004 : idx -= runp->max; 106 : : 107 : 4316004 : runp = runp->next; 108 [ + + ]: 4316004 : if (runp == NULL) 109 : : { 110 : 84 : __libelf_seterrno (ELF_E_INVALID_INDEX); 111 : 84 : break; 112 : : } 113 : : } 114 : : 115 : : out: 116 : : rwlock_unlock (elf->lock); 117 : : 118 : : return result; 119 : : } 120 : : INTDEF(elf_getscn)