1 /* Get symbol information from symbol table at the given index. 2 Copyright (C) 1999, 2000, 2001, 2002 Red Hat, Inc. 3 Written by Ulrich Drepper <drepper (at) redhat.com>, 1999. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation, version 2. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software Foundation, 16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 17 18 #ifdef HAVE_CONFIG_H 19 # include <config.h> 20 #endif 21 22 #include <assert.h> 23 #include <gelf.h> 24 #include <string.h> 25 26 #include "libelfP.h" 27 28 29 GElf_Sym * 30 gelf_getsym (data, ndx, dst) 31 Elf_Data *data; 32 int ndx; 33 GElf_Sym *dst; 34 { 35 Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; 36 GElf_Sym *result = NULL; 37 38 if (data == NULL) 39 return NULL; 40 41 if (unlikely (data->d_type != ELF_T_SYM)) 42 { 43 __libelf_seterrno (ELF_E_INVALID_HANDLE); 44 return NULL; 45 } 46 47 rwlock_rdlock (data_scn->s->elf->lock); 48 49 /* This is the one place where we have to take advantage of the fact 50 that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'. 51 The interface is broken so that it requires this hack. */ 52 if (data_scn->s->elf->class == ELFCLASS32) 53 { 54 Elf32_Sym *src; 55 56 /* Here it gets a bit more complicated. The format of the symbol 57 table entries has to be adopted. The user better has provided 58 a buffer where we can store the information. While copying the 59 data we are converting the format. */ 60 if (unlikely ((ndx + 1) * sizeof (Elf32_Sym) > data->d_size)) 61 { 62 __libelf_seterrno (ELF_E_INVALID_INDEX); 63 goto out; 64 } 65 66 src = &((Elf32_Sym *) data->d_buf)[ndx]; 67 68 /* This might look like a simple copy operation but it's 69 not. There are zero- and sign-extensions going on. */ 70 #define COPY(name) \ 71 dst->name = src->name 72 COPY (st_name); 73 /* Please note that we can simply copy the `st_info' element since 74 the definitions of ELFxx_ST_BIND and ELFxx_ST_TYPE are the same 75 for the 64 bit variant. */ 76 COPY (st_info); 77 COPY (st_other); 78 COPY (st_shndx); 79 COPY (st_value); 80 COPY (st_size); 81 } 82 else 83 { 84 /* If this is a 64 bit object it's easy. */ 85 assert (sizeof (GElf_Sym) == sizeof (Elf64_Sym)); 86 87 /* The data is already in the correct form. Just make sure the 88 index is OK. */ 89 if (unlikely ((ndx + 1) * sizeof (GElf_Sym) > data->d_size)) 90 { 91 __libelf_seterrno (ELF_E_INVALID_INDEX); 92 goto out; 93 } 94 95 *dst = ((GElf_Sym *) data->d_buf)[ndx]; 96 } 97 98 result = dst; 99 100 out: 101 rwlock_unlock (data_scn->s->elf->lock); 102 103 return result; 104 } 105 INTDEF(gelf_getsym) 106