/* Manage function descriptors.  Generic version.
   Copyright (C) 1999-2018 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 <libintl.h>
#include <unistd.h>
#include <string.h>
#include <sys/param.h>
#include <sys/mman.h>
#include <link.h>
#include <ldsodefs.h>
#include <elf/dynamic-link.h>
#include <dl-fptr.h>
#include <dl-unmap-segments.h>
#include <atomic.h>
#include <libc-pointer-arith.h>

#ifndef ELF_MACHINE_BOOT_FPTR_TABLE_LEN
/* ELF_MACHINE_BOOT_FPTR_TABLE_LEN should be greater than the number of
   dynamic symbols in ld.so.  */
# define ELF_MACHINE_BOOT_FPTR_TABLE_LEN 256
#endif

#ifndef ELF_MACHINE_LOAD_ADDRESS
# error "ELF_MACHINE_LOAD_ADDRESS is not defined."
#endif

#ifndef COMPARE_AND_SWAP
# define COMPARE_AND_SWAP(ptr, old, new) \
  (catomic_compare_and_exchange_bool_acq (ptr, new, old) == 0)
#endif

ElfW(Addr) _dl_boot_fptr_table [ELF_MACHINE_BOOT_FPTR_TABLE_LEN];

static struct local
  {
    struct fdesc_table *root;
    struct fdesc *free_list;
    unsigned int npages;		/* # of pages to allocate */
    /* the next to members MUST be consecutive! */
    struct fdesc_table boot_table;
    struct fdesc boot_fdescs[1024];
  }
local =
  {
#ifdef SHARED
    /* Address of .boot_table is not known until runtime.  */
    .root = 0,
#else
    .root = &local.boot_table,
#endif
    .npages = 2,
    .boot_table =
      {
	.len = sizeof (local.boot_fdescs) / sizeof (local.boot_fdescs[0]),
	.first_unused = 0
      }
  };

/* Create a new fdesc table and return a pointer to the first fdesc
   entry.  The fdesc lock must have been acquired already.  */

