169783Smsmith/* ldctor.c -- constructor support routines
269783Smsmith   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
369783Smsmith   2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
469783Smsmith   By Steve Chamberlain <sac@cygnus.com>
569783Smsmith
669783SmsmithThis file is part of GLD, the Gnu Linker.
769783Smsmith
869783SmsmithGLD is free software; you can redistribute it and/or modify
969783Smsmithit under the terms of the GNU General Public License as published by
1069783Smsmiththe Free Software Foundation; either version 2, or (at your option)
1169783Smsmithany later version.
1269783Smsmith
1369783SmsmithGLD is distributed in the hope that it will be useful,
1469783Smsmithbut WITHOUT ANY WARRANTY; without even the implied warranty of
1569783SmsmithMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1669783SmsmithGNU General Public License for more details.
1769783Smsmith
1869783SmsmithYou should have received a copy of the GNU General Public License
1969783Smsmithalong with GLD; see the file COPYING.  If not, write to the Free
2069783SmsmithSoftware Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
2169783Smsmith02110-1301, USA.  */
2269783Smsmith
2369783Smsmith#include "sysdep.h"
2469783Smsmith#include "bfd.h"
2569783Smsmith#include "bfdlink.h"
2669783Smsmith#include "safe-ctype.h"
2769783Smsmith
2869783Smsmith#include "ld.h"
2969783Smsmith#include "ldexp.h"
3069783Smsmith#include "ldlang.h"
3169783Smsmith#include "ldmisc.h"
3269783Smsmith#include <ldgram.h>
3369783Smsmith#include "ldmain.h"
3469783Smsmith#include "ldctor.h"
3569783Smsmith
3669783Smsmith/* The list of statements needed to handle constructors.  These are
3769783Smsmith   invoked by the command CONSTRUCTORS in the linker script.  */
3869783Smsmithlang_statement_list_type constructor_list;
3969783Smsmith
4069783Smsmith/* Whether the constructors should be sorted.  Note that this is
41107546Simp   global for the entire link; we assume that there is only a single
42107546Simp   CONSTRUCTORS command in the linker script.  */
43106844Smdoddbfd_boolean constructors_sorted;
4469783Smsmith
4569783Smsmith/* The sets we have seen.  */
4669783Smsmithstruct set_info *sets;
47119285Simp
48119285Simp/* Add an entry to a set.  H is the entry in the linker hash table.
49119285Simp   RELOC is the relocation to use for an entry in the set.  SECTION
5069783Smsmith   and VALUE are the value to add.  This is called during the first
5169783Smsmith   phase of the link, when we are still gathering symbols together.
5269783Smsmith   We just record the information now.  The ldctor_build_sets
5369783Smsmith   function will construct the sets.  */
5469783Smsmith
5569783Smsmithvoid
5669783Smsmithldctor_add_set_entry (struct bfd_link_hash_entry *h,
5769783Smsmith		      bfd_reloc_code_real_type reloc,
5869783Smsmith		      const char *name,
5969783Smsmith		      asection *section,
6069783Smsmith		      bfd_vma value)
6169783Smsmith{
6269783Smsmith  struct set_info *p;
6369783Smsmith  struct set_element *e;
6469783Smsmith  struct set_element **epp;
6569783Smsmith
6669783Smsmith  for (p = sets; p != NULL; p = p->next)
6769783Smsmith    if (p->h == h)
6869783Smsmith      break;
6969783Smsmith
7069783Smsmith  if (p == NULL)
7169783Smsmith    {
7269783Smsmith      p = xmalloc (sizeof (struct set_info));
7369783Smsmith      p->next = sets;
7469783Smsmith      sets = p;
7569783Smsmith      p->h = h;
7669783Smsmith      p->reloc = reloc;
7769783Smsmith      p->count = 0;
7869783Smsmith      p->elements = NULL;
7969783Smsmith    }
8069783Smsmith  else
8169783Smsmith    {
8269783Smsmith      if (p->reloc != reloc)
8369783Smsmith	{
8469783Smsmith	  einfo (_("%P%X: Different relocs used in set %s\n"),
8569783Smsmith		 h->root.string);
8669783Smsmith	  return;
8769783Smsmith	}
8869783Smsmith
89102441Sjhb      /* Don't permit a set to be constructed from different object
9069783Smsmith         file formats.  The same reloc may have different results.  We
9169783Smsmith         actually could sometimes handle this, but the case is
9269783Smsmith         unlikely to ever arise.  Sometimes constructor symbols are in
9369783Smsmith         unusual sections, such as the absolute section--this appears
94106844Smdodd         to be the case in Linux a.out--and in such cases we just
95106844Smdodd         assume everything is OK.  */
96106844Smdodd      if (p->elements != NULL
97106844Smdodd	  && section->owner != NULL
98106844Smdodd	  && p->elements->section->owner != NULL
99106844Smdodd	  && strcmp (bfd_get_target (section->owner),
100106844Smdodd		     bfd_get_target (p->elements->section->owner)) != 0)
101106844Smdodd	{
102106844Smdodd	  einfo (_("%P%X: Different object file formats composing set %s\n"),
103106844Smdodd		 h->root.string);
104106844Smdodd	  return;
105106844Smdodd	}
10669783Smsmith    }
10769783Smsmith
10869783Smsmith  e = xmalloc (sizeof (struct set_element));
10969783Smsmith  e->next = NULL;
11069783Smsmith  e->name = name;
11169783Smsmith  e->section = section;
11269783Smsmith  e->value = value;
11369783Smsmith
11469783Smsmith  for (epp = &p->elements; *epp != NULL; epp = &(*epp)->next)
11569783Smsmith    ;
11669783Smsmith  *epp = e;
11769783Smsmith
11869783Smsmith  ++p->count;
119102441Sjhb}
120102441Sjhb
12169783Smsmith/* Get the priority of a g++ global constructor or destructor from the
12269783Smsmith   symbol name.  */
123119266Simp
12469783Smsmithstatic int
12569783Smsmithctor_prio (const char *name)
12669783Smsmith{
12769783Smsmith  /* The name will look something like _GLOBAL_$I$65535$test02__Fv.
12869908Smsmith     There might be extra leading underscores, and the $ characters
12969908Smsmith     might be something else.  The I might be a D.  */
13069908Smsmith
13169953Smsmith  while (*name == '_')
13269908Smsmith    ++name;
13369908Smsmith
13469908Smsmith  if (! CONST_STRNEQ (name, "GLOBAL_"))
13569908Smsmith    return -1;
13669908Smsmith
13769783Smsmith  name += sizeof "GLOBAL_" - 1;
13869908Smsmith
13969908Smsmith  if (name[0] != name[2])
14069908Smsmith    return -1;
14169953Smsmith  if (name[1] != 'I' && name[1] != 'D')
14269953Smsmith    return -1;
14369953Smsmith  if (! ISDIGIT (name[3]))
14469953Smsmith    return -1;
14569953Smsmith
14669953Smsmith  return atoi (name + 3);
14769953Smsmith}
14869953Smsmith
14969908Smsmith/* This function is used to sort constructor elements by priority.  It
15069953Smsmith   is called via qsort.  */
15169953Smsmith
15269953Smsmithstatic int
15369953Smsmithctor_cmp (const void *p1, const void *p2)
15469953Smsmith{
15569953Smsmith  const struct set_element * const *pe1 = p1;
15669953Smsmith  const struct set_element * const *pe2 = p2;
15769908Smsmith  const char *n1;
15869908Smsmith  const char *n2;
15969908Smsmith  int prio1;
16069908Smsmith  int prio2;
16169908Smsmith
16269953Smsmith  n1 = (*pe1)->name;
16369953Smsmith  if (n1 == NULL)
16469953Smsmith    n1 = "";
16569953Smsmith  n2 = (*pe2)->name;
16669953Smsmith  if (n2 == NULL)
16769953Smsmith    n2 = "";
16869953Smsmith
16969953Smsmith  /* We need to sort in reverse order by priority.  When two
17069908Smsmith     constructors have the same priority, we should maintain their
17169908Smsmith     current relative position.  */
17269908Smsmith
17369908Smsmith  prio1 = ctor_prio (n1);
17469908Smsmith  prio2 = ctor_prio (n2);
17569908Smsmith
17669908Smsmith  /* We sort in reverse order because that is what g++ expects.  */
177119266Simp  if (prio1 < prio2)
17869908Smsmith    return 1;
17969908Smsmith  else if (prio1 > prio2)
18069908Smsmith    return -1;
18169908Smsmith
18269908Smsmith  /* Force a stable sort.  */
18369908Smsmith
18469908Smsmith  if (pe1 < pe2)
18569908Smsmith    return -1;
18669908Smsmith  else if (pe1 > pe2)
18769908Smsmith    return 1;
18869783Smsmith  else
18969783Smsmith    return 0;
19069783Smsmith}
19169783Smsmith
19269783Smsmith/* This function is called after the first phase of the link and
19369783Smsmith   before the second phase.  At this point all set information has
19469783Smsmith   been gathered.  We now put the statements to build the sets
19569783Smsmith   themselves into constructor_list.  */
19669783Smsmith
19769783Smsmithvoid
19869783Smsmithldctor_build_sets (void)
19969783Smsmith{
20069783Smsmith  static bfd_boolean called;
20169783Smsmith  lang_statement_list_type *old;
20269783Smsmith  bfd_boolean header_printed;
20369783Smsmith  struct set_info *p;
20469783Smsmith
20569783Smsmith  /* The emulation code may call us directly, but we only want to do
20669783Smsmith     this once.  */
207102441Sjhb  if (called)
20869783Smsmith    return;
209103042Sjhb  called = TRUE;
210102441Sjhb
211102441Sjhb  if (constructors_sorted)
212102441Sjhb    {
213102441Sjhb      for (p = sets; p != NULL; p = p->next)
214102441Sjhb	{
215102441Sjhb	  int c, i;
216102441Sjhb	  struct set_element *e;
21769783Smsmith	  struct set_element **array;
218103016Sjhb
21969783Smsmith	  if (p->elements == NULL)
22069783Smsmith	    continue;
22169783Smsmith
22269783Smsmith	  c = 0;
22369783Smsmith	  for (e = p->elements; e != NULL; e = e->next)
22469783Smsmith	    ++c;
22569783Smsmith
22669783Smsmith	  array = xmalloc (c * sizeof *array);
227102441Sjhb
22869783Smsmith	  i = 0;
22969783Smsmith	  for (e = p->elements; e != NULL; e = e->next)
23069783Smsmith	    {
23169783Smsmith	      array[i] = e;
23269783Smsmith	      ++i;
23369783Smsmith	    }
23469783Smsmith
23569783Smsmith	  qsort (array, c, sizeof *array, ctor_cmp);
23669783Smsmith
23769783Smsmith	  e = array[0];
23869783Smsmith	  p->elements = e;
23969783Smsmith	  for (i = 0; i < c - 1; i++)
240102441Sjhb	    array[i]->next = array[i + 1];
24169783Smsmith	  array[i]->next = NULL;
24269783Smsmith
24369783Smsmith	  free (array);
24469783Smsmith	}
24569783Smsmith    }
24669783Smsmith
24769783Smsmith  old = stat_ptr;
24869783Smsmith  stat_ptr = &constructor_list;
24969783Smsmith
25069783Smsmith  lang_list_init (stat_ptr);
25169783Smsmith
25269783Smsmith  header_printed = FALSE;
25369783Smsmith  for (p = sets; p != NULL; p = p->next)
25490388Simp    {
25590388Simp      struct set_element *e;
256107546Simp      reloc_howto_type *howto;
257107546Simp      int reloc_size, size;
25890388Simp
25990388Simp      /* If the symbol is defined, we may have been invoked from
26090388Simp	 collect, and the sets may already have been built, so we do
26190388Simp	 not do anything.  */
26290898Simp      if (p->h->type == bfd_link_hash_defined
26390388Simp	  || p->h->type == bfd_link_hash_defweak)
26490388Simp	continue;
26590388Simp
26690388Simp      /* For each set we build:
26790388Simp	   set:
26890388Simp	     .long number_of_elements
26990388Simp	     .long element0
27090388Simp	     ...
27190388Simp	     .long elementN
27290388Simp	     .long 0
27390898Simp	 except that we use the right size instead of .long.  When
27490388Simp	 generating relocatable output, we generate relocs instead of
27590388Simp	 addresses.  */
27690388Simp      howto = bfd_reloc_type_lookup (output_bfd, p->reloc);
27790388Simp      if (howto == NULL)
27890388Simp	{
279107546Simp	  if (link_info.relocatable)
280107546Simp	    {
281107546Simp	      einfo (_("%P%X: %s does not support reloc %s for set %s\n"),
282107546Simp		     bfd_get_target (output_bfd),
283107546Simp		     bfd_get_reloc_code_name (p->reloc),
284107546Simp		     p->h->root.string);
285107546Simp	      continue;
286107546Simp	    }
287107546Simp
288107546Simp	  /* If this is not a relocatable link, all we need is the
289107546Simp	     size, which we can get from the input BFD.  */
290107546Simp	  if (p->elements->section->owner != NULL)
291107546Simp	    howto = bfd_reloc_type_lookup (p->elements->section->owner,
292107546Simp					   p->reloc);
293107546Simp	  if (howto == NULL)
294107546Simp	    {
295107546Simp	      einfo (_("%P%X: %s does not support reloc %s for set %s\n"),
296107546Simp		     bfd_get_target (p->elements->section->owner),
297107546Simp		     bfd_get_reloc_code_name (p->reloc),
298107546Simp		     p->h->root.string);
299107546Simp	      continue;
300107546Simp	    }
301107546Simp	}
302107546Simp
303107546Simp      reloc_size = bfd_get_reloc_size (howto);
304107546Simp      switch (reloc_size)
305107546Simp	{
30669783Smsmith	case 1: size = BYTE; break;
30769783Smsmith	case 2: size = SHORT; break;
30869783Smsmith	case 4: size = LONG; break;
309102441Sjhb	case 8:
31069783Smsmith	  if (howto->complain_on_overflow == complain_overflow_signed)
31169783Smsmith	    size = SQUAD;
31269783Smsmith	  else
31369783Smsmith	    size = QUAD;
314107546Simp	  break;
31569783Smsmith	default:
31669783Smsmith	  einfo (_("%P%X: Unsupported size %d for set %s\n"),
31769783Smsmith		 bfd_get_reloc_size (howto), p->h->root.string);
31869783Smsmith	  size = LONG;
31969783Smsmith	  break;
32069783Smsmith	}
32169783Smsmith
32269783Smsmith      lang_add_assignment (exp_assop ('=', ".",
32369783Smsmith				      exp_unop (ALIGN_K,
32469783Smsmith						exp_intop (reloc_size))));
32569783Smsmith      lang_add_assignment (exp_assop ('=', p->h->root.string,
32669783Smsmith				      exp_nameop (NAME, ".")));
32769783Smsmith      lang_add_data (size, exp_intop (p->count));
32869783Smsmith
32969783Smsmith      for (e = p->elements; e != NULL; e = e->next)
330107546Simp	{
33190898Simp	  if (config.map_file != NULL)
332107546Simp	    {
333107546Simp	      int len;
334107546Simp
335106844Smdodd	      if (! header_printed)
336107546Simp		{
337107546Simp		  minfo (_("\nSet                 Symbol\n\n"));
338107546Simp		  header_printed = TRUE;
339107546Simp		}
340107546Simp
341107546Simp	      minfo ("%s", p->h->root.string);
342106844Smdodd	      len = strlen (p->h->root.string);
343106844Smdodd
344106844Smdodd	      if (len >= 19)
345106844Smdodd		{
346106844Smdodd		  print_nl ();
347106844Smdodd		  len = 0;
348106844Smdodd		}
349106844Smdodd	      while (len < 20)
350106844Smdodd		{
351106844Smdodd		  print_space ();
35290898Simp		  ++len;
353107546Simp		}
354107546Simp
355107546Simp	      if (e->name != NULL)
356107546Simp		minfo ("%T\n", e->name);
357107546Simp	      else
358107546Simp		minfo ("%G\n", e->section->owner, e->section, e->value);
359107546Simp	    }
360107546Simp
361107546Simp	  /* Need SEC_KEEP for --gc-sections.  */
362107546Simp	  if (! bfd_is_abs_section (e->section))
36390388Simp	    e->section->flags |= SEC_KEEP;
36469783Smsmith
36569908Smsmith	  if (link_info.relocatable)
36669908Smsmith	    lang_add_reloc (p->reloc, howto, e->section, e->name,
36769908Smsmith			    exp_intop (e->value));
36869783Smsmith	  else
36969783Smsmith	    lang_add_data (size, exp_relop (e->section, e->value));
37069783Smsmith	}
371107546Simp
37290898Simp      lang_add_data (size, exp_intop (0));
373107546Simp    }
374107546Simp
375107546Simp  stat_ptr = old;
376107546Simp}
377107546Simp