Subversion Repositories Kolibri OS

Rev

Rev 5199 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5199 serge 1
/* ldctor.c -- constructor support routines
6324 serge 2
   Copyright (C) 1991-2015 Free Software Foundation, Inc.
5199 serge 3
   By Steve Chamberlain 
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
 
27
#include "ld.h"
28
#include "ldexp.h"
29
#include "ldlang.h"
30
#include "ldmisc.h"
31
#include 
32
#include "ldmain.h"
33
#include "ldctor.h"
34
 
35
/* The list of statements needed to handle constructors.  These are
36
   invoked by the command CONSTRUCTORS in the linker script.  */
37
lang_statement_list_type constructor_list;
38
 
39
/* Whether the constructors should be sorted.  Note that this is
40
   global for the entire link; we assume that there is only a single
41
   CONSTRUCTORS command in the linker script.  */
42
bfd_boolean constructors_sorted;
43
 
44
/* The sets we have seen.  */
45
struct set_info *sets;
46
 
47
/* Add an entry to a set.  H is the entry in the linker hash table.
48
   RELOC is the relocation to use for an entry in the set.  SECTION
49
   and VALUE are the value to add.  This is called during the first
50
   phase of the link, when we are still gathering symbols together.
51
   We just record the information now.  The ldctor_build_sets
52
   function will construct the sets.  */
53
 
54
void
55
ldctor_add_set_entry (struct bfd_link_hash_entry *h,
56
		      bfd_reloc_code_real_type reloc,
57
		      const char *name,
58
		      asection *section,
59
		      bfd_vma value)
60
{
61
  struct set_info *p;
62
  struct set_element *e;
63
  struct set_element **epp;
64
 
65
  for (p = sets; p != NULL; p = p->next)
66
    if (p->h == h)
67
      break;
68
 
69
  if (p == NULL)
70
    {
71
      p = (struct set_info *) xmalloc (sizeof (struct set_info));
72
      p->next = sets;
73
      sets = p;
74
      p->h = h;
75
      p->reloc = reloc;
76
      p->count = 0;
77
      p->elements = NULL;
78
    }
79
  else
80
    {
81
      if (p->reloc != reloc)
82
	{
83
	  einfo (_("%P%X: Different relocs used in set %s\n"),
84
		 h->root.string);
85
	  return;
86
	}
87
 
88
      /* Don't permit a set to be constructed from different object
89
         file formats.  The same reloc may have different results.  We
90
         actually could sometimes handle this, but the case is
91
         unlikely to ever arise.  Sometimes constructor symbols are in
92
         unusual sections, such as the absolute section--this appears
93
         to be the case in Linux a.out--and in such cases we just
94
         assume everything is OK.  */
95
      if (p->elements != NULL
96
	  && section->owner != NULL
97
	  && p->elements->section->owner != NULL
98
	  && strcmp (bfd_get_target (section->owner),
99
		     bfd_get_target (p->elements->section->owner)) != 0)
100
	{
101
	  einfo (_("%P%X: Different object file formats composing set %s\n"),
102
		 h->root.string);
103
	  return;
104
	}
105
    }
106
 
107
  e = (struct set_element *) xmalloc (sizeof (struct set_element));
108
  e->next = NULL;
109
  e->name = name;
110
  e->section = section;
111
  e->value = value;
112
 
113
  for (epp = &p->elements; *epp != NULL; epp = &(*epp)->next)
114
    ;
115
  *epp = e;
116
 
117
  ++p->count;
118
}
119
 
120
/* Get the priority of a g++ global constructor or destructor from the
121
   symbol name.  */
122
 
123
static int
124
ctor_prio (const char *name)
125
{
126
  /* The name will look something like _GLOBAL_$I$65535$test02__Fv.
127
     There might be extra leading underscores, and the $ characters
128
     might be something else.  The I might be a D.  */
129
 
130
  while (*name == '_')
131
    ++name;
132
 
133
  if (! CONST_STRNEQ (name, "GLOBAL_"))
134
    return -1;
135
 
136
  name += sizeof "GLOBAL_" - 1;
137
 
138
  if (name[0] != name[2])
139
    return -1;
140
  if (name[1] != 'I' && name[1] != 'D')
141
    return -1;
142
  if (! ISDIGIT (name[3]))
143
    return -1;
144
 
145
  return atoi (name + 3);
146
}
147
 
148
/* This function is used to sort constructor elements by priority.  It
149
   is called via qsort.  */
150
 
