/* ldcref.c -- output a cross reference table
   Copyright (C) 1996-2021 Free Software Foundation, Inc.
   Written by Ian Lance Taylor <ian@cygnus.com>

   This file is part of the GNU Binutils.

   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; either version 3 of the License, or
   (at your option) any later version.

   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., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */


/* This file holds routines that manage the cross reference table.
   The table is used to generate cross reference reports.  It is also
   used to implement the NOCROSSREFS command in the linker script.  */

#include "sysdep.h"
#include "bfd.h"
#include "bfdlink.h"
#include "ctf-api.h"
#include "libiberty.h"
#include "demangle.h"
#include "objalloc.h"

#include "ld.h"
#include "ldmain.h"
#include "ldmisc.h"
#include "ldexp.h"
#include "ldlang.h"

/* We keep an instance of this structure for each reference to a
   symbol from a given object.  */

struct cref_ref
{
  /* The next reference.  */
  struct cref_ref *next;
  /* The object.  */
  bfd *abfd;
  /* True if the symbol is defined.  */
  unsigned int def : 1;
  /* True if the symbol is common.  */
  unsigned int common : 1;
  /* True if the symbol is undefined.  */
  unsigned int undef : 1;
};

/* We keep a hash table of symbols.  Each entry looks like this.  */

struct cref_hash_entry
{
  struct bfd_hash_entry root;
  /* The demangled name.  */
  const char *demangled;
  /* References to and definitions of this symbol.  */
  struct cref_ref *refs;
};

/* This is what the hash table looks like.  */

struct cref_hash_table
{
  struct bfd_hash_table root;
};

/* Forward declarations.  */

static void output_one_cref (FILE *, struct cref_hash_entry *);
static void check_local_sym_xref (lang_input_statement_type *);
static bool check_nocrossref (struct cref_hash_entry *, void *);
static void check_refs (const char *, bool, asection *, bfd *,
			struct lang_nocrossrefs *);
static void check_reloc_refs (bfd *, asection *, void *);

/* Look up an entry in the cref hash table.  */

#define cref_hash_lookup(table, string, create, copy)		\
  ((struct cref_hash_entry *)					\
   bfd_hash_lookup (&(table)->root, (string), (create), (copy)))

/* Traverse the cref hash table.  */

#define cref_hash_traverse(table, func, info)				\
  (bfd_hash_traverse							\
   (&(table)->root,							\
    (bool (*) (struct bfd_hash_entry *, void *)) (func), (info)))

/* The cref hash table.  */

static struct cref_hash_table cref_table;

/* Whether the cref hash table has been initialized.  */

static bool cref_initialized;

/* The number of symbols seen so far.  */

static size_t cref_symcount;

/* Used to take a snapshot of the cref hash table when starting to
   add syms from an as-needed library.  */
static struct bfd_hash_entry **old_table;
static unsigned int old_size;
static unsigned int old_count;
static void *old_tab;
static void *alloc_mark;
static size_t tabsize, entsize, refsize;
static size_t old_symcount;

/* Create an entry in a cref hash table.  */