static struct fdesc_table *
new_fdesc_table (struct local *l, size_t *size)
{
  size_t old_npages = l->npages;
  size_t new_npages = old_npages + old_npages;
  struct fdesc_table *new_table;

  /* If someone has just created a new table, we return NULL to tell
     the caller to use the new table.  */
  if (! COMPARE_AND_SWAP (&l->npages, old_npages, new_npages))
    return (struct fdesc_table *) NULL;

  *size = old_npages * GLRO(dl_pagesize);
  new_table = __mmap (NULL, *size,
		      PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
  if (new_table == MAP_FAILED)
    _dl_signal_error (errno, NULL, NULL,
		      N_("cannot map pages for fdesc table"));

  new_table->len
    = (*size - sizeof (*new_table)) / sizeof (struct fdesc);
  new_table->first_unused = 1;
  return new_table;
}

/* Must call _dl_fptr_init before using any other function.  */
void
_dl_fptr_init (void)
{
  struct local *l;

  ELF_MACHINE_LOAD_ADDRESS (l, local);
  l->root = &l->boot_table;
}

static ElfW(Addr)
make_fdesc (ElfW(Addr) ip, ElfW(Addr) gp)
{
  struct fdesc *fdesc = NULL;
  struct fdesc_table *root;
  unsigned int old;
  struct local *l;

  ELF_MACHINE_LOAD_ADDRESS (l, local);

 retry:
  root = l->root;
  while (1)
    {
      old = root->first_unused;
      if (old >= root->len)
	break;
      else if (COMPARE_AND_SWAP (&root->first_unused, old, old + 1))
	{
	  fdesc = &root->fdesc[old];
	  goto install;
	}
    }

  if (l->free_list)
    {
      /* Get it from free-list.  */
      do
	{
	  fdesc = l->free_list;
	  if (fdesc == NULL)
	    goto retry;
	}
      while (! COMPARE_AND_SWAP ((ElfW(Addr) *) &l->free_list,
				 (ElfW(Addr)) fdesc, fdesc->ip));
    }
  else
    {
      /* Create a new fdesc table.  */
      size_t size;
      struct fdesc_table *new_table = new_fdesc_table (l, &size);

      if (new_table == NULL)
	goto retry;

      new_table->next = root;
      if (! COMPARE_AND_SWAP ((ElfW(Addr) *) &l->root,
			      (ElfW(Addr)) root,
			      (ElfW(Addr)) new_table))
	{
	  /* Someone has just installed a new table. Return NULL to
	     tell the caller to use the new table.  */
	  __munmap (new_table, size);
	  goto retry;
	}

      /* Note that the first entry was reserved while allocating the
	 memory for the new page.  */
      fdesc = &new_table->fdesc[0];
    }

 install:
  fdesc->ip = ip;
  fdesc->gp = gp;

  return (ElfW(Addr)) fdesc;
}


static inline ElfW(Addr) * __attribute__ ((always_inline))
make_fptr_table (struct link_map *map)
{
  const ElfW(Sym) *symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
  const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
  ElfW(Addr) *fptr_table;
  size_t size;
  size_t len;
  const ElfW(Sym) *symtabend;

  /* Determine the end of the dynamic symbol table using the hash.  */
  if (map->l_info[DT_HASH] != NULL)
    symtabend = (symtab + ((Elf_Symndx *) D_PTR (map, 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;

  len = (((char *) symtabend - (char *) symtab)
	 / map->l_info[DT_SYMENT]->d_un.d_val);
  size = ALIGN_UP (len * sizeof (fptr_table[0]), GLRO(dl_pagesize));

  /* We don't support systems without MAP_ANON.  We avoid using malloc
     because this might get called before malloc is setup.  */
  fptr_table = __mmap (NULL, size,
		       PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,
		       -1, 0);
  if (fptr_table == MAP_FAILED)
    _dl_signal_error (errno, NULL, NULL,
		      N_("cannot map pages for fptr table"));

  if (COMPARE_AND_SWAP ((ElfW(Addr) *) &map->l_mach.fptr_table,
			(ElfW(Addr)) NULL, (ElfW(Addr)) fptr_table))
    map->l_mach.fptr_table_len = len;
  else
    __munmap (fptr_table, len * sizeof (fptr_table[0]));

  return map->l_mach.fptr_table;
}


ElfW(Addr)
_dl_make_fptr (struct link_map *map, const ElfW(Sym) *sym,
	       ElfW(Addr) ip)
{
  ElfW(Addr) *ftab = map->l_mach.fptr_table;
  const ElfW(Sym) *symtab;
  Elf_Symndx symidx;
  struct local *l;

  if (__builtin_expect (ftab == NULL, 0))
    ftab = make_fptr_table (map);

  symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]);
  symidx = sym - symtab;

  if (symidx >= map->l_mach.fptr_table_len)
    _dl_signal_error (0, NULL, NULL,
		      N_("internal error: symidx out of range of fptr table"));

  while (ftab[symidx] == 0)
    {
      /* GOT has already been relocated in elf_get_dynamic_info -
	 don't try to relocate it again.  */
      ElfW(Addr) fdesc
	= make_fdesc (ip, map->l_info[DT_PLTGOT]->d_un.d_ptr);

      if (__builtin_expect (COMPARE_AND_SWAP (&ftab[symidx], (ElfW(Addr)) NULL,
					      fdesc), 1))
	{
	  /* Noone has updated the entry and the new function
	     descriptor has been installed.  */
#if 0
	  const char *strtab
	    = (const void *) D_PTR (map, l_info[DT_STRTAB]);

	  ELF_MACHINE_LOAD_ADDRESS (l, local);
	  if (l->root != &l->boot_table
	      || l->boot_table.first_unused > 20)
	    _dl_debug_printf ("created fdesc symbol `%s' at %lx\n",
			      strtab + sym->st_name, ftab[symidx]);
#endif
	  break;
	}
      else
	{
	  /* We created a duplicated function descriptor. We put it on
	     free-list.  */
	  struct fdesc *f = (struct fdesc *) fdesc;

	  ELF_MACHINE_LOAD_ADDRESS (l, local);

	  do
	    f->ip = (ElfW(Addr)) l->free_list;
	  while (! COMPARE_AND_SWAP ((ElfW(Addr) *) &l->free_list,
				     f->ip, fdesc));
	}
    }

  return ftab[symidx];
}


void
_dl_unmap (struct link_map *map)
{
  ElfW(Addr) *ftab = map->l_mach.fptr_table;
  struct fdesc *head = NULL, *tail = NULL;
  size_t i;

  _dl_unmap_segments (map);

  if (ftab == NULL)
    return;

  /* String together the fdesc structures that are being freed.  */
  for (i = 0; i < map->l_mach.fptr_table_len; ++i)
    {
      if (ftab[i])
	{
	  *(struct fdesc **) ftab[i] = head;
	  head = (struct fdesc *) ftab[i];
	  if (tail == NULL)
	    tail = head;
	}
    }

  /* Prepend the new list to the free_list: */
  if (tail)
    do
      tail->ip = (ElfW(Addr)) local.free_list;
    while (! COMPARE_AND_SWAP ((ElfW(Addr) *) &local.free_list,
			       tail->ip, (ElfW(Addr)) head));

  __munmap (ftab, (map->l_mach.fptr_table_len
		   * sizeof (map->l_mach.fptr_table[0])));

  map->l_mach.fptr_table = NULL;
}

extern ElfW(Addr) _dl_fixup (struct link_map *, ElfW(Word)) attribute_hidden;

static inline Elf32_Addr
elf_machine_resolve (void)
{
  Elf32_Addr addr;

  asm ("b,l     1f,%0\n"
"	addil	L'_dl_runtime_resolve - ($PIC_pcrel$0 - 1),%0\n"
"1:	ldo	R'_dl_runtime_resolve - ($PIC_pcrel$0 - 5)(%%r1),%0\n"
       : "=r" (addr) : : "r1");

  return addr;
}

static inline int
_dl_read_access_allowed (unsigned int *addr)
{
  int result;

  asm ("proberi	(%1),3,%0" : "=r" (result) : "r" (addr) : );

  return result;
}

ElfW(Addr)
_dl_lookup_address (const void *address)
{
  ElfW(Addr) addr = (ElfW(Addr)) address;
  unsigned int *desc, *gptr;

  /* Return ADDR if the least-significant two bits of ADDR are not consistent
     with ADDR being a linker defined function pointer.  The normal value for
     a code address in a backtrace is 3.  */
  if (((unsigned int) addr & 3) != 2)
    return addr;

  /* Handle special case where ADDR points to page 0.  */
  if ((unsigned int) addr < 4096)
    return addr;

  /* Clear least-significant two bits from descriptor address.  */
  desc = (unsigned int *) ((unsigned int) addr & ~3);
  if (!_dl_read_access_allowed (desc))
    return addr;

  /* Load first word of candidate descriptor.  It should be a pointer
     with word alignment and point to memory that can be read.  */
  gptr = (unsigned int *) desc[0];
  if (((unsigned int) gptr & 3) != 0
      || !_dl_read_access_allowed (gptr))
    return addr;

  /* See if descriptor requires resolution.  The following trampoline is
     used in each global offset table for function resolution:

		ldw 0(r20),r22
		bv r0(r22)
		ldw 4(r20),r21
     tramp:	b,l .-12,r20
		depwi 0,31,2,r20
		.word _dl_runtime_resolve
		.word "_dl_runtime_resolve ltp"
     got:	.word _DYNAMIC
		.word "struct link map address" */
  if (gptr[0] == 0xea9f1fdd			/* b,l .-12,r20     */
      && gptr[1] == 0xd6801c1e			/* depwi 0,31,2,r20 */
      && (ElfW(Addr)) gptr[2] == elf_machine_resolve ())
    _dl_fixup ((struct link_map *) gptr[5], (ElfW(Word)) desc[1]);

  return (ElfW(Addr)) desc[0];
}