151
static int
152
ctor_cmp (const void *p1, const void *p2)
153
{
154
  const struct set_element * const *pe1 =
155
      (const struct set_element * const *) p1;
156
  const struct set_element * const *pe2 =
157
      (const struct set_element * const *) p2;
158
  const char *n1;
159
  const char *n2;
160
  int prio1;
161
  int prio2;
162
 
163
  n1 = (*pe1)->name;
164
  if (n1 == NULL)
165
    n1 = "";
166
  n2 = (*pe2)->name;
167
  if (n2 == NULL)
168
    n2 = "";
169
 
170
  /* We need to sort in reverse order by priority.  When two
171
     constructors have the same priority, we should maintain their
172
     current relative position.  */
173
 
174
  prio1 = ctor_prio (n1);
175
  prio2 = ctor_prio (n2);
176
 
177
  /* We sort in reverse order because that is what g++ expects.  */
178
  if (prio1 < prio2)
179
    return 1;
180
  else if (prio1 > prio2)
181
    return -1;
182
 
183
  /* Force a stable sort.  */
184
 
185
  if (pe1 < pe2)
186
    return -1;
187
  else if (pe1 > pe2)
188
    return 1;
189
  else
190
    return 0;
191
}
192
 
193
/* This function is called after the first phase of the link and
194
   before the second phase.  At this point all set information has
195
   been gathered.  We now put the statements to build the sets
196
   themselves into constructor_list.  */
197
 
198
void
199
ldctor_build_sets (void)
200
{
201
  static bfd_boolean called;
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 = (struct set_element **) 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
  lang_list_init (&constructor_list);
248
  push_stat_ptr (&constructor_list);
249
 
250
  header_printed = FALSE;
251
  for (p = sets; p != NULL; p = p->next)
252
    {
253
      struct set_element *e;
254
      reloc_howto_type *howto;
255
      int reloc_size, size;
256
 
257
      /* If the symbol is defined, we may have been invoked from
258
	 collect, and the sets may already have been built, so we do
259
	 not do anything.  */
260
      if (p->h->type == bfd_link_hash_defined
261
	  || p->h->type == bfd_link_hash_defweak)
262
	continue;
263
 
264
      /* For each set we build:
265
	   set:
266
	     .long number_of_elements
267
	     .long element0
268
	     ...
269
	     .long elementN
270
	     .long 0
271
	 except that we use the right size instead of .long.  When
272
	 generating relocatable output, we generate relocs instead of
273
	 addresses.  */
274
      howto = bfd_reloc_type_lookup (link_info.output_bfd, p->reloc);
275
      if (howto == NULL)
276
	{
6324 serge 277
	  if (bfd_link_relocatable (&link_info))
5199 serge 278
	    {
279
	      einfo (_("%P%X: %s does not support reloc %s for set %s\n"),
280
		     bfd_get_target (link_info.output_bfd),
281
		     bfd_get_reloc_code_name (p->reloc),
282
		     p->h->root.string);
283
	      continue;
284
	    }
285
 
286
	  /* If this is not a relocatable link, all we need is the
287
	     size, which we can get from the input BFD.  */
288
	  if (p->elements->section->owner != NULL)
289
	    howto = bfd_reloc_type_lookup (p->elements->section->owner,
290
					   p->reloc);
291
	  if (howto == NULL)
292
	    {
293
	      einfo (_("%P%X: %s does not support reloc %s for set %s\n"),
294
		     bfd_get_target (p->elements->section->owner),
295
		     bfd_get_reloc_code_name (p->reloc),
296
		     p->h->root.string);
297
	      continue;
298
	    }
299
	}
300
 
301
      reloc_size = bfd_get_reloc_size (howto);
302
      switch (reloc_size)
303
	{
304
	case 1: size = BYTE; break;
305
	case 2: size = SHORT; break;
306
	case 4: size = LONG; break;
307
	case 8:
308
	  if (howto->complain_on_overflow == complain_overflow_signed)
309
	    size = SQUAD;
310
	  else
311
	    size = QUAD;
312
	  break;
313
	default:
314
	  einfo (_("%P%X: Unsupported size %d for set %s\n"),
315
		 bfd_get_reloc_size (howto), p->h->root.string);
316
	  size = LONG;
317
	  break;
318
	}
319
 
320
      lang_add_assignment (exp_assign (".",
321
				       exp_unop (ALIGN_K,
322
						 exp_intop (reloc_size)),
323
				       FALSE));
324
      lang_add_assignment (exp_assign (p->h->root.string,
325
				       exp_nameop (NAME, "."),
326
				       FALSE));
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
 
6324 serge 365
	  if (bfd_link_relocatable (&link_info))
5199 serge 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
  pop_stat_ptr ();
376
}