static struct bfd_hash_entry *
cref_hash_newfunc (struct bfd_hash_entry *entry,
		   struct bfd_hash_table *table,
		   const char *string)
{
  struct cref_hash_entry *ret = (struct cref_hash_entry *) entry;

  /* Allocate the structure if it has not already been allocated by a
     subclass.  */
  if (ret == NULL)
    ret = ((struct cref_hash_entry *)
	   bfd_hash_allocate (table, sizeof (struct cref_hash_entry)));
  if (ret == NULL)
    return NULL;

  /* Call the allocation method of the superclass.  */
  ret = ((struct cref_hash_entry *)
	 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
  if (ret != NULL)
    {
      /* Set local fields.  */
      ret->demangled = NULL;
      ret->refs = NULL;

      /* Keep a count of the number of entries created in the hash
	 table.  */
      ++cref_symcount;
    }

  return &ret->root;
}

/* Add a symbol to the cref hash table.  This is called for every
   global symbol that is seen during the link.  */

void
add_cref (const char *name,
	  bfd *abfd,
	  asection *section,
	  bfd_vma value ATTRIBUTE_UNUSED)
{
  struct cref_hash_entry *h;
  struct cref_ref *r;

  if (!cref_initialized)
    {
      if (!bfd_hash_table_init (&cref_table.root, cref_hash_newfunc,
				sizeof (struct cref_hash_entry)))
	einfo (_("%X%P: bfd_hash_table_init of cref table failed: %E\n"));
      cref_initialized = true;
    }

  h = cref_hash_lookup (&cref_table, name, true, false);
  if (h == NULL)
    einfo (_("%X%P: cref_hash_lookup failed: %E\n"));

  for (r = h->refs; r != NULL; r = r->next)
    if (r->abfd == abfd)
      break;

  if (r == NULL)
    {
      r = (struct cref_ref *) bfd_hash_allocate (&cref_table.root, sizeof *r);
      if (r == NULL)
	einfo (_("%X%P: cref alloc failed: %E\n"));
      r->next = h->refs;
      h->refs = r;
      r->abfd = abfd;
      r->def = false;
      r->common = false;
      r->undef = false;
    }

  if (bfd_is_und_section (section))
    r->undef = true;
  else if (bfd_is_com_section (section))
    r->common = true;
  else
    r->def = true;
}

/* Called before loading an as-needed library to take a snapshot of
   the cref hash table, and after we have loaded or found that the
   library was not needed.  */

bool
handle_asneeded_cref (bfd *abfd ATTRIBUTE_UNUSED,
		      enum notice_asneeded_action act)
{
  unsigned int i;

  if (!cref_initialized)
    return true;

  if (act == notice_as_needed)
    {
      char *old_ent, *old_ref;

      for (i = 0; i < cref_table.root.size; i++)
	{
	  struct bfd_hash_entry *p;
	  struct cref_hash_entry *c;
	  struct cref_ref *r;

	  for (p = cref_table.root.table[i]; p != NULL; p = p->next)
	    {
	      entsize += cref_table.root.entsize;
	      c = (struct cref_hash_entry *) p;
	      for (r = c->refs; r != NULL; r = r->next)
		refsize += sizeof (struct cref_ref);
	    }
	}

      tabsize = cref_table.root.size * sizeof (struct bfd_hash_entry *);
      old_tab = xmalloc (tabsize + entsize + refsize);

      alloc_mark = bfd_hash_allocate (&cref_table.root, 1);
      if (alloc_mark == NULL)
	return false;

      memcpy (old_tab, cref_table.root.table, tabsize);
      old_ent = (char *) old_tab + tabsize;
      old_ref = (char *) old_ent + entsize;
      old_table = cref_table.root.table;
      old_size = cref_table.root.size;
      old_count = cref_table.root.count;
      old_symcount = cref_symcount;

      for (i = 0; i < cref_table.root.size; i++)
	{
	  struct bfd_hash_entry *p;
	  struct cref_hash_entry *c;
	  struct cref_ref *r;

	  for (p = cref_table.root.table[i]; p != NULL; p = p->next)
	    {
	      memcpy (old_ent, p, cref_table.root.entsize);
	      old_ent = (char *) old_ent + cref_table.root.entsize;
	      c = (struct cref_hash_entry *) p;
	      for (r = c->refs; r != NULL; r = r->next)
		{
		  memcpy (old_ref, r, sizeof (struct cref_ref));
		  old_ref = (char *) old_ref + sizeof (struct cref_ref);
		}
	    }
	}
      return true;
    }

  if (act == notice_not_needed)
    {
      char *old_ent, *old_ref;

      if (old_tab == NULL)
	{
	  /* The only way old_tab can be NULL is if the cref hash table
	     had not been initialised when notice_as_needed.  */
	  bfd_hash_table_free (&cref_table.root);
	  cref_initialized = false;
	  return true;
	}

      old_ent = (char *) old_tab + tabsize;
      old_ref = (char *) old_ent + entsize;
      cref_table.root.table = old_table;
      cref_table.root.size = old_size;
      cref_table.root.count = old_count;
      memcpy (cref_table.root.table, old_tab, tabsize);
      cref_symcount = old_symcount;

      for (i = 0; i < cref_table.root.size; i++)
	{
	  struct bfd_hash_entry *p;
	  struct cref_hash_entry *c;
	  struct cref_ref *r;

	  for (p = cref_table.root.table[i]; p != NULL; p = p->next)
	    {
	      memcpy (p, old_ent, cref_table.root.entsize);
	      old_ent = (char *) old_ent + cref_table.root.entsize;
	      c = (struct cref_hash_entry *) p;
	      for (r = c->refs; r != NULL; r = r->next)
		{
		  memcpy (r, old_ref, sizeof (struct cref_ref));
		  old_ref = (char *) old_ref + sizeof (struct cref_ref);
		}
	    }
	}

      objalloc_free_block ((struct objalloc *) cref_table.root.memory,
			   alloc_mark);
    }
  else if (act != notice_needed)
    return false;

  free (old_tab);
  old_tab = NULL;
  return true;
}

/* Copy the addresses of the hash table entries into an array.  This
   is called via cref_hash_traverse.  We also fill in the demangled
   name.  */

static bool
cref_fill_array (struct cref_hash_entry *h, void *data)
{
  struct cref_hash_entry ***pph = (struct cref_hash_entry ***) data;

  ASSERT (h->demangled == NULL);
  h->demangled = bfd_demangle (link_info.output_bfd, h->root.string,
			       DMGL_ANSI | DMGL_PARAMS);
  if (h->demangled == NULL)
    h->demangled = h->root.string;

  **pph = h;

  ++*pph;

  return true;
}

/* Sort an array of cref hash table entries by name.  */

static int
cref_sort_array (const void *a1, const void *a2)
{
  const struct cref_hash_entry *const *p1
    = (const struct cref_hash_entry *const *) a1;
  const struct cref_hash_entry *const *p2
    = (const struct cref_hash_entry *const *) a2;

  if (demangling)
    return strcmp ((*p1)->demangled, (*p2)->demangled);
  else
    return strcmp ((*p1)->root.string, (*p2)->root.string);
}

/* Write out the cref table.  */

#define FILECOL (50)

void
output_cref (FILE *fp)
{
  int len;
  struct cref_hash_entry **csyms, **csym_fill, **csym, **csym_end;
  const char *msg;

  fprintf (fp, _("\nCross Reference Table\n\n"));
  msg = _("Symbol");
  fprintf (fp, "%s", msg);
  len = strlen (msg);
  while (len < FILECOL)
    {
      putc (' ', fp);
      ++len;
    }
  fprintf (fp, _("File\n"));

  if (!cref_initialized)
    {
      fprintf (fp, _("No symbols\n"));
      return;
    }

  csyms = (struct cref_hash_entry **) xmalloc (cref_symcount * sizeof (*csyms));

  csym_fill = csyms;
  cref_hash_traverse (&cref_table, cref_fill_array, &csym_fill);
  ASSERT ((size_t) (csym_fill - csyms) == cref_symcount);

  qsort (csyms, cref_symcount, sizeof (*csyms), cref_sort_array);

  csym_end = csyms + cref_symcount;
  for (csym = csyms; csym < csym_end; csym++)
    output_one_cref (fp, *csym);
}

/* Output one entry in the cross reference table.  */

static void
output_one_cref (FILE *fp, struct cref_hash_entry *h)
{
  int len;
  struct bfd_link_hash_entry *hl;
  struct cref_ref *r;

  hl = bfd_link_hash_lookup (link_info.hash, h->root.string, false,
			     false, true);
  if (hl == NULL)
    einfo (_("%P: symbol `%pT' missing from main hash table\n"),
	   h->root.string);
  else
    {
      /* If this symbol is defined in a dynamic object but never
	 referenced by a normal object, then don't print it.  */
      if (hl->type == bfd_link_hash_defined)
	{
	  if (hl->u.def.section->output_section == NULL)
	    return;
	  if (hl->u.def.section->owner != NULL
	      && (hl->u.def.section->owner->flags & DYNAMIC) != 0)
	    {
	      for (r = h->refs; r != NULL; r = r->next)
		if ((r->abfd->flags & DYNAMIC) == 0)
		  break;
	      if (r == NULL)
		return;
	    }
	}
    }

  if (demangling)
    {
      fprintf (fp, "%s ", h->demangled);
      len = strlen (h->demangled) + 1;
    }
  else
    {
      fprintf (fp, "%s ", h->root.string);
      len = strlen (h->root.string) + 1;
    }

  for (r = h->refs; r != NULL; r = r->next)
    {
      if (r->def)
	{
	  while (len < FILECOL)
	    {
	      putc (' ', fp);
	      ++len;
	    }
	  lfinfo (fp, "%pB\n", r->abfd);
	  len = 0;
	}
    }

  for (r = h->refs; r != NULL; r = r->next)
    {
      if (r->common)
	{
	  while (len < FILECOL)
	    {
	      putc (' ', fp);
	      ++len;
	    }
	  lfinfo (fp, "%pB\n", r->abfd);
	  len = 0;
	}
    }

  for (r = h->refs; r != NULL; r = r->next)
    {
      if (!r->def && !r->common)
	{
	  while (len < FILECOL)
	    {
	      putc (' ', fp);
	      ++len;
	    }
	  lfinfo (fp, "%pB\n", r->abfd);
	  len = 0;
	}
    }

  ASSERT (len == 0);
}

/* Check for prohibited cross references.  */

void
check_nocrossrefs (void)
{
  if (!cref_initialized)
    return;

  cref_hash_traverse (&cref_table, check_nocrossref, NULL);

  lang_for_each_file (check_local_sym_xref);
}

/* Check for prohibited cross references to local and section symbols.  */

static void
check_local_sym_xref (lang_input_statement_type *statement)
{
  bfd *abfd;
  asymbol **syms;

  abfd = statement->the_bfd;
  if (abfd == NULL)
    return;

  if (!bfd_generic_link_read_symbols (abfd))
    einfo (_("%F%P: %pB: could not read symbols: %E\n"), abfd);

  for (syms = bfd_get_outsymbols (abfd); *syms; ++syms)
    {
      asymbol *sym = *syms;
      if (sym->flags & (BSF_GLOBAL | BSF_WARNING | BSF_INDIRECT | BSF_FILE))
	continue;
      if ((sym->flags & (BSF_LOCAL | BSF_SECTION_SYM)) != 0
	  && sym->section->output_section != NULL)
	{
	  const char *outsecname, *symname;
	  struct lang_nocrossrefs *ncrs;
	  struct lang_nocrossref *ncr;

	  outsecname = sym->section->output_section->name;
	  symname = NULL;
	  if ((sym->flags & BSF_SECTION_SYM) == 0)
	    symname = sym->name;
	  for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
	    for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
	      {
		if (strcmp (ncr->name, outsecname) == 0)
		  check_refs (symname, false, sym->section, abfd, ncrs);
		/* The NOCROSSREFS_TO command only checks symbols defined in
		   the first section in the list.  */
		if (ncrs->onlyfirst)
		  break;
	      }
	}
    }
}

/* Check one symbol to see if it is a prohibited cross reference.  */

static bool
check_nocrossref (struct cref_hash_entry *h, void *ignore ATTRIBUTE_UNUSED)
{
  struct bfd_link_hash_entry *hl;
  asection *defsec;
  const char *defsecname;
  struct lang_nocrossrefs *ncrs;
  struct lang_nocrossref *ncr;
  struct cref_ref *ref;

  hl = bfd_link_hash_lookup (link_info.hash, h->root.string, false,
			     false, true);
  if (hl == NULL)
    {
      einfo (_("%P: symbol `%pT' missing from main hash table\n"),
	     h->root.string);
      return true;
    }

  if (hl->type != bfd_link_hash_defined
      && hl->type != bfd_link_hash_defweak)
    return true;

  defsec = hl->u.def.section->output_section;
  if (defsec == NULL)
    return true;
  defsecname = bfd_section_name (defsec);

  for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
    for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
      {
	if (strcmp (ncr->name, defsecname) == 0)
	  for (ref = h->refs; ref != NULL; ref = ref->next)
	    check_refs (hl->root.string, true, hl->u.def.section,
			ref->abfd, ncrs);
	/* The NOCROSSREFS_TO command only checks symbols defined in the first
	   section in the list.  */
	if (ncrs->onlyfirst)
	  break;
      }

  return true;
}

/* The struct is used to pass information from check_refs to
   check_reloc_refs through bfd_map_over_sections.  */

struct check_refs_info
{
  const char *sym_name;
  asection *defsec;
  struct lang_nocrossrefs *ncrs;
  asymbol **asymbols;
  bool global;
};

/* This function is called for each symbol defined in a section which
   prohibits cross references.  We need to look through all references
   to this symbol, and ensure that the references are not from
   prohibited sections.  */

static void
check_refs (const char *name,
	    bool global,
	    asection *sec,
	    bfd *abfd,
	    struct lang_nocrossrefs *ncrs)
{
  struct check_refs_info info;

  /* We need to look through the relocations for this BFD, to see
     if any of the relocations which refer to this symbol are from
     a prohibited section.  Note that we need to do this even for
     the BFD in which the symbol is defined, since even a single
     BFD might contain a prohibited cross reference.  */

  if (!bfd_generic_link_read_symbols (abfd))
    einfo (_("%F%P: %pB: could not read symbols: %E\n"), abfd);

  info.sym_name = name;
  info.global = global;
  info.defsec = sec;
  info.ncrs = ncrs;
  info.asymbols = bfd_get_outsymbols (abfd);
  bfd_map_over_sections (abfd, check_reloc_refs, &info);
}

/* This is called via bfd_map_over_sections.  INFO->SYM_NAME is a symbol
   defined in INFO->DEFSECNAME.  If this section maps into any of the
   sections listed in INFO->NCRS, other than INFO->DEFSECNAME, then we
   look through the relocations.  If any of the relocations are to
   INFO->SYM_NAME, then we report a prohibited cross reference error.  */

static void
check_reloc_refs (bfd *abfd, asection *sec, void *iarg)
{
  struct check_refs_info *info = (struct check_refs_info *) iarg;
  asection *outsec;
  const char *outsecname;
  asection *outdefsec;
  const char *outdefsecname;
  struct lang_nocrossref *ncr;
  const char *symname;
  bool global;
  long relsize;
  arelent **relpp;
  long relcount;
  arelent **p, **pend;

  outsec = sec->output_section;
  outsecname = bfd_section_name (outsec);

  outdefsec = info->defsec->output_section;
  outdefsecname = bfd_section_name (outdefsec);

  /* The section where the symbol is defined is permitted.  */
  if (strcmp (outsecname, outdefsecname) == 0)
    return;

  for (ncr = info->ncrs->list; ncr != NULL; ncr = ncr->next)
    if (strcmp (outsecname, ncr->name) == 0)
      break;

  if (ncr == NULL)
    return;

  /* This section is one for which cross references are prohibited.
     Look through the relocations, and see if any of them are to
     INFO->SYM_NAME.  If INFO->SYMNAME is NULL, check for relocations
     against the section symbol.  If INFO->GLOBAL is TRUE, the
     definition is global, check for relocations against the global
     symbols.  Otherwise check for relocations against the local and
     section symbols.  */

  symname = info->sym_name;
  global = info->global;

  relsize = bfd_get_reloc_upper_bound (abfd, sec);
  if (relsize < 0)
    einfo (_("%F%P: %pB: could not read relocs: %E\n"), abfd);
  if (relsize == 0)
    return;

  relpp = (arelent **) xmalloc (relsize);
  relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols);
  if (relcount < 0)
    einfo (_("%F%P: %pB: could not read relocs: %E\n"), abfd);

  p = relpp;
  pend = p + relcount;
  for (; p < pend && *p != NULL; p++)
    {
      arelent *q = *p;

      if (q->sym_ptr_ptr != NULL
	  && *q->sym_ptr_ptr != NULL
	  && ((global
	       && (bfd_is_und_section (bfd_asymbol_section (*q->sym_ptr_ptr))
		   || bfd_is_com_section (bfd_asymbol_section (*q->sym_ptr_ptr))
		   || ((*q->sym_ptr_ptr)->flags & (BSF_GLOBAL
						   | BSF_WEAK)) != 0))
	      || (!global
		  && ((*q->sym_ptr_ptr)->flags & (BSF_LOCAL
						  | BSF_SECTION_SYM)) != 0
		  && bfd_asymbol_section (*q->sym_ptr_ptr) == info->defsec))
	  && (symname != NULL
	      ? strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) == 0
	      : ((*q->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0))
	{
	  /* We found a reloc for the symbol.  The symbol is defined
	     in OUTSECNAME.  This reloc is from a section which is
	     mapped into a section from which references to OUTSECNAME
	     are prohibited.  We must report an error.  */
	  einfo (_("%X%P: %C: prohibited cross reference from %s to `%pT' in %s\n"),
		 abfd, sec, q->address, outsecname,
		 bfd_asymbol_name (*q->sym_ptr_ptr), outdefsecname);
	}
    }

  free (relpp);
}
