Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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