(linenum→info "unix/slp.c:2238")

binutils/2.18/ld/ldctor.c

    1: /* ldctor.c -- constructor support routines
    2:    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
    3:    2002, 2003, 2004, 2006, 2007  Free Software Foundation, Inc.
    4:    By Steve Chamberlain <sac@cygnus.com>
    5: 
    6:    This file is part of the GNU Binutils.
    7: 
    8:    This program is free software; you can redistribute it and/or modify
    9:    it under the terms of the GNU General Public License as published by
   10:    the Free Software Foundation; either version 3 of the License, or
   11:    (at your option) any later version.
   12: 
   13:    This program is distributed in the hope that it will be useful,
   14:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   15:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16:    GNU General Public License for more details.
   17: 
   18:    You should have received a copy of the GNU General Public License
   19:    along with this program; if not, write to the Free Software
   20:    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   21:    MA 02110-1301, USA.  */
   22: 
   23: #include "sysdep.h"
   24: #include "bfd.h"
   25: #include "bfdlink.h"
   26: #include "safe-ctype.h"
   27: 
   28: #include "ld.h"
   29: #include "ldexp.h"
   30: #include "ldlang.h"
   31: #include "ldmisc.h"
   32: #include <ldgram.h>
   33: #include "ldmain.h"
   34: #include "ldctor.h"
   35: 
   36: /* The list of statements needed to handle constructors.  These are
   37:    invoked by the command CONSTRUCTORS in the linker script.  */
   38: lang_statement_list_type constructor_list;
   39: 
   40: /* Whether the constructors should be sorted.  Note that this is
   41:    global for the entire link; we assume that there is only a single
   42:    CONSTRUCTORS command in the linker script.  */
   43: bfd_boolean constructors_sorted;
   44: 
   45: /* The sets we have seen.  */
   46: struct set_info *sets;
   47: 
   48: /* Add an entry to a set.  H is the entry in the linker hash table.
   49:    RELOC is the relocation to use for an entry in the set.  SECTION
   50:    and VALUE are the value to add.  This is called during the first
   51:    phase of the link, when we are still gathering symbols together.
   52:    We just record the information now.  The ldctor_build_sets
   53:    function will construct the sets.  */
   54: 
   55: void
   56: ldctor_add_set_entry (struct bfd_link_hash_entry *h,
   57:                       bfd_reloc_code_real_type reloc,
   58:                       const char *name,
   59:                       asection *section,
   60:                       bfd_vma value)
   61: {
   62:   struct set_info *p;
   63:   struct set_element *e;
   64:   struct set_element **epp;
   65: 
   66:   for (p = sets; p != NULL; p = p->next)
   67:     if (p->h == h)
   68:       break;
   69: 
   70:   if (p == NULL)
   71:     {
   72:       p = xmalloc (sizeof (struct set_info));
   73:       p->next = sets;
   74:       sets = p;
   75:       p->h = h;
   76:       p->reloc = reloc;
   77:       p->count = 0;
   78:       p->elements = NULL;
   79:     }
   80:   else
   81:     {
   82:       if (p->reloc != reloc)
   83:         {
   84:           einfo (_("%P%X: Different relocs used in set %s\n"),
   85:                  h->root.string);
   86:           return;
   87:         }
   88: 
   89:       /* Don't permit a set to be constructed from different object
   90:          file formats.  The same reloc may have different results.  We
   91:          actually could sometimes handle this, but the case is
   92:          unlikely to ever arise.  Sometimes constructor symbols are in
   93:          unusual sections, such as the absolute section--this appears
   94:          to be the case in Linux a.out--and in such cases we just
   95:          assume everything is OK.  */
   96:       if (p->elements != NULL
   97:           && section->owner != NULL
   98:           && p->elements->section->owner != NULL
   99:           && strcmp (bfd_get_target (section->owner),
  100:                      bfd_get_target (p->elements->section->owner)) != 0)
  101:         {
  102:           einfo (_("%P%X: Different object file formats composing set %s\n"),
  103:                  h->root.string);
  104:           return;
  105:         }
  106:     }
  107: 
  108:   e = xmalloc (sizeof (struct set_element));
  109:   e->next = NULL;
  110:   e->name = name;
  111:   e->section = section;
  112:   e->value = value;
  113: 
  114:   for (epp = &p->elements; *epp != NULL; epp = &(*epp)->next)
  115:     ;
  116:   *epp = e;
  117: 
  118:   ++p->count;
  119: }
  120: 
  121: /* Get the priority of a g++ global constructor or destructor from the
  122:    symbol name.  */
  123: 
  124: static int
  125: ctor_prio (const char *name)
  126: {
  127:   /* The name will look something like _GLOBAL_$I$65535$test02__Fv.
  128:      There might be extra leading underscores, and the $ characters
  129:      might be something else.  The I might be a D.  */
  130: 
  131:   while (*name == '_')
  132:     ++name;
  133: 
  134:   if (! CONST_STRNEQ (name, "GLOBAL_"))
  135:     return -1;
  136: 
  137:   name += sizeof "GLOBAL_" - 1;
  138: 
  139:   if (name[0] != name[2])
  140:     return -1;
  141:   if (name[1] != 'I' && name[1] != 'D')
  142:     return -1;
  143:   if (! ISDIGIT (name[3]))
  144:     return -1;
  145: 
  146:   return atoi (name + 3);
  147: }
  148: 
  149: /* This function is used to sort constructor elements by priority.  It
  150:    is called via qsort.  */
  151: 
  152: static int
  153: ctor_cmp (const void *p1, const void *p2)
  154: {
  155:   const struct set_element * const *pe1 = p1;
  156:   const struct set_element * const *pe2 = p2;
  157:   const char *n1;
  158:   const char *n2;
  159:   int prio1;
  160:   int prio2;
  161: 
  162:   n1 = (*pe1)->name;
  163:   if (n1 == NULL)
  164:     n1 = "";
  165:   n2 = (*pe2)->name;
  166:   if (n2 == NULL)
  167:     n2 = "";
  168: 
  169:   /* We need to sort in reverse order by priority.  When two
  170:      constructors have the same priority, we should maintain their
  171:      current relative position.  */
  172: 
  173:   prio1 = ctor_prio (n1);
  174:   prio2 = ctor_prio (n2);
  175: 
  176:   /* We sort in reverse order because that is what g++ expects.  */
  177:   if (prio1 < prio2)
  178:     return 1;
  179:   else if (prio1 > prio2)
  180:     return -1;
  181: 
  182:   /* Force a stable sort.  */
  183: 
  184:   if (pe1 < pe2)
  185:     return -1;
  186:   else if (pe1 > pe2)
  187:     return 1;
  188:   else
  189:     return 0;
  190: }
  191: 
  192: /* This function is called after the first phase of the link and
  193:    before the second phase.  At this point all set information has
  194:    been gathered.  We now put the statements to build the sets
  195:    themselves into constructor_list.  */
  196: 
  197: void
  198: ldctor_build_sets (void)
  199: {
  200:   static bfd_boolean called;
  201:   lang_statement_list_type *old;
  202:   bfd_boolean header_printed;
  203:   struct set_info *p;
  204: 
  205:   /* The emulation code may call us directly, but we only want to do
  206:      this once.  */
  207:   if (called)
  208:     return;
  209:   called = TRUE;
  210: 
  211:   if (constructors_sorted)
  212:     {
  213:       for (p = sets; p != NULL; p = p->next)
  214:         {
  215:           int c, i;
  216:           struct set_element *e;
  217:           struct set_element **array;
  218: 
  219:           if (p->elements == NULL)
  220:             continue;
  221: 
  222:           c = 0;
  223:           for (e = p->elements; e != NULL; e = e->next)
  224:             ++c;
  225: 
  226:           array = xmalloc (c * sizeof *array);
  227: 
  228:           i = 0;
  229:           for (e = p->elements; e != NULL; e = e->next)
  230:             {
  231:               array[i] = e;
  232:               ++i;
  233:             }
  234: 
  235:           qsort (array, c, sizeof *array, ctor_cmp);
  236: 
  237:           e = array[0];
  238:           p->elements = e;
  239:           for (i = 0; i < c - 1; i++)
  240:             array[i]->next = array[i + 1];
  241:           array[i]->next = NULL;
  242: 
  243:           free (array);
  244:         }
  245:     }
  246: 
  247:   old = stat_ptr;
  248:   stat_ptr = &constructor_list;
  249: 
  250:   lang_list_init (stat_ptr);
  251: 
  252:   header_printed = FALSE;
  253:   for (p = sets; p != NULL; p = p->next)
  254:     {
  255:       struct set_element *e;
  256:       reloc_howto_type *howto;
  257:       int reloc_size, size;
  258: 
  259:       /* If the symbol is defined, we may have been invoked from
  260:          collect, and the sets may already have been built, so we do
  261:          not do anything.  */
  262:       if (p->h->type == bfd_link_hash_defined
  263:           || p->h->type == bfd_link_hash_defweak)
  264:         continue;
  265: 
  266:       /* For each set we build:
  267:            set:
  268:              .long number_of_elements
  269:              .long element0
  270:              ...
  271:              .long elementN
  272:              .long 0
  273:          except that we use the right size instead of .long.  When
  274:          generating relocatable output, we generate relocs instead of
  275:          addresses.  */
  276:       howto = bfd_reloc_type_lookup (output_bfd, p->reloc);
  277:       if (howto == NULL)
  278:         {
  279:           if (link_info.relocatable)
  280:             {
  281:               einfo (_("%P%X: %s does not support reloc %s for set %s\n"),
  282:                      bfd_get_target (output_bfd),
  283:                      bfd_get_reloc_code_name (p->reloc),
  284:                      p->h->root.string);
  285:               continue;
  286:             }
  287: 
  288:           /* If this is not a relocatable link, all we need is the
  289:              size, which we can get from the input BFD.  */
  290:           if (p->elements->section->owner != NULL)
  291:             howto = bfd_reloc_type_lookup (p->elements->section->owner,
  292:                                            p->reloc);
  293:           if (howto == NULL)
  294:             {
  295:               einfo (_("%P%X: %s does not support reloc %s for set %s\n"),
  296:                      bfd_get_target (p->elements->section->owner),
  297:                      bfd_get_reloc_code_name (p->reloc),
  298:                      p->h->root.string);
  299:               continue;
  300:             }
  301:         }
  302: 
  303:       reloc_size = bfd_get_reloc_size (howto);
  304:       switch (reloc_size)
  305:         {
  306:         case 1: size = BYTE; break;
  307:         case 2: size = SHORT; break;
  308:         case 4: size = LONG; break;
  309:         case 8:
  310:           if (howto->complain_on_overflow == complain_overflow_signed)
  311:             size = SQUAD;
  312:           else
  313:             size = QUAD;
  314:           break;
  315:         default:
  316:           einfo (_("%P%X: Unsupported size %d for set %s\n"),
  317:                  bfd_get_reloc_size (howto), p->h->root.string);
  318:           size = LONG;
  319:           break;
  320:         }
  321: 
  322:       lang_add_assignment (exp_assop ('=', ".",
  323:                                       exp_unop (ALIGN_K,
  324:                                                 exp_intop (reloc_size))));
  325:       lang_add_assignment (exp_assop ('=', p->h->root.string,
  326:                                       exp_nameop (NAME, ".")));
  327:       lang_add_data (size, exp_intop (p->count));
  328: 
  329:       for (e = p->elements; e != NULL; e = e->next)
  330:         {
  331:           if (config.map_file != NULL)
  332:             {
  333:               int len;
  334: 
  335:               if (! header_printed)
  336:                 {
  337:                   minfo (_("\nSet                 Symbol\n\n"));
  338:                   header_printed = TRUE;
  339:                 }
  340: 
  341:               minfo ("%s", p->h->root.string);
  342:               len = strlen (p->h->root.string);
  343: 
  344:               if (len >= 19)
  345:                 {
  346:                   print_nl ();
  347:                   len = 0;
  348:                 }
  349:               while (len < 20)
  350:                 {
  351:                   print_space ();
  352:                   ++len;
  353:                 }
  354: 
  355:               if (e->name != NULL)
  356:                 minfo ("%T\n", e->name);
  357:               else
  358:                 minfo ("%G\n", e->section->owner, e->section, e->value);
  359:             }
  360: 
  361:           /* Need SEC_KEEP for --gc-sections.  */
  362:           if (! bfd_is_abs_section (e->section))
  363:             e->section->flags |= SEC_KEEP;
  364: 
  365:           if (link_info.relocatable)
  366:             lang_add_reloc (p->reloc, howto, e->section, e->name,
  367:                             exp_intop (e->value));
  368:           else
  369:             lang_add_data (size, exp_relop (e->section, e->value));
  370:         }
  371: 
  372:       lang_add_data (size, exp_intop (0));
  373:     }
  374: 
  375:   stat_ptr = old;
  376: }
Syntax (Markdown)