xref: /dragonfly/contrib/binutils-2.34/ld/ldctor.c (revision c37c9ab3)
1 /* ldctor.c -- constructor support routines
2    Copyright (C) 1991-2020 Free Software Foundation, Inc.
3    By Steve Chamberlain <sac@cygnus.com>
4 
5    This file is part of the GNU Binutils.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20    MA 02110-1301, USA.  */
21 
22 #include "sysdep.h"
23 #include "bfd.h"
24 #include "bfdlink.h"
25 #include "safe-ctype.h"
26 #include "ctf-api.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 = (struct set_info *) 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 (_("%X%P: 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 (_("%X%P: different object file formats composing set %s\n"),
103 		 h->root.string);
104 	  return;
105 	}
106     }
107 
108   e = (struct set_element *) xmalloc (sizeof (struct set_element));
109   e->u.next = NULL;
110   e->name = name;
111   e->section = section;
112   e->value = value;
113 
114   for (epp = &p->elements; *epp != NULL; epp = &(*epp)->u.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 *pe1 = *(const struct set_element **) p1;
156   const struct set_element *pe2 = *(const struct set_element **) 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   if (prio1 > prio2)
180     return -1;
181 
182   /* Force a stable sort.  */
183   if (pe1->u.idx < pe2->u.idx)
184     return -1;
185   if (pe1->u.idx > pe2->u.idx)
186     return 1;
187   return 0;
188 }
189 
190 /* This function is called after the first phase of the link and
191    before the second phase.  At this point all set information has
192    been gathered.  We now put the statements to build the sets
193    themselves into constructor_list.  */
194 
195 void
196 ldctor_build_sets (void)
197 {
198   static bfd_boolean called;
199   bfd_boolean header_printed;
200   struct set_info *p;
201 
202   /* The emulation code may call us directly, but we only want to do
203      this once.  */
204   if (called)
205     return;
206   called = TRUE;
207 
208   if (constructors_sorted)
209     {
210       for (p = sets; p != NULL; p = p->next)
211 	{
212 	  int c, i;
213 	  struct set_element *e, *enext;
214 	  struct set_element **array;
215 
216 	  if (p->elements == NULL)
217 	    continue;
218 
219 	  c = 0;
220 	  for (e = p->elements; e != NULL; e = e->u.next)
221 	    ++c;
222 
223 	  array = (struct set_element **) xmalloc (c * sizeof *array);
224 
225 	  i = 0;
226 	  for (e = p->elements; e != NULL; e = enext)
227 	    {
228 	      array[i] = e;
229 	      enext = e->u.next;
230 	      e->u.idx = i;
231 	      ++i;
232 	    }
233 
234 	  qsort (array, c, sizeof *array, ctor_cmp);
235 
236 	  e = array[0];
237 	  p->elements = e;
238 	  for (i = 0; i < c - 1; i++)
239 	    array[i]->u.next = array[i + 1];
240 	  array[i]->u.next = NULL;
241 
242 	  free (array);
243 	}
244     }
245 
246   lang_list_init (&constructor_list);
247   push_stat_ptr (&constructor_list);
248 
249   header_printed = FALSE;
250   for (p = sets; p != NULL; p = p->next)
251     {
252       struct set_element *e;
253       reloc_howto_type *howto;
254       int reloc_size, size;
255 
256       /* If the symbol is defined, we may have been invoked from
257 	 collect, and the sets may already have been built, so we do
258 	 not do anything.  */
259       if (p->h->type == bfd_link_hash_defined
260 	  || p->h->type == bfd_link_hash_defweak)
261 	continue;
262 
263       /* For each set we build:
264 	   set:
265 	     .long number_of_elements
266 	     .long element0
267 	     ...
268 	     .long elementN
269 	     .long 0
270 	 except that we use the right size instead of .long.  When
271 	 generating relocatable output, we generate relocs instead of
272 	 addresses.  */
273       howto = bfd_reloc_type_lookup (link_info.output_bfd, p->reloc);
274       if (howto == NULL)
275 	{
276 	  if (bfd_link_relocatable (&link_info))
277 	    {
278 	      einfo (_("%X%P: %s does not support reloc %s for set %s\n"),
279 		     bfd_get_target (link_info.output_bfd),
280 		     bfd_get_reloc_code_name (p->reloc),
281 		     p->h->root.string);
282 	      continue;
283 	    }
284 
285 	  /* If this is not a relocatable link, all we need is the
286 	     size, which we can get from the input BFD.  */
287 	  if (p->elements->section->owner != NULL)
288 	    howto = bfd_reloc_type_lookup (p->elements->section->owner,
289 					   p->reloc);
290 	  if (howto == NULL)
291 	    {
292 	      /* See PR 20911 for a reproducer.  */
293 	      if (p->elements->section->owner == NULL)
294 		einfo (_("%X%P: special section %s does not support reloc %s for set %s\n"),
295 		       bfd_section_name (p->elements->section),
296 		       bfd_get_reloc_code_name (p->reloc),
297 		       p->h->root.string);
298 	      else
299 		einfo (_("%X%P: %s does not support reloc %s for set %s\n"),
300 		       bfd_get_target (p->elements->section->owner),
301 		       bfd_get_reloc_code_name (p->reloc),
302 		       p->h->root.string);
303 	      continue;
304 	    }
305 	}
306 
307       reloc_size = bfd_get_reloc_size (howto);
308       switch (reloc_size)
309 	{
310 	case 1: size = BYTE; break;
311 	case 2: size = SHORT; break;
312 	case 4: size = LONG; break;
313 	case 8:
314 	  if (howto->complain_on_overflow == complain_overflow_signed)
315 	    size = SQUAD;
316 	  else
317 	    size = QUAD;
318 	  break;
319 	default:
320 	  einfo (_("%X%P: unsupported size %d for set %s\n"),
321 		 bfd_get_reloc_size (howto), p->h->root.string);
322 	  size = LONG;
323 	  break;
324 	}
325 
326       lang_add_assignment (exp_assign (".",
327 				       exp_unop (ALIGN_K,
328 						 exp_intop (reloc_size)),
329 				       FALSE));
330       lang_add_assignment (exp_assign (p->h->root.string,
331 				       exp_nameop (NAME, "."),
332 				       FALSE));
333       lang_add_data (size, exp_intop (p->count));
334 
335       for (e = p->elements; e != NULL; e = e->u.next)
336 	{
337 	  if (config.map_file != NULL)
338 	    {
339 	      int len;
340 
341 	      if (!header_printed)
342 		{
343 		  minfo (_("\nSet                 Symbol\n\n"));
344 		  header_printed = TRUE;
345 		}
346 
347 	      minfo ("%s", p->h->root.string);
348 	      len = strlen (p->h->root.string);
349 
350 	      if (len >= 19)
351 		{
352 		  print_nl ();
353 		  len = 0;
354 		}
355 	      while (len < 20)
356 		{
357 		  print_space ();
358 		  ++len;
359 		}
360 
361 	      if (e->name != NULL)
362 		minfo ("%pT\n", e->name);
363 	      else
364 		minfo ("%G\n", e->section->owner, e->section, e->value);
365 	    }
366 
367 	  /* Need SEC_KEEP for --gc-sections.  */
368 	  if (!bfd_is_abs_section (e->section))
369 	    e->section->flags |= SEC_KEEP;
370 
371 	  if (bfd_link_relocatable (&link_info))
372 	    lang_add_reloc (p->reloc, howto, e->section, e->name,
373 			    exp_intop (e->value));
374 	  else
375 	    lang_add_data (size, exp_relop (e->section, e->value));
376 	}
377 
378       lang_add_data (size, exp_intop (0));
379     }
380 
381   pop_stat_ptr ();
382 }
383