/* Locate the shared object symbol nearest a given address.
   Copyright (C) 1996-2007, 2009 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <dlfcn.h>
#include <stddef.h>
#include <ldsodefs.h>


static void
__attribute ((always_inline))
determine_info (const ElfW(Addr) addr, struct link_map *match, Dl_info *info,
		struct link_map **mapp, const ElfW(Sym) **symbolp)
{
  /* Now we know what object the address lies in.  */
  info->dli_fname = match->l_name;
  info->dli_fbase = (void *) match->l_map_start;

  /* If this is the main program the information is incomplete.  */
  if (__builtin_expect (match->l_name[0], 'a') == '\0'
      && match->l_type == lt_executable)
    info->dli_fname = _dl_argv[0];

  const ElfW(Sym) *symtab
    = (const ElfW(Sym) *) D_PTR (match, l_info[DT_SYMTAB]);
  const char *strtab = (const char *) D_PTR (match, l_info[DT_STRTAB]);

  ElfW(Word) strtabsize = match->l_info[DT_STRSZ]->d_un.d_val;

  const ElfW(Sym) *matchsym = NULL;
  if (match->l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM + DT_THISPROCNUM
		    + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] != NULL)
    {
      /* We look at all symbol table entries referenced by the hash
	 table.  */
      for (Elf_Symndx bucket = 0; bucket < match->l_nbuckets; ++bucket)
	{
	  Elf32_Word symndx = match->l_gnu_buckets[bucket];
	  if (symndx != 0)
	    {
	      const Elf32_Word *hasharr = &match->l_gnu_chain_zero[symndx];

	      do
		{
		  /* The hash table never references local symbols so
		     we can omit that test here.  */
		  if ((symtab[symndx].st_shndx != SHN_UNDEF
		       || symtab[symndx].st_value != 0)
		      && ELFW(ST_TYPE) (symtab[symndx].st_info) != STT_TLS
		      && DL_ADDR_SYM_MATCH (match, &symtab[symndx],
					    matchsym, addr)
		      && symtab[symndx].st_name < strtabsize)
		    matchsym = (ElfW(Sym) *) &symtab[symndx];

		  ++symndx;
		}
	      while ((*hasharr++ & 1u) == 0);
	    }
	}
    }
  else
    {
      const ElfW(Sym) *symtabend;
      if (match->l_info[DT_HASH] != NULL)
	symtabend = (symtab
		     + ((Elf_Symndx *) D_PTR (match, l_info[DT_HASH]))[1]);
      else
	/* There is no direct way to determine the number of symbols in the
	   dynamic symbol table and no hash table is present.  The ELF
	   binary is ill-formed but what shall we do?  Use the beginning of
	   the string table which generally follows the symbol table.  */
	symtabend = (const ElfW(Sym) *) strtab;

      for (; (void *) symtab < (void *) symtabend; ++symtab)
	if ((ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL
	     || ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)
	    && ELFW(ST_TYPE) (symtab->st_info) != STT_TLS
	    && (symtab->st_shndx != SHN_UNDEF
		|| symtab->st_value != 0)
	    && DL_ADDR_SYM_MATCH (match, symtab, matchsym, addr)
	    && symtab->st_name < strtabsize)
	  matchsym = (ElfW(Sym) *) symtab;
    }

  if (mapp)
    *mapp = match;
  if (symbolp)
    *symbolp = matchsym;

  if (matchsym)
    {
      /* We found a symbol close by.  Fill in its name and exact
	 address.  */
      lookup_t matchl = LOOKUP_VALUE (match);

      info->dli_sname = strtab + matchsym->st_name;
      info->dli_saddr = DL_SYMBOL_ADDRESS (matchl, matchsym);
    }
  else
    {
      /* No symbol matches.  We return only the containing object.  */
      info->dli_sname = NULL;
      info->dli_saddr = NULL;
    }
}


int
internal_function
_dl_addr (const void *address, Dl_info *info,
	  struct link_map **mapp, const ElfW(Sym) **symbolp)
{
  const ElfW(Addr) addr = DL_LOOKUP_ADDRESS (address);
  int result = 0;

  /* Protect against concurrent loads and unloads.  */
  __rtld_lock_lock_recursive (GL(dl_load_lock));

  /* Find the highest-addressed object that ADDRESS is not below.  */
  for (Lmid_t ns = 0; ns < GL(dl_nns); ++ns)
    for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l; l = l->l_next)
      if (addr >= l->l_map_start && addr < l->l_map_end
	  && (l->l_contiguous || _dl_addr_inside_object (l, addr)))
	{
	  determine_info (addr, l, info, mapp, symbolp);
	  result = 1;
	  goto out;
	}

 out:
  __rtld_lock_unlock_recursive (GL(dl_load_lock));

  return result;
}
libc_hidden_def (_dl_addr)

/* Return non-zero if ADDR lies within one of L's segments.  */
int
internal_function
_dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr)
{
  int n = l->l_phnum;
  const ElfW(Addr) reladdr = addr - l->l_addr;

  while (--n >= 0)
    if (l->l_phdr[n].p_type == PT_LOAD
	&& reladdr - l->l_phdr[n].p_vaddr >= 0
	&& reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz)
      return 1;
  return 0;
}
