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