/* Extract symbol list from binary.
   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2007 Red Hat, Inc.
   This file is part of elfutils.
   Written by Ulrich Drepper <drepper@redhat.com>, 1998.

   This file is free software; you can redistribute it and/or modify
   it under the terms of either

     * the GNU Lesser General Public License as published by the Free
       Software Foundation; either version 3 of the License, or (at
       your option) any later version

   or

     * the GNU General Public License as published by the Free
       Software Foundation; either version 2 of the License, or (at
       your option) any later version

   or both in parallel, as here.

   elfutils 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 copies of the GNU General Public License and
   the GNU Lesser General Public License along with this program.  If
   not, see <http://www.gnu.org/licenses/>.  */

#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_fd;

  /* 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) INTUSE(elf_end) (elf);

  /* Neither the file descriptor.  */
  (void) close (fd);

  return 0;

 fail_dealloc:
  nlist_fshash_fini (table);

 fail_close:
  /* We do not need the ELF descriptor anymore.  */
  (void) INTUSE(elf_end) (elf);

 fail_fd:
  /* Neither the file descriptor.  */
  (void) close (fd);

 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;
}
