xref: /netbsd-src/external/gpl3/binutils.old/dist/ld/ldctor.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
175fd0b74Schristos /* ldctor.c -- constructor support routines
2*e992f068Schristos    Copyright (C) 1991-2022 Free Software Foundation, Inc.
375fd0b74Schristos    By Steve Chamberlain <sac@cygnus.com>
475fd0b74Schristos 
575fd0b74Schristos    This file is part of the GNU Binutils.
675fd0b74Schristos 
775fd0b74Schristos    This program is free software; you can redistribute it and/or modify
875fd0b74Schristos    it under the terms of the GNU General Public License as published by
975fd0b74Schristos    the Free Software Foundation; either version 3 of the License, or
1075fd0b74Schristos    (at your option) any later version.
1175fd0b74Schristos 
1275fd0b74Schristos    This program is distributed in the hope that it will be useful,
1375fd0b74Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
1475fd0b74Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1575fd0b74Schristos    GNU General Public License for more details.
1675fd0b74Schristos 
1775fd0b74Schristos    You should have received a copy of the GNU General Public License
1875fd0b74Schristos    along with this program; if not, write to the Free Software
1975fd0b74Schristos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
2075fd0b74Schristos    MA 02110-1301, USA.  */
2175fd0b74Schristos 
2275fd0b74Schristos #include "sysdep.h"
2375fd0b74Schristos #include "bfd.h"
2475fd0b74Schristos #include "bfdlink.h"
2575fd0b74Schristos #include "safe-ctype.h"
26012573ebSchristos #include "ctf-api.h"
2775fd0b74Schristos 
2875fd0b74Schristos #include "ld.h"
2975fd0b74Schristos #include "ldexp.h"
3075fd0b74Schristos #include "ldlang.h"
3175fd0b74Schristos #include "ldmisc.h"
3275fd0b74Schristos #include <ldgram.h>
3375fd0b74Schristos #include "ldmain.h"
3475fd0b74Schristos #include "ldctor.h"
3575fd0b74Schristos 
3675fd0b74Schristos /* The list of statements needed to handle constructors.  These are
3775fd0b74Schristos    invoked by the command CONSTRUCTORS in the linker script.  */
3875fd0b74Schristos lang_statement_list_type constructor_list;
3975fd0b74Schristos 
4075fd0b74Schristos /* Whether the constructors should be sorted.  Note that this is
4175fd0b74Schristos    global for the entire link; we assume that there is only a single
4275fd0b74Schristos    CONSTRUCTORS command in the linker script.  */
43*e992f068Schristos bool constructors_sorted;
4475fd0b74Schristos 
4575fd0b74Schristos /* The sets we have seen.  */
4675fd0b74Schristos struct set_info *sets;
4775fd0b74Schristos 
4875fd0b74Schristos /* Add an entry to a set.  H is the entry in the linker hash table.
4975fd0b74Schristos    RELOC is the relocation to use for an entry in the set.  SECTION
5075fd0b74Schristos    and VALUE are the value to add.  This is called during the first
5175fd0b74Schristos    phase of the link, when we are still gathering symbols together.
5275fd0b74Schristos    We just record the information now.  The ldctor_build_sets
5375fd0b74Schristos    function will construct the sets.  */
5475fd0b74Schristos 
5575fd0b74Schristos void
ldctor_add_set_entry(struct bfd_link_hash_entry * h,bfd_reloc_code_real_type reloc,const char * name,asection * section,bfd_vma value)5675fd0b74Schristos ldctor_add_set_entry (struct bfd_link_hash_entry *h,
5775fd0b74Schristos 		      bfd_reloc_code_real_type reloc,
5875fd0b74Schristos 		      const char *name,
5975fd0b74Schristos 		      asection *section,
6075fd0b74Schristos 		      bfd_vma value)
6175fd0b74Schristos {
6275fd0b74Schristos   struct set_info *p;
6375fd0b74Schristos   struct set_element *e;
6475fd0b74Schristos   struct set_element **epp;
6575fd0b74Schristos 
6675fd0b74Schristos   for (p = sets; p != NULL; p = p->next)
6775fd0b74Schristos     if (p->h == h)
6875fd0b74Schristos       break;
6975fd0b74Schristos 
7075fd0b74Schristos   if (p == NULL)
7175fd0b74Schristos     {
7275fd0b74Schristos       p = (struct set_info *) xmalloc (sizeof (struct set_info));
7375fd0b74Schristos       p->next = sets;
7475fd0b74Schristos       sets = p;
7575fd0b74Schristos       p->h = h;
7675fd0b74Schristos       p->reloc = reloc;
7775fd0b74Schristos       p->count = 0;
7875fd0b74Schristos       p->elements = NULL;
7975fd0b74Schristos     }
8075fd0b74Schristos   else
8175fd0b74Schristos     {
8275fd0b74Schristos       if (p->reloc != reloc)
8375fd0b74Schristos 	{
84ede78133Schristos 	  einfo (_("%X%P: different relocs used in set %s\n"),
8575fd0b74Schristos 		 h->root.string);
8675fd0b74Schristos 	  return;
8775fd0b74Schristos 	}
8875fd0b74Schristos 
8975fd0b74Schristos       /* Don't permit a set to be constructed from different object
9075fd0b74Schristos 	 file formats.  The same reloc may have different results.  We
9175fd0b74Schristos 	 actually could sometimes handle this, but the case is
9275fd0b74Schristos 	 unlikely to ever arise.  Sometimes constructor symbols are in
9375fd0b74Schristos 	 unusual sections, such as the absolute section--this appears
9475fd0b74Schristos 	 to be the case in Linux a.out--and in such cases we just
9575fd0b74Schristos 	 assume everything is OK.  */
9675fd0b74Schristos       if (p->elements != NULL
9775fd0b74Schristos 	  && section->owner != NULL
9875fd0b74Schristos 	  && p->elements->section->owner != NULL
9975fd0b74Schristos 	  && strcmp (bfd_get_target (section->owner),
10075fd0b74Schristos 		     bfd_get_target (p->elements->section->owner)) != 0)
10175fd0b74Schristos 	{
102ede78133Schristos 	  einfo (_("%X%P: different object file formats composing set %s\n"),
10375fd0b74Schristos 		 h->root.string);
10475fd0b74Schristos 	  return;
10575fd0b74Schristos 	}
10675fd0b74Schristos     }
10775fd0b74Schristos 
10875fd0b74Schristos   e = (struct set_element *) xmalloc (sizeof (struct set_element));
109012573ebSchristos   e->u.next = NULL;
11075fd0b74Schristos   e->name = name;
11175fd0b74Schristos   e->section = section;
11275fd0b74Schristos   e->value = value;
11375fd0b74Schristos 
114012573ebSchristos   for (epp = &p->elements; *epp != NULL; epp = &(*epp)->u.next)
11575fd0b74Schristos     ;
11675fd0b74Schristos   *epp = e;
11775fd0b74Schristos 
11875fd0b74Schristos   ++p->count;
11975fd0b74Schristos }
12075fd0b74Schristos 
12175fd0b74Schristos /* Get the priority of a g++ global constructor or destructor from the
12275fd0b74Schristos    symbol name.  */
12375fd0b74Schristos 
12475fd0b74Schristos static int
ctor_prio(const char * name)12575fd0b74Schristos ctor_prio (const char *name)
12675fd0b74Schristos {
12775fd0b74Schristos   /* The name will look something like _GLOBAL_$I$65535$test02__Fv.
12875fd0b74Schristos      There might be extra leading underscores, and the $ characters
12975fd0b74Schristos      might be something else.  The I might be a D.  */
13075fd0b74Schristos 
13175fd0b74Schristos   while (*name == '_')
13275fd0b74Schristos     ++name;
13375fd0b74Schristos 
134*e992f068Schristos   if (!startswith (name, "GLOBAL_"))
13575fd0b74Schristos     return -1;
13675fd0b74Schristos 
13775fd0b74Schristos   name += sizeof "GLOBAL_" - 1;
13875fd0b74Schristos 
13975fd0b74Schristos   if (name[0] != name[2])
14075fd0b74Schristos     return -1;
14175fd0b74Schristos   if (name[1] != 'I' && name[1] != 'D')
14275fd0b74Schristos     return -1;
14375fd0b74Schristos   if (!ISDIGIT (name[3]))
14475fd0b74Schristos     return -1;
14575fd0b74Schristos 
14675fd0b74Schristos   return atoi (name + 3);
14775fd0b74Schristos }
14875fd0b74Schristos 
14975fd0b74Schristos /* This function is used to sort constructor elements by priority.  It
15075fd0b74Schristos    is called via qsort.  */
15175fd0b74Schristos 
15275fd0b74Schristos static int
ctor_cmp(const void * p1,const void * p2)15375fd0b74Schristos ctor_cmp (const void *p1, const void *p2)
15475fd0b74Schristos {
155012573ebSchristos   const struct set_element *pe1 = *(const struct set_element **) p1;
156012573ebSchristos   const struct set_element *pe2 = *(const struct set_element **) p2;
15775fd0b74Schristos   const char *n1;
15875fd0b74Schristos   const char *n2;
15975fd0b74Schristos   int prio1;
16075fd0b74Schristos   int prio2;
16175fd0b74Schristos 
162012573ebSchristos   n1 = pe1->name;
16375fd0b74Schristos   if (n1 == NULL)
16475fd0b74Schristos     n1 = "";
165012573ebSchristos   n2 = pe2->name;
16675fd0b74Schristos   if (n2 == NULL)
16775fd0b74Schristos     n2 = "";
16875fd0b74Schristos 
16975fd0b74Schristos   /* We need to sort in reverse order by priority.  When two
17075fd0b74Schristos      constructors have the same priority, we should maintain their
17175fd0b74Schristos      current relative position.  */
17275fd0b74Schristos 
17375fd0b74Schristos   prio1 = ctor_prio (n1);
17475fd0b74Schristos   prio2 = ctor_prio (n2);
17575fd0b74Schristos 
17675fd0b74Schristos   /* We sort in reverse order because that is what g++ expects.  */
17775fd0b74Schristos   if (prio1 < prio2)
17875fd0b74Schristos     return 1;
179012573ebSchristos   if (prio1 > prio2)
18075fd0b74Schristos     return -1;
18175fd0b74Schristos 
18275fd0b74Schristos   /* Force a stable sort.  */
183012573ebSchristos   if (pe1->u.idx < pe2->u.idx)
18475fd0b74Schristos     return -1;
185012573ebSchristos   if (pe1->u.idx > pe2->u.idx)
18675fd0b74Schristos     return 1;
18775fd0b74Schristos   return 0;
18875fd0b74Schristos }
18975fd0b74Schristos 
19075fd0b74Schristos /* This function is called after the first phase of the link and
19175fd0b74Schristos    before the second phase.  At this point all set information has
19275fd0b74Schristos    been gathered.  We now put the statements to build the sets
19375fd0b74Schristos    themselves into constructor_list.  */
19475fd0b74Schristos 
19575fd0b74Schristos void
ldctor_build_sets(void)19675fd0b74Schristos ldctor_build_sets (void)
19775fd0b74Schristos {
198*e992f068Schristos   static bool called;
199*e992f068Schristos   bool header_printed;
20075fd0b74Schristos   struct set_info *p;
20175fd0b74Schristos 
20275fd0b74Schristos   /* The emulation code may call us directly, but we only want to do
20375fd0b74Schristos      this once.  */
20475fd0b74Schristos   if (called)
20575fd0b74Schristos     return;
206*e992f068Schristos   called = true;
20775fd0b74Schristos 
20875fd0b74Schristos   if (constructors_sorted)
20975fd0b74Schristos     {
21075fd0b74Schristos       for (p = sets; p != NULL; p = p->next)
21175fd0b74Schristos 	{
21275fd0b74Schristos 	  int c, i;
213012573ebSchristos 	  struct set_element *e, *enext;
21475fd0b74Schristos 	  struct set_element **array;
21575fd0b74Schristos 
21675fd0b74Schristos 	  if (p->elements == NULL)
21775fd0b74Schristos 	    continue;
21875fd0b74Schristos 
21975fd0b74Schristos 	  c = 0;
220012573ebSchristos 	  for (e = p->elements; e != NULL; e = e->u.next)
22175fd0b74Schristos 	    ++c;
22275fd0b74Schristos 
22375fd0b74Schristos 	  array = (struct set_element **) xmalloc (c * sizeof *array);
22475fd0b74Schristos 
22575fd0b74Schristos 	  i = 0;
226012573ebSchristos 	  for (e = p->elements; e != NULL; e = enext)
22775fd0b74Schristos 	    {
22875fd0b74Schristos 	      array[i] = e;
229012573ebSchristos 	      enext = e->u.next;
230012573ebSchristos 	      e->u.idx = i;
23175fd0b74Schristos 	      ++i;
23275fd0b74Schristos 	    }
23375fd0b74Schristos 
23475fd0b74Schristos 	  qsort (array, c, sizeof *array, ctor_cmp);
23575fd0b74Schristos 
23675fd0b74Schristos 	  e = array[0];
23775fd0b74Schristos 	  p->elements = e;
23875fd0b74Schristos 	  for (i = 0; i < c - 1; i++)
239012573ebSchristos 	    array[i]->u.next = array[i + 1];
240012573ebSchristos 	  array[i]->u.next = NULL;
24175fd0b74Schristos 
24275fd0b74Schristos 	  free (array);
24375fd0b74Schristos 	}
24475fd0b74Schristos     }
24575fd0b74Schristos 
24675fd0b74Schristos   lang_list_init (&constructor_list);
24775fd0b74Schristos   push_stat_ptr (&constructor_list);
24875fd0b74Schristos 
249*e992f068Schristos   header_printed = false;
25075fd0b74Schristos   for (p = sets; p != NULL; p = p->next)
25175fd0b74Schristos     {
25275fd0b74Schristos       struct set_element *e;
25375fd0b74Schristos       reloc_howto_type *howto;
25475fd0b74Schristos       int reloc_size, size;
25575fd0b74Schristos 
25675fd0b74Schristos       /* If the symbol is defined, we may have been invoked from
25775fd0b74Schristos 	 collect, and the sets may already have been built, so we do
25875fd0b74Schristos 	 not do anything.  */
25975fd0b74Schristos       if (p->h->type == bfd_link_hash_defined
26075fd0b74Schristos 	  || p->h->type == bfd_link_hash_defweak)
26175fd0b74Schristos 	continue;
26275fd0b74Schristos 
26375fd0b74Schristos       /* For each set we build:
26475fd0b74Schristos 	   set:
26575fd0b74Schristos 	     .long number_of_elements
26675fd0b74Schristos 	     .long element0
26775fd0b74Schristos 	     ...
26875fd0b74Schristos 	     .long elementN
26975fd0b74Schristos 	     .long 0
27075fd0b74Schristos 	 except that we use the right size instead of .long.  When
27175fd0b74Schristos 	 generating relocatable output, we generate relocs instead of
27275fd0b74Schristos 	 addresses.  */
27375fd0b74Schristos       howto = bfd_reloc_type_lookup (link_info.output_bfd, p->reloc);
27475fd0b74Schristos       if (howto == NULL)
27575fd0b74Schristos 	{
27675fd0b74Schristos 	  if (bfd_link_relocatable (&link_info))
27775fd0b74Schristos 	    {
278ede78133Schristos 	      einfo (_("%X%P: %s does not support reloc %s for set %s\n"),
27975fd0b74Schristos 		     bfd_get_target (link_info.output_bfd),
28075fd0b74Schristos 		     bfd_get_reloc_code_name (p->reloc),
28175fd0b74Schristos 		     p->h->root.string);
28275fd0b74Schristos 	      continue;
28375fd0b74Schristos 	    }
28475fd0b74Schristos 
28575fd0b74Schristos 	  /* If this is not a relocatable link, all we need is the
28675fd0b74Schristos 	     size, which we can get from the input BFD.  */
28775fd0b74Schristos 	  if (p->elements->section->owner != NULL)
28875fd0b74Schristos 	    howto = bfd_reloc_type_lookup (p->elements->section->owner,
28975fd0b74Schristos 					   p->reloc);
29075fd0b74Schristos 	  if (howto == NULL)
29175fd0b74Schristos 	    {
292ede78133Schristos 	      /* See PR 20911 for a reproducer.  */
293ede78133Schristos 	      if (p->elements->section->owner == NULL)
294ede78133Schristos 		einfo (_("%X%P: special section %s does not support reloc %s for set %s\n"),
295012573ebSchristos 		       bfd_section_name (p->elements->section),
296ede78133Schristos 		       bfd_get_reloc_code_name (p->reloc),
297ede78133Schristos 		       p->h->root.string);
298ede78133Schristos 	      else
299ede78133Schristos 		einfo (_("%X%P: %s does not support reloc %s for set %s\n"),
30075fd0b74Schristos 		       bfd_get_target (p->elements->section->owner),
30175fd0b74Schristos 		       bfd_get_reloc_code_name (p->reloc),
30275fd0b74Schristos 		       p->h->root.string);
30375fd0b74Schristos 	      continue;
30475fd0b74Schristos 	    }
30575fd0b74Schristos 	}
30675fd0b74Schristos 
30775fd0b74Schristos       reloc_size = bfd_get_reloc_size (howto);
30875fd0b74Schristos       switch (reloc_size)
30975fd0b74Schristos 	{
31075fd0b74Schristos 	case 1: size = BYTE; break;
31175fd0b74Schristos 	case 2: size = SHORT; break;
31275fd0b74Schristos 	case 4: size = LONG; break;
31375fd0b74Schristos 	case 8:
31475fd0b74Schristos 	  if (howto->complain_on_overflow == complain_overflow_signed)
31575fd0b74Schristos 	    size = SQUAD;
31675fd0b74Schristos 	  else
31775fd0b74Schristos 	    size = QUAD;
31875fd0b74Schristos 	  break;
31975fd0b74Schristos 	default:
320ede78133Schristos 	  einfo (_("%X%P: unsupported size %d for set %s\n"),
32175fd0b74Schristos 		 bfd_get_reloc_size (howto), p->h->root.string);
32275fd0b74Schristos 	  size = LONG;
32375fd0b74Schristos 	  break;
32475fd0b74Schristos 	}
32575fd0b74Schristos 
32675fd0b74Schristos       lang_add_assignment (exp_assign (".",
32775fd0b74Schristos 				       exp_unop (ALIGN_K,
32875fd0b74Schristos 						 exp_intop (reloc_size)),
329*e992f068Schristos 				       false));
33075fd0b74Schristos       lang_add_assignment (exp_assign (p->h->root.string,
33175fd0b74Schristos 				       exp_nameop (NAME, "."),
332*e992f068Schristos 				       false));
33375fd0b74Schristos       lang_add_data (size, exp_intop (p->count));
33475fd0b74Schristos 
335012573ebSchristos       for (e = p->elements; e != NULL; e = e->u.next)
33675fd0b74Schristos 	{
33775fd0b74Schristos 	  if (config.map_file != NULL)
33875fd0b74Schristos 	    {
33975fd0b74Schristos 	      int len;
34075fd0b74Schristos 
34175fd0b74Schristos 	      if (!header_printed)
34275fd0b74Schristos 		{
34375fd0b74Schristos 		  minfo (_("\nSet                 Symbol\n\n"));
344*e992f068Schristos 		  header_printed = true;
34575fd0b74Schristos 		}
34675fd0b74Schristos 
34775fd0b74Schristos 	      minfo ("%s", p->h->root.string);
34875fd0b74Schristos 	      len = strlen (p->h->root.string);
34975fd0b74Schristos 
35075fd0b74Schristos 	      if (len >= 19)
35175fd0b74Schristos 		{
35275fd0b74Schristos 		  print_nl ();
35375fd0b74Schristos 		  len = 0;
35475fd0b74Schristos 		}
35575fd0b74Schristos 	      while (len < 20)
35675fd0b74Schristos 		{
35775fd0b74Schristos 		  print_space ();
35875fd0b74Schristos 		  ++len;
35975fd0b74Schristos 		}
36075fd0b74Schristos 
36175fd0b74Schristos 	      if (e->name != NULL)
362ede78133Schristos 		minfo ("%pT\n", e->name);
36375fd0b74Schristos 	      else
36475fd0b74Schristos 		minfo ("%G\n", e->section->owner, e->section, e->value);
36575fd0b74Schristos 	    }
36675fd0b74Schristos 
36775fd0b74Schristos 	  /* Need SEC_KEEP for --gc-sections.  */
36875fd0b74Schristos 	  if (!bfd_is_abs_section (e->section))
36975fd0b74Schristos 	    e->section->flags |= SEC_KEEP;
37075fd0b74Schristos 
37175fd0b74Schristos 	  if (bfd_link_relocatable (&link_info))
37275fd0b74Schristos 	    lang_add_reloc (p->reloc, howto, e->section, e->name,
37375fd0b74Schristos 			    exp_intop (e->value));
37475fd0b74Schristos 	  else
37575fd0b74Schristos 	    lang_add_data (size, exp_relop (e->section, e->value));
37675fd0b74Schristos 	}
37775fd0b74Schristos 
37875fd0b74Schristos       lang_add_data (size, exp_intop (0));
37975fd0b74Schristos     }
38075fd0b74Schristos 
38175fd0b74Schristos   pop_stat_ptr ();
38275fd0b74Schristos }
383