diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:22 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:22 -0800 |
commit | 7a80622f69812ca3262d2027c07a4ed0c0242945 (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /libelf/nlist.c | |
parent | ee6008996aa701ad2a50d5d6b1529c9e2c2724c1 (diff) | |
download | android_external_elfutils-7a80622f69812ca3262d2027c07a4ed0c0242945.tar.gz android_external_elfutils-7a80622f69812ca3262d2027c07a4ed0c0242945.tar.bz2 android_external_elfutils-7a80622f69812ca3262d2027c07a4ed0c0242945.zip |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'libelf/nlist.c')
-rw-r--r-- | libelf/nlist.c | 224 |
1 files changed, 0 insertions, 224 deletions
diff --git a/libelf/nlist.c b/libelf/nlist.c deleted file mode 100644 index cc42a31e..00000000 --- a/libelf/nlist.c +++ /dev/null @@ -1,224 +0,0 @@ -/* Extract symbol list from binary. - Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. - Written by Ulrich Drepper <drepper@redhat.com>, 1998. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, version 2. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <fcntl.h> -#include <gelf.h> -#include <libelf.h> -#include <nlist.h> -#include <unistd.h> - -#include "libelfP.h" - - -struct hashentry -{ - const char *str; - GElf_Sym sym; -}; -#define TYPE struct hashentry -/* XXX Use a better hash function some day. */ -#define HASHFCT(str, len) INTUSE(elf_hash) (str) -#define COMPARE(p1, p2) strcmp ((p1)->str, (p2)->str) -#define CLASS static -#define PREFIX nlist_ -#define xcalloc(n, m) calloc (n, m) -#define next_prime(s) __libelf_next_prime (s) -#include <fixedsizehash.h> - - -int -nlist (const char *filename, struct nlist *nl) -{ - int fd; - Elf *elf; - Elf_Scn *scn = NULL; - Elf_Scn *symscn = NULL; - GElf_Shdr shdr_mem; - GElf_Shdr *shdr = NULL; - Elf_Data *data; - struct nlist_fshash *table; - size_t nsyms; - size_t cnt; - - /* Open the file. */ - fd = open (filename, O_RDONLY); - if (fd == -1) - { - __libelf_seterrno (ELF_E_NOFILE); - goto fail; - } - - /* For compatibility reasons (`nlist' existed before ELF and libelf) - we don't expect the caller to set the ELF version. Do this here - if it hasn't happened yet. */ - if (__libelf_version_initialized == 0) - INTUSE(elf_version) (EV_CURRENT); - - /* Now get an ELF descriptor. */ - elf = INTUSE(elf_begin) (fd, ELF_C_READ_MMAP, NULL); - if (elf == NULL) - goto fail; - - /* Find a symbol table. We prefer the real symbol table but if it - does not exist use the dynamic symbol table. */ - while ((scn = INTUSE(elf_nextscn) (elf, scn)) != NULL) - { - shdr = INTUSE(gelf_getshdr) (scn, &shdr_mem); - if (shdr == NULL) - goto fail_close; - - /* That is what we are looking for. */ - if (shdr->sh_type == SHT_SYMTAB) - { - symscn = scn; - break; - } - - /* Better than nothing. Remember this section. */ - if (shdr->sh_type == SHT_DYNSYM) - symscn = scn; - } - - if (symscn == NULL) - /* We haven't found anything. Fail. */ - goto fail_close; - - /* Re-get the section header in case we found only the dynamic symbol - table. */ - if (scn == NULL) - shdr = INTUSE(gelf_getshdr) (symscn, &shdr_mem); - /* SHDR->SH_LINK now contains the index of the string section. */ - - /* Get the data for the symbol section. */ - data = INTUSE(elf_getdata) (symscn, NULL); - if (data == NULL) - goto fail_close; - - /* How many symbols are there? */ - nsyms = (shdr->sh_size - / INTUSE(gelf_fsize) (elf, ELF_T_SYM, 1, data->d_version)); - - /* Create the hash table. */ - table = nlist_fshash_init (nsyms); - if (table == NULL) - { - __libelf_seterrno (ELF_E_NOMEM); - goto fail_close; - } - - /* Iterate over all the symbols in the section. */ - for (cnt = 0; cnt < nsyms; ++cnt) - { - struct hashentry mem; - GElf_Sym *sym; - - /* Get the symbol. */ - sym = INTUSE(gelf_getsym) (data, cnt, &mem.sym); - if (sym == NULL) - goto fail_dealloc; - - /* Get the name of the symbol. */ - mem.str = INTUSE(elf_strptr) (elf, shdr->sh_link, sym->st_name); - if (mem.str == NULL) - goto fail_dealloc; - - /* Don't allow zero-length strings. */ - if (mem.str[0] == '\0') - continue; - - /* And add it to the hash table. Note that we are using the - overwrite version. This will ensure that - a) global symbols are preferred over local symbols since - they are all located at the end - b) if there are multiple local symbols with the same name - the last one is used. - */ - (void) nlist_fshash_overwrite (table, mem.str, 0, &mem); - } - - /* Now it is time to look for the symbols the user asked for. - XXX What is a `null name/null string'? This is what the - standard says terminates the list. Is it a null pointer - or a zero-length string? We test for both... */ - while (nl->n_name != NULL && nl->n_name[0] != '\0') - { - struct hashentry search; - const struct hashentry *found; - - /* Search for a matching entry in the hash table. */ - search.str = nl->n_name; - found = nlist_fshash_find (table, nl->n_name, 0, &search); - - if (found != NULL) - { - /* Found it. */ - nl->n_value = found->sym.st_value; - nl->n_scnum = found->sym.st_shndx; - nl->n_type = GELF_ST_TYPE (found->sym.st_info); - /* XXX What shall we fill in the next fields? */ - nl->n_sclass = 0; - nl->n_numaux = 0; - } - else - { - /* Not there. */ - nl->n_value = 0; - nl->n_scnum = 0; - nl->n_type = 0; - nl->n_sclass = 0; - nl->n_numaux = 0; - } - - /* Next search request. */ - ++nl; - } - - /* Free the resources. */ - nlist_fshash_fini (table); - - /* We do not need the ELF descriptor anymore. */ - (void) elf_end (elf); - - return 0; - - fail_dealloc: - nlist_fshash_fini (table); - - fail_close: - /* We do not need the ELF descriptor anymore. */ - (void) elf_end (elf); - - fail: - /* We have to set all entries to zero. */ - while (nl->n_name != NULL && nl->n_name[0] != '\0') - { - nl->n_value = 0; - nl->n_scnum = 0; - nl->n_type = 0; - nl->n_sclass = 0; - nl->n_numaux = 0; - - /* Next entry. */ - ++nl; - } - - return -1; -} |