133965Sjdp/* ldctor.c -- constructor support routines
2130561Sobrien   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
3218822Sdim   2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
433965Sjdp   By Steve Chamberlain <sac@cygnus.com>
577298Sobrien
633965SjdpThis file is part of GLD, the Gnu Linker.
733965Sjdp
833965SjdpGLD is free software; you can redistribute it and/or modify
933965Sjdpit under the terms of the GNU General Public License as published by
1033965Sjdpthe Free Software Foundation; either version 2, or (at your option)
1133965Sjdpany later version.
1233965Sjdp
1333965SjdpGLD is distributed in the hope that it will be useful,
1433965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of
1533965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1633965SjdpGNU General Public License for more details.
1733965Sjdp
1833965SjdpYou should have received a copy of the GNU General Public License
1960484Sobrienalong with GLD; see the file COPYING.  If not, write to the Free
20218822SdimSoftware Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21218822Sdim02110-1301, USA.  */
2233965Sjdp
23218822Sdim#include "sysdep.h"
2433965Sjdp#include "bfd.h"
2533965Sjdp#include "bfdlink.h"
2689857Sobrien#include "safe-ctype.h"
2733965Sjdp
2833965Sjdp#include "ld.h"
2933965Sjdp#include "ldexp.h"
3033965Sjdp#include "ldlang.h"
3133965Sjdp#include "ldmisc.h"
32107492Sobrien#include <ldgram.h>
3333965Sjdp#include "ldmain.h"
3433965Sjdp#include "ldctor.h"
3533965Sjdp
3633965Sjdp/* The list of statements needed to handle constructors.  These are
3733965Sjdp   invoked by the command CONSTRUCTORS in the linker script.  */
3833965Sjdplang_statement_list_type constructor_list;
3933965Sjdp
4060484Sobrien/* Whether the constructors should be sorted.  Note that this is
4160484Sobrien   global for the entire link; we assume that there is only a single
4260484Sobrien   CONSTRUCTORS command in the linker script.  */
43130561Sobrienbfd_boolean constructors_sorted;
4460484Sobrien
4533965Sjdp/* The sets we have seen.  */
4633965Sjdpstruct set_info *sets;
4733965Sjdp
4833965Sjdp/* Add an entry to a set.  H is the entry in the linker hash table.
4933965Sjdp   RELOC is the relocation to use for an entry in the set.  SECTION
5033965Sjdp   and VALUE are the value to add.  This is called during the first
5133965Sjdp   phase of the link, when we are still gathering symbols together.
52218822Sdim   We just record the information now.  The ldctor_build_sets
5333965Sjdp   function will construct the sets.  */
5433965Sjdp
5533965Sjdpvoid
56130561Sobrienldctor_add_set_entry (struct bfd_link_hash_entry *h,
57130561Sobrien		      bfd_reloc_code_real_type reloc,
58130561Sobrien		      const char *name,
59130561Sobrien		      asection *section,
60130561Sobrien		      bfd_vma value)
6133965Sjdp{
6233965Sjdp  struct set_info *p;
6333965Sjdp  struct set_element *e;
6433965Sjdp  struct set_element **epp;
6533965Sjdp
66130561Sobrien  for (p = sets; p != NULL; p = p->next)
6733965Sjdp    if (p->h == h)
6833965Sjdp      break;
6933965Sjdp
70130561Sobrien  if (p == NULL)
7133965Sjdp    {
72130561Sobrien      p = xmalloc (sizeof (struct set_info));
7333965Sjdp      p->next = sets;
7433965Sjdp      sets = p;
7533965Sjdp      p->h = h;
7633965Sjdp      p->reloc = reloc;
7733965Sjdp      p->count = 0;
7833965Sjdp      p->elements = NULL;
7933965Sjdp    }
8033965Sjdp  else
8133965Sjdp    {
8233965Sjdp      if (p->reloc != reloc)
8333965Sjdp	{
8477298Sobrien	  einfo (_("%P%X: Different relocs used in set %s\n"),
8577298Sobrien		 h->root.string);
8633965Sjdp	  return;
8733965Sjdp	}
8833965Sjdp
8933965Sjdp      /* Don't permit a set to be constructed from different object
9033965Sjdp         file formats.  The same reloc may have different results.  We
9133965Sjdp         actually could sometimes handle this, but the case is
9233965Sjdp         unlikely to ever arise.  Sometimes constructor symbols are in
9333965Sjdp         unusual sections, such as the absolute section--this appears
9433965Sjdp         to be the case in Linux a.out--and in such cases we just
9533965Sjdp         assume everything is OK.  */
9633965Sjdp      if (p->elements != NULL
9733965Sjdp	  && section->owner != NULL
9833965Sjdp	  && p->elements->section->owner != NULL
9933965Sjdp	  && strcmp (bfd_get_target (section->owner),
10033965Sjdp		     bfd_get_target (p->elements->section->owner)) != 0)
10133965Sjdp	{
10260484Sobrien	  einfo (_("%P%X: Different object file formats composing set %s\n"),
10333965Sjdp		 h->root.string);
10433965Sjdp	  return;
10533965Sjdp	}
10633965Sjdp    }
10733965Sjdp
108130561Sobrien  e = xmalloc (sizeof (struct set_element));
10933965Sjdp  e->next = NULL;
11033965Sjdp  e->name = name;
11133965Sjdp  e->section = section;
11233965Sjdp  e->value = value;
11333965Sjdp
11433965Sjdp  for (epp = &p->elements; *epp != NULL; epp = &(*epp)->next)
11533965Sjdp    ;
11633965Sjdp  *epp = e;
11733965Sjdp
11833965Sjdp  ++p->count;
11933965Sjdp}
12033965Sjdp
12160484Sobrien/* Get the priority of a g++ global constructor or destructor from the
12260484Sobrien   symbol name.  */
12360484Sobrien
12460484Sobrienstatic int
125130561Sobrienctor_prio (const char *name)
12660484Sobrien{
12760484Sobrien  /* The name will look something like _GLOBAL_$I$65535$test02__Fv.
12860484Sobrien     There might be extra leading underscores, and the $ characters
12960484Sobrien     might be something else.  The I might be a D.  */
13060484Sobrien
13160484Sobrien  while (*name == '_')
13260484Sobrien    ++name;
13360484Sobrien
134218822Sdim  if (! CONST_STRNEQ (name, "GLOBAL_"))
13560484Sobrien    return -1;
13660484Sobrien
13760484Sobrien  name += sizeof "GLOBAL_" - 1;
13860484Sobrien
13960484Sobrien  if (name[0] != name[2])
14060484Sobrien    return -1;
14160484Sobrien  if (name[1] != 'I' && name[1] != 'D')
14260484Sobrien    return -1;
14389857Sobrien  if (! ISDIGIT (name[3]))
14460484Sobrien    return -1;
14560484Sobrien
14660484Sobrien  return atoi (name + 3);
14760484Sobrien}
14860484Sobrien
14960484Sobrien/* This function is used to sort constructor elements by priority.  It
15060484Sobrien   is called via qsort.  */
15160484Sobrien
15260484Sobrienstatic int
153130561Sobrienctor_cmp (const void *p1, const void *p2)
15460484Sobrien{
155130561Sobrien  const struct set_element * const *pe1 = p1;
156130561Sobrien  const struct set_element * const *pe2 = p2;
15760484Sobrien  const char *n1;
15860484Sobrien  const char *n2;
15960484Sobrien  int prio1;
16060484Sobrien  int prio2;
16160484Sobrien
16260484Sobrien  n1 = (*pe1)->name;
16360484Sobrien  if (n1 == NULL)
16460484Sobrien    n1 = "";
16560484Sobrien  n2 = (*pe2)->name;
16660484Sobrien  if (n2 == NULL)
16760484Sobrien    n2 = "";
16860484Sobrien
16960484Sobrien  /* We need to sort in reverse order by priority.  When two
17060484Sobrien     constructors have the same priority, we should maintain their
17160484Sobrien     current relative position.  */
17260484Sobrien
17360484Sobrien  prio1 = ctor_prio (n1);
17460484Sobrien  prio2 = ctor_prio (n2);
17560484Sobrien
17660484Sobrien  /* We sort in reverse order because that is what g++ expects.  */
17760484Sobrien  if (prio1 < prio2)
17860484Sobrien    return 1;
17960484Sobrien  else if (prio1 > prio2)
18060484Sobrien    return -1;
18160484Sobrien
18260484Sobrien  /* Force a stable sort.  */
18360484Sobrien
18460484Sobrien  if (pe1 < pe2)
18560484Sobrien    return -1;
18660484Sobrien  else if (pe1 > pe2)
18760484Sobrien    return 1;
18860484Sobrien  else
18960484Sobrien    return 0;
19060484Sobrien}
19160484Sobrien
19233965Sjdp/* This function is called after the first phase of the link and
19333965Sjdp   before the second phase.  At this point all set information has
19433965Sjdp   been gathered.  We now put the statements to build the sets
19533965Sjdp   themselves into constructor_list.  */
19633965Sjdp
19733965Sjdpvoid
198130561Sobrienldctor_build_sets (void)
19933965Sjdp{
200130561Sobrien  static bfd_boolean called;
20133965Sjdp  lang_statement_list_type *old;
202130561Sobrien  bfd_boolean header_printed;
20333965Sjdp  struct set_info *p;
20433965Sjdp
20533965Sjdp  /* The emulation code may call us directly, but we only want to do
20633965Sjdp     this once.  */
20733965Sjdp  if (called)
20833965Sjdp    return;
209130561Sobrien  called = TRUE;
21033965Sjdp
21160484Sobrien  if (constructors_sorted)
21260484Sobrien    {
21360484Sobrien      for (p = sets; p != NULL; p = p->next)
21460484Sobrien	{
21560484Sobrien	  int c, i;
21660484Sobrien	  struct set_element *e;
21760484Sobrien	  struct set_element **array;
21860484Sobrien
21960484Sobrien	  if (p->elements == NULL)
22060484Sobrien	    continue;
22160484Sobrien
22260484Sobrien	  c = 0;
22360484Sobrien	  for (e = p->elements; e != NULL; e = e->next)
22460484Sobrien	    ++c;
22560484Sobrien
226130561Sobrien	  array = xmalloc (c * sizeof *array);
22760484Sobrien
22860484Sobrien	  i = 0;
22960484Sobrien	  for (e = p->elements; e != NULL; e = e->next)
23060484Sobrien	    {
23160484Sobrien	      array[i] = e;
23260484Sobrien	      ++i;
23360484Sobrien	    }
23460484Sobrien
23560484Sobrien	  qsort (array, c, sizeof *array, ctor_cmp);
23660484Sobrien
23760484Sobrien	  e = array[0];
23860484Sobrien	  p->elements = e;
23960484Sobrien	  for (i = 0; i < c - 1; i++)
24060484Sobrien	    array[i]->next = array[i + 1];
24160484Sobrien	  array[i]->next = NULL;
24260484Sobrien
24360484Sobrien	  free (array);
24460484Sobrien	}
24560484Sobrien    }
24660484Sobrien
24733965Sjdp  old = stat_ptr;
24833965Sjdp  stat_ptr = &constructor_list;
24933965Sjdp
25033965Sjdp  lang_list_init (stat_ptr);
25133965Sjdp
252130561Sobrien  header_printed = FALSE;
253130561Sobrien  for (p = sets; p != NULL; p = p->next)
25433965Sjdp    {
25533965Sjdp      struct set_element *e;
25633965Sjdp      reloc_howto_type *howto;
25738889Sjdp      int reloc_size, size;
25833965Sjdp
25933965Sjdp      /* If the symbol is defined, we may have been invoked from
26033965Sjdp	 collect, and the sets may already have been built, so we do
26133965Sjdp	 not do anything.  */
26233965Sjdp      if (p->h->type == bfd_link_hash_defined
26333965Sjdp	  || p->h->type == bfd_link_hash_defweak)
26433965Sjdp	continue;
26533965Sjdp
26633965Sjdp      /* For each set we build:
26733965Sjdp	   set:
26833965Sjdp	     .long number_of_elements
26933965Sjdp	     .long element0
27033965Sjdp	     ...
27133965Sjdp	     .long elementN
27233965Sjdp	     .long 0
27333965Sjdp	 except that we use the right size instead of .long.  When
274130561Sobrien	 generating relocatable output, we generate relocs instead of
27533965Sjdp	 addresses.  */
27633965Sjdp      howto = bfd_reloc_type_lookup (output_bfd, p->reloc);
277130561Sobrien      if (howto == NULL)
27833965Sjdp	{
279130561Sobrien	  if (link_info.relocatable)
28033965Sjdp	    {
28160484Sobrien	      einfo (_("%P%X: %s does not support reloc %s for set %s\n"),
28233965Sjdp		     bfd_get_target (output_bfd),
28333965Sjdp		     bfd_get_reloc_code_name (p->reloc),
28433965Sjdp		     p->h->root.string);
28533965Sjdp	      continue;
28633965Sjdp	    }
28733965Sjdp
288130561Sobrien	  /* If this is not a relocatable link, all we need is the
28933965Sjdp	     size, which we can get from the input BFD.  */
29060484Sobrien	  if (p->elements->section->owner != NULL)
29160484Sobrien	    howto = bfd_reloc_type_lookup (p->elements->section->owner,
29260484Sobrien					   p->reloc);
29333965Sjdp	  if (howto == NULL)
29433965Sjdp	    {
29560484Sobrien	      einfo (_("%P%X: %s does not support reloc %s for set %s\n"),
29633965Sjdp		     bfd_get_target (p->elements->section->owner),
29733965Sjdp		     bfd_get_reloc_code_name (p->reloc),
29833965Sjdp		     p->h->root.string);
29933965Sjdp	      continue;
30033965Sjdp	    }
30133965Sjdp	}
30233965Sjdp
30338889Sjdp      reloc_size = bfd_get_reloc_size (howto);
30438889Sjdp      switch (reloc_size)
30533965Sjdp	{
30633965Sjdp	case 1: size = BYTE; break;
30733965Sjdp	case 2: size = SHORT; break;
30833965Sjdp	case 4: size = LONG; break;
30938889Sjdp	case 8:
31038889Sjdp	  if (howto->complain_on_overflow == complain_overflow_signed)
31138889Sjdp	    size = SQUAD;
31238889Sjdp	  else
31338889Sjdp	    size = QUAD;
31438889Sjdp	  break;
31533965Sjdp	default:
31660484Sobrien	  einfo (_("%P%X: Unsupported size %d for set %s\n"),
31733965Sjdp		 bfd_get_reloc_size (howto), p->h->root.string);
31833965Sjdp	  size = LONG;
31933965Sjdp	  break;
32033965Sjdp	}
32133965Sjdp
32238889Sjdp      lang_add_assignment (exp_assop ('=', ".",
32338889Sjdp				      exp_unop (ALIGN_K,
32438889Sjdp						exp_intop (reloc_size))));
32533965Sjdp      lang_add_assignment (exp_assop ('=', p->h->root.string,
32633965Sjdp				      exp_nameop (NAME, ".")));
327130561Sobrien      lang_add_data (size, exp_intop (p->count));
32833965Sjdp
329130561Sobrien      for (e = p->elements; e != NULL; e = e->next)
33033965Sjdp	{
33133965Sjdp	  if (config.map_file != NULL)
33233965Sjdp	    {
33333965Sjdp	      int len;
33433965Sjdp
33533965Sjdp	      if (! header_printed)
33633965Sjdp		{
33760484Sobrien		  minfo (_("\nSet                 Symbol\n\n"));
338130561Sobrien		  header_printed = TRUE;
33933965Sjdp		}
34033965Sjdp
34133965Sjdp	      minfo ("%s", p->h->root.string);
34233965Sjdp	      len = strlen (p->h->root.string);
34333965Sjdp
34433965Sjdp	      if (len >= 19)
34533965Sjdp		{
34633965Sjdp		  print_nl ();
34733965Sjdp		  len = 0;
34833965Sjdp		}
34933965Sjdp	      while (len < 20)
35033965Sjdp		{
35133965Sjdp		  print_space ();
35233965Sjdp		  ++len;
35333965Sjdp		}
35433965Sjdp
35533965Sjdp	      if (e->name != NULL)
35633965Sjdp		minfo ("%T\n", e->name);
35733965Sjdp	      else
35833965Sjdp		minfo ("%G\n", e->section->owner, e->section, e->value);
35933965Sjdp	    }
36033965Sjdp
36177298Sobrien	  /* Need SEC_KEEP for --gc-sections.  */
36260484Sobrien	  if (! bfd_is_abs_section (e->section))
36360484Sobrien	    e->section->flags |= SEC_KEEP;
36460484Sobrien
365130561Sobrien	  if (link_info.relocatable)
36633965Sjdp	    lang_add_reloc (p->reloc, howto, e->section, e->name,
36733965Sjdp			    exp_intop (e->value));
36833965Sjdp	  else
36933965Sjdp	    lang_add_data (size, exp_relop (e->section, e->value));
37033965Sjdp	}
37133965Sjdp
37233965Sjdp      lang_add_data (size, exp_intop (0));
37333965Sjdp    }
37433965Sjdp
37533965Sjdp  stat_ptr = old;
37633965Sjdp}
377