xref: /openbsd-src/gnu/usr.bin/binutils/ld/ldctor.c (revision 007c2a4539b8b8aaa95c5e73e77620090abe113b)
12159047fSniklas /* ldctor.c -- constructor support routines
2c074d1c9Sdrahn    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
3*007c2a45Smiod    2002, 2003 Free Software Foundation, Inc.
42159047fSniklas    By Steve Chamberlain <sac@cygnus.com>
52159047fSniklas 
62159047fSniklas This file is part of GLD, the Gnu Linker.
72159047fSniklas 
82159047fSniklas GLD is free software; you can redistribute it and/or modify
92159047fSniklas it under the terms of the GNU General Public License as published by
102159047fSniklas the Free Software Foundation; either version 2, or (at your option)
112159047fSniklas any later version.
122159047fSniklas 
132159047fSniklas GLD is distributed in the hope that it will be useful,
142159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
152159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
162159047fSniklas GNU General Public License for more details.
172159047fSniklas 
182159047fSniklas You should have received a copy of the GNU General Public License
19b305b0f1Sespie along with GLD; see the file COPYING.  If not, write to the Free
20b305b0f1Sespie Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21b305b0f1Sespie 02111-1307, USA.  */
222159047fSniklas 
232159047fSniklas #include "bfd.h"
242159047fSniklas #include "sysdep.h"
252159047fSniklas #include "bfdlink.h"
26c074d1c9Sdrahn #include "safe-ctype.h"
27b305b0f1Sespie 
282159047fSniklas #include "ld.h"
292159047fSniklas #include "ldexp.h"
302159047fSniklas #include "ldlang.h"
312159047fSniklas #include "ldmisc.h"
32c074d1c9Sdrahn #include <ldgram.h>
332159047fSniklas #include "ldmain.h"
342159047fSniklas #include "ldctor.h"
352159047fSniklas 
362159047fSniklas /* The list of statements needed to handle constructors.  These are
372159047fSniklas    invoked by the command CONSTRUCTORS in the linker script.  */
382159047fSniklas lang_statement_list_type constructor_list;
392159047fSniklas 
40b305b0f1Sespie /* Whether the constructors should be sorted.  Note that this is
41b305b0f1Sespie    global for the entire link; we assume that there is only a single
42b305b0f1Sespie    CONSTRUCTORS command in the linker script.  */
43c074d1c9Sdrahn bfd_boolean constructors_sorted;
44b305b0f1Sespie 
452159047fSniklas /* The sets we have seen.  */
462159047fSniklas struct set_info *sets;
472159047fSniklas 
482159047fSniklas /* Add an entry to a set.  H is the entry in the linker hash table.
492159047fSniklas    RELOC is the relocation to use for an entry in the set.  SECTION
502159047fSniklas    and VALUE are the value to add.  This is called during the first
512159047fSniklas    phase of the link, when we are still gathering symbols together.
522159047fSniklas    We just record the information now.  The ldctor_find_constructors
532159047fSniklas    function will construct the sets.  */
542159047fSniklas 
552159047fSniklas 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)56*007c2a45Smiod ldctor_add_set_entry (struct bfd_link_hash_entry *h,
57*007c2a45Smiod 		      bfd_reloc_code_real_type reloc,
58*007c2a45Smiod 		      const char *name,
59*007c2a45Smiod 		      asection *section,
60*007c2a45Smiod 		      bfd_vma value)
612159047fSniklas {
622159047fSniklas   struct set_info *p;
632159047fSniklas   struct set_element *e;
642159047fSniklas   struct set_element **epp;
652159047fSniklas 
66*007c2a45Smiod   for (p = sets; p != NULL; p = p->next)
672159047fSniklas     if (p->h == h)
682159047fSniklas       break;
692159047fSniklas 
70*007c2a45Smiod   if (p == NULL)
712159047fSniklas     {
72*007c2a45Smiod       p = xmalloc (sizeof (struct set_info));
732159047fSniklas       p->next = sets;
742159047fSniklas       sets = p;
752159047fSniklas       p->h = h;
762159047fSniklas       p->reloc = reloc;
772159047fSniklas       p->count = 0;
782159047fSniklas       p->elements = NULL;
792159047fSniklas     }
802159047fSniklas   else
812159047fSniklas     {
822159047fSniklas       if (p->reloc != reloc)
832159047fSniklas 	{
84b55d4692Sfgsch 	  einfo (_("%P%X: Different relocs used in set %s\n"),
85b55d4692Sfgsch 		 h->root.string);
862159047fSniklas 	  return;
872159047fSniklas 	}
882159047fSniklas 
892159047fSniklas       /* Don't permit a set to be constructed from different object
902159047fSniklas          file formats.  The same reloc may have different results.  We
912159047fSniklas          actually could sometimes handle this, but the case is
922159047fSniklas          unlikely to ever arise.  Sometimes constructor symbols are in
932159047fSniklas          unusual sections, such as the absolute section--this appears
942159047fSniklas          to be the case in Linux a.out--and in such cases we just
952159047fSniklas          assume everything is OK.  */
962159047fSniklas       if (p->elements != NULL
972159047fSniklas 	  && section->owner != NULL
982159047fSniklas 	  && p->elements->section->owner != NULL
992159047fSniklas 	  && strcmp (bfd_get_target (section->owner),
1002159047fSniklas 		     bfd_get_target (p->elements->section->owner)) != 0)
1012159047fSniklas 	{
102b305b0f1Sespie 	  einfo (_("%P%X: Different object file formats composing set %s\n"),
1032159047fSniklas 		 h->root.string);
1042159047fSniklas 	  return;
1052159047fSniklas 	}
1062159047fSniklas     }
1072159047fSniklas 
108*007c2a45Smiod   e = xmalloc (sizeof (struct set_element));
1092159047fSniklas   e->next = NULL;
1102159047fSniklas   e->name = name;
1112159047fSniklas   e->section = section;
1122159047fSniklas   e->value = value;
1132159047fSniklas 
1142159047fSniklas   for (epp = &p->elements; *epp != NULL; epp = &(*epp)->next)
1152159047fSniklas     ;
1162159047fSniklas   *epp = e;
1172159047fSniklas 
1182159047fSniklas   ++p->count;
1192159047fSniklas }
1202159047fSniklas 
121b305b0f1Sespie /* Get the priority of a g++ global constructor or destructor from the
122b305b0f1Sespie    symbol name.  */
123b305b0f1Sespie 
124b305b0f1Sespie static int
ctor_prio(const char * name)125*007c2a45Smiod ctor_prio (const char *name)
126b305b0f1Sespie {
127b305b0f1Sespie   /* The name will look something like _GLOBAL_$I$65535$test02__Fv.
128b305b0f1Sespie      There might be extra leading underscores, and the $ characters
129b305b0f1Sespie      might be something else.  The I might be a D.  */
130b305b0f1Sespie 
131b305b0f1Sespie   while (*name == '_')
132b305b0f1Sespie     ++name;
133b305b0f1Sespie 
134b305b0f1Sespie   if (strncmp (name, "GLOBAL_", sizeof "GLOBAL_" - 1) != 0)
135b305b0f1Sespie     return -1;
136b305b0f1Sespie 
137b305b0f1Sespie   name += sizeof "GLOBAL_" - 1;
138b305b0f1Sespie 
139b305b0f1Sespie   if (name[0] != name[2])
140b305b0f1Sespie     return -1;
141b305b0f1Sespie   if (name[1] != 'I' && name[1] != 'D')
142b305b0f1Sespie     return -1;
143c074d1c9Sdrahn   if (! ISDIGIT (name[3]))
144b305b0f1Sespie     return -1;
145b305b0f1Sespie 
146b305b0f1Sespie   return atoi (name + 3);
147b305b0f1Sespie }
148b305b0f1Sespie 
149b305b0f1Sespie /* This function is used to sort constructor elements by priority.  It
150b305b0f1Sespie    is called via qsort.  */
151b305b0f1Sespie 
152b305b0f1Sespie static int
ctor_cmp(const void * p1,const void * p2)153*007c2a45Smiod ctor_cmp (const void *p1, const void *p2)
154b305b0f1Sespie {
155*007c2a45Smiod   const struct set_element * const *pe1 = p1;
156*007c2a45Smiod   const struct set_element * const *pe2 = p2;
157b305b0f1Sespie   const char *n1;
158b305b0f1Sespie   const char *n2;
159b305b0f1Sespie   int prio1;
160b305b0f1Sespie   int prio2;
161b305b0f1Sespie 
162b305b0f1Sespie   n1 = (*pe1)->name;
163b305b0f1Sespie   if (n1 == NULL)
164b305b0f1Sespie     n1 = "";
165b305b0f1Sespie   n2 = (*pe2)->name;
166b305b0f1Sespie   if (n2 == NULL)
167b305b0f1Sespie     n2 = "";
168b305b0f1Sespie 
169b305b0f1Sespie   /* We need to sort in reverse order by priority.  When two
170b305b0f1Sespie      constructors have the same priority, we should maintain their
171b305b0f1Sespie      current relative position.  */
172b305b0f1Sespie 
173b305b0f1Sespie   prio1 = ctor_prio (n1);
174b305b0f1Sespie   prio2 = ctor_prio (n2);
175b305b0f1Sespie 
176b305b0f1Sespie   /* We sort in reverse order because that is what g++ expects.  */
177b305b0f1Sespie   if (prio1 < prio2)
178b305b0f1Sespie     return 1;
179b305b0f1Sespie   else if (prio1 > prio2)
180b305b0f1Sespie     return -1;
181b305b0f1Sespie 
182b305b0f1Sespie   /* Force a stable sort.  */
183b305b0f1Sespie 
184b305b0f1Sespie   if (pe1 < pe2)
185b305b0f1Sespie     return -1;
186b305b0f1Sespie   else if (pe1 > pe2)
187b305b0f1Sespie     return 1;
188b305b0f1Sespie   else
189b305b0f1Sespie     return 0;
190b305b0f1Sespie }
191b305b0f1Sespie 
1922159047fSniklas /* This function is called after the first phase of the link and
1932159047fSniklas    before the second phase.  At this point all set information has
1942159047fSniklas    been gathered.  We now put the statements to build the sets
1952159047fSniklas    themselves into constructor_list.  */
1962159047fSniklas 
1972159047fSniklas void
ldctor_build_sets(void)198*007c2a45Smiod ldctor_build_sets (void)
1992159047fSniklas {
200c074d1c9Sdrahn   static bfd_boolean called;
2012159047fSniklas   lang_statement_list_type *old;
202c074d1c9Sdrahn   bfd_boolean header_printed;
2032159047fSniklas   struct set_info *p;
2042159047fSniklas 
2052159047fSniklas   /* The emulation code may call us directly, but we only want to do
2062159047fSniklas      this once.  */
2072159047fSniklas   if (called)
2082159047fSniklas     return;
209c074d1c9Sdrahn   called = TRUE;
2102159047fSniklas 
211b305b0f1Sespie   if (constructors_sorted)
212b305b0f1Sespie     {
213b305b0f1Sespie       for (p = sets; p != NULL; p = p->next)
214b305b0f1Sespie 	{
215b305b0f1Sespie 	  int c, i;
216b305b0f1Sespie 	  struct set_element *e;
217b305b0f1Sespie 	  struct set_element **array;
218b305b0f1Sespie 
219b305b0f1Sespie 	  if (p->elements == NULL)
220b305b0f1Sespie 	    continue;
221b305b0f1Sespie 
222b305b0f1Sespie 	  c = 0;
223b305b0f1Sespie 	  for (e = p->elements; e != NULL; e = e->next)
224b305b0f1Sespie 	    ++c;
225b305b0f1Sespie 
226*007c2a45Smiod 	  array = xmalloc (c * sizeof *array);
227b305b0f1Sespie 
228b305b0f1Sespie 	  i = 0;
229b305b0f1Sespie 	  for (e = p->elements; e != NULL; e = e->next)
230b305b0f1Sespie 	    {
231b305b0f1Sespie 	      array[i] = e;
232b305b0f1Sespie 	      ++i;
233b305b0f1Sespie 	    }
234b305b0f1Sespie 
235b305b0f1Sespie 	  qsort (array, c, sizeof *array, ctor_cmp);
236b305b0f1Sespie 
237b305b0f1Sespie 	  e = array[0];
238b305b0f1Sespie 	  p->elements = e;
239b305b0f1Sespie 	  for (i = 0; i < c - 1; i++)
240b305b0f1Sespie 	    array[i]->next = array[i + 1];
241b305b0f1Sespie 	  array[i]->next = NULL;
242b305b0f1Sespie 
243b305b0f1Sespie 	  free (array);
244b305b0f1Sespie 	}
245b305b0f1Sespie     }
246b305b0f1Sespie 
2472159047fSniklas   old = stat_ptr;
2482159047fSniklas   stat_ptr = &constructor_list;
2492159047fSniklas 
2502159047fSniklas   lang_list_init (stat_ptr);
2512159047fSniklas 
252c074d1c9Sdrahn   header_printed = FALSE;
253*007c2a45Smiod   for (p = sets; p != NULL; p = p->next)
2542159047fSniklas     {
2552159047fSniklas       struct set_element *e;
2562159047fSniklas       reloc_howto_type *howto;
257b305b0f1Sespie       int reloc_size, size;
2582159047fSniklas 
2592159047fSniklas       /* If the symbol is defined, we may have been invoked from
2602159047fSniklas 	 collect, and the sets may already have been built, so we do
2612159047fSniklas 	 not do anything.  */
2622159047fSniklas       if (p->h->type == bfd_link_hash_defined
2632159047fSniklas 	  || p->h->type == bfd_link_hash_defweak)
2642159047fSniklas 	continue;
2652159047fSniklas 
2662159047fSniklas       /* For each set we build:
2672159047fSniklas 	   set:
2682159047fSniklas 	     .long number_of_elements
2692159047fSniklas 	     .long element0
2702159047fSniklas 	     ...
2712159047fSniklas 	     .long elementN
2722159047fSniklas 	     .long 0
2732159047fSniklas 	 except that we use the right size instead of .long.  When
274*007c2a45Smiod 	 generating relocatable output, we generate relocs instead of
2752159047fSniklas 	 addresses.  */
2762159047fSniklas       howto = bfd_reloc_type_lookup (output_bfd, p->reloc);
277*007c2a45Smiod       if (howto == NULL)
2782159047fSniklas 	{
279*007c2a45Smiod 	  if (link_info.relocatable)
2802159047fSniklas 	    {
281b305b0f1Sespie 	      einfo (_("%P%X: %s does not support reloc %s for set %s\n"),
2822159047fSniklas 		     bfd_get_target (output_bfd),
2832159047fSniklas 		     bfd_get_reloc_code_name (p->reloc),
2842159047fSniklas 		     p->h->root.string);
2852159047fSniklas 	      continue;
2862159047fSniklas 	    }
2872159047fSniklas 
288*007c2a45Smiod 	  /* If this is not a relocatable link, all we need is the
2892159047fSniklas 	     size, which we can get from the input BFD.  */
290b305b0f1Sespie 	  if (p->elements->section->owner != NULL)
2912159047fSniklas 	    howto = bfd_reloc_type_lookup (p->elements->section->owner,
2922159047fSniklas 					   p->reloc);
2932159047fSniklas 	  if (howto == NULL)
2942159047fSniklas 	    {
295b305b0f1Sespie 	      einfo (_("%P%X: %s does not support reloc %s for set %s\n"),
2962159047fSniklas 		     bfd_get_target (p->elements->section->owner),
2972159047fSniklas 		     bfd_get_reloc_code_name (p->reloc),
2982159047fSniklas 		     p->h->root.string);
2992159047fSniklas 	      continue;
3002159047fSniklas 	    }
3012159047fSniklas 	}
3022159047fSniklas 
303b305b0f1Sespie       reloc_size = bfd_get_reloc_size (howto);
304b305b0f1Sespie       switch (reloc_size)
3052159047fSniklas 	{
3062159047fSniklas 	case 1: size = BYTE; break;
3072159047fSniklas 	case 2: size = SHORT; break;
3082159047fSniklas 	case 4: size = LONG; break;
309b305b0f1Sespie 	case 8:
310b305b0f1Sespie 	  if (howto->complain_on_overflow == complain_overflow_signed)
311b305b0f1Sespie 	    size = SQUAD;
312b305b0f1Sespie 	  else
313b305b0f1Sespie 	    size = QUAD;
314b305b0f1Sespie 	  break;
3152159047fSniklas 	default:
316b305b0f1Sespie 	  einfo (_("%P%X: Unsupported size %d for set %s\n"),
3172159047fSniklas 		 bfd_get_reloc_size (howto), p->h->root.string);
3182159047fSniklas 	  size = LONG;
3192159047fSniklas 	  break;
3202159047fSniklas 	}
3212159047fSniklas 
322b305b0f1Sespie       lang_add_assignment (exp_assop ('=', ".",
323b305b0f1Sespie 				      exp_unop (ALIGN_K,
324b305b0f1Sespie 						exp_intop (reloc_size))));
3252159047fSniklas       lang_add_assignment (exp_assop ('=', p->h->root.string,
3262159047fSniklas 				      exp_nameop (NAME, ".")));
327*007c2a45Smiod       lang_add_data (size, exp_intop (p->count));
3282159047fSniklas 
329*007c2a45Smiod       for (e = p->elements; e != NULL; e = e->next)
3302159047fSniklas 	{
331191aa565Sniklas 	  if (config.map_file != NULL)
332191aa565Sniklas 	    {
333191aa565Sniklas 	      int len;
334191aa565Sniklas 
335191aa565Sniklas 	      if (! header_printed)
336191aa565Sniklas 		{
337b305b0f1Sespie 		  minfo (_("\nSet                 Symbol\n\n"));
338c074d1c9Sdrahn 		  header_printed = TRUE;
339191aa565Sniklas 		}
340191aa565Sniklas 
341191aa565Sniklas 	      minfo ("%s", p->h->root.string);
342191aa565Sniklas 	      len = strlen (p->h->root.string);
343191aa565Sniklas 
344191aa565Sniklas 	      if (len >= 19)
345191aa565Sniklas 		{
346191aa565Sniklas 		  print_nl ();
347191aa565Sniklas 		  len = 0;
348191aa565Sniklas 		}
349191aa565Sniklas 	      while (len < 20)
350191aa565Sniklas 		{
351191aa565Sniklas 		  print_space ();
352191aa565Sniklas 		  ++len;
353191aa565Sniklas 		}
354191aa565Sniklas 
355191aa565Sniklas 	      if (e->name != NULL)
356191aa565Sniklas 		minfo ("%T\n", e->name);
357191aa565Sniklas 	      else
358191aa565Sniklas 		minfo ("%G\n", e->section->owner, e->section, e->value);
359191aa565Sniklas 	    }
360191aa565Sniklas 
361b55d4692Sfgsch 	  /* Need SEC_KEEP for --gc-sections.  */
362b305b0f1Sespie 	  if (! bfd_is_abs_section (e->section))
363b305b0f1Sespie 	    e->section->flags |= SEC_KEEP;
364b305b0f1Sespie 
365*007c2a45Smiod 	  if (link_info.relocatable)
3662159047fSniklas 	    lang_add_reloc (p->reloc, howto, e->section, e->name,
3672159047fSniklas 			    exp_intop (e->value));
3682159047fSniklas 	  else
3692159047fSniklas 	    lang_add_data (size, exp_relop (e->section, e->value));
3702159047fSniklas 	}
3712159047fSniklas 
3722159047fSniklas       lang_add_data (size, exp_intop (0));
3732159047fSniklas     }
3742159047fSniklas 
3752159047fSniklas   stat_ptr = old;
3762159047fSniklas }
377