Subversion Repositories Kolibri OS

Rev

Rev 5199 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5199 serge 1
/* ldwrite.c -- write out the linked file
6324 serge 2
   Copyright (C) 1991-2015 Free Software Foundation, Inc.
5199 serge 3
   Written 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 "libiberty.h"
26
#include "safe-ctype.h"
27
 
28
#include "ld.h"
29
#include "ldexp.h"
30
#include "ldlang.h"
31
#include "ldwrite.h"
32
#include "ldmisc.h"
33
#include 
34
#include "ldmain.h"
35
 
36
/* Build link_order structures for the BFD linker.  */
37
 
38
static void
39
build_link_order (lang_statement_union_type *statement)
40
{
41
  switch (statement->header.type)
42
    {
43
    case lang_data_statement_enum:
44
      {
45
	asection *output_section;
46
	struct bfd_link_order *link_order;
47
	bfd_vma value;
48
	bfd_boolean big_endian = FALSE;
49
 
50
	output_section = statement->data_statement.output_section;
51
	ASSERT (output_section->owner == link_info.output_bfd);
52
 
53
	if (!((output_section->flags & SEC_HAS_CONTENTS) != 0
54
	      || ((output_section->flags & SEC_LOAD) != 0
55
		  && (output_section->flags & SEC_THREAD_LOCAL))))
56
	  break;
57
 
58
	link_order = bfd_new_link_order (link_info.output_bfd, output_section);
59
	if (link_order == NULL)
60
	  einfo (_("%P%F: bfd_new_link_order failed\n"));
61
 
62
	link_order->type = bfd_data_link_order;
63
	link_order->offset = statement->data_statement.output_offset;
64
	link_order->u.data.contents = (bfd_byte *) xmalloc (QUAD_SIZE);
65
 
66
	value = statement->data_statement.value;
67
 
68
	/* If the endianness of the output BFD is not known, then we
69
	   base the endianness of the data on the first input file.
70
	   By convention, the bfd_put routines for an unknown
71
	   endianness are big endian, so we must swap here if the
72
	   input file is little endian.  */
73
	if (bfd_big_endian (link_info.output_bfd))
74
	  big_endian = TRUE;
75
	else if (bfd_little_endian (link_info.output_bfd))
76
	  big_endian = FALSE;
77
	else
78
	  {
79
	    bfd_boolean swap;
80
 
81
	    swap = FALSE;
82
	    if (command_line.endian == ENDIAN_BIG)
83
	      big_endian = TRUE;
84
	    else if (command_line.endian == ENDIAN_LITTLE)
85
	      {
86
		big_endian = FALSE;
87
		swap = TRUE;
88
	      }
89
	    else if (command_line.endian == ENDIAN_UNSET)
90
	      {
91
		big_endian = TRUE;
92
		{
93
		  LANG_FOR_EACH_INPUT_STATEMENT (s)
94
		    {
95
		      if (s->the_bfd != NULL)
96
			{
97
			  if (bfd_little_endian (s->the_bfd))
98
			    {
99
			      big_endian = FALSE;
100
			      swap = TRUE;
101
			    }
102
			  break;
103
			}
104
		    }
105
		}
106
	      }
107
 
108
	    if (swap)
109
	      {
110
		bfd_byte buffer[8];
111
 
112
		switch (statement->data_statement.type)
113
		  {
114
		  case QUAD:
115
		  case SQUAD:
116
		    if (sizeof (bfd_vma) >= QUAD_SIZE)
117
		      {
118
			bfd_putl64 (value, buffer);
119
			value = bfd_getb64 (buffer);
120
			break;
121
		      }
122
		    /* Fall through.  */
123
		  case LONG:
124
		    bfd_putl32 (value, buffer);
125
		    value = bfd_getb32 (buffer);
126
		    break;
127
		  case SHORT:
128
		    bfd_putl16 (value, buffer);
129
		    value = bfd_getb16 (buffer);
130
		    break;
131
		  case BYTE:
132
		    break;
133
		  default:
134
		    abort ();
135
		  }
136
	      }
137
	  }
138
 
139
	ASSERT (output_section->owner == link_info.output_bfd);
140
	switch (statement->data_statement.type)
141
	  {
142
	  case QUAD:
143
	  case SQUAD:
144
	    if (sizeof (bfd_vma) >= QUAD_SIZE)
145
	      bfd_put_64 (link_info.output_bfd, value,
146
			  link_order->u.data.contents);
147
	    else
148
	      {
149
		bfd_vma high;
150
 
151
		if (statement->data_statement.type == QUAD)
152
		  high = 0;
153
		else if ((value & 0x80000000) == 0)
154
		  high = 0;
155
		else
156
		  high = (bfd_vma) -1;
157
		bfd_put_32 (link_info.output_bfd, high,
158
			    (link_order->u.data.contents
159
			     + (big_endian ? 0 : 4)));
160
		bfd_put_32 (link_info.output_bfd, value,
161
			    (link_order->u.data.contents
162
			     + (big_endian ? 4 : 0)));
163
	      }
164
	    link_order->size = QUAD_SIZE;
165
	    break;
166
	  case LONG:
167
	    bfd_put_32 (link_info.output_bfd, value,
168
			link_order->u.data.contents);
169
	    link_order->size = LONG_SIZE;
170
	    break;
171
	  case SHORT:
172
	    bfd_put_16 (link_info.output_bfd, value,
173
			link_order->u.data.contents);
174
	    link_order->size = SHORT_SIZE;
175
	    break;
176
	  case BYTE:
177
	    bfd_put_8 (link_info.output_bfd, value,
178
		       link_order->u.data.contents);
179
	    link_order->size = BYTE_SIZE;
180
	    break;
181
	  default:
182
	    abort ();
183
	  }
184
	link_order->u.data.size = link_order->size;
185
      }
186
      break;
187
 
188
    case lang_reloc_statement_enum:
189
      {
190
	lang_reloc_statement_type *rs;
191
	asection *output_section;
192
	struct bfd_link_order *link_order;
193
 
194
	rs = &statement->reloc_statement;
195
 
196
	output_section = rs->output_section;
197
	ASSERT (output_section->owner == link_info.output_bfd);
198
 
199
	if (!((output_section->flags & SEC_HAS_CONTENTS) != 0
200
	      || ((output_section->flags & SEC_LOAD) != 0
201
		  && (output_section->flags & SEC_THREAD_LOCAL))))
202
	  break;
203
 
204
	link_order = bfd_new_link_order (link_info.output_bfd, output_section);
205
	if (link_order == NULL)
206
	  einfo (_("%P%F: bfd_new_link_order failed\n"));
207
 
208
	link_order->offset = rs->output_offset;
209
	link_order->size = bfd_get_reloc_size (rs->howto);
210
 
211
	link_order->u.reloc.p = (struct bfd_link_order_reloc *)
212
            xmalloc (sizeof (struct bfd_link_order_reloc));
213
 
214
	link_order->u.reloc.p->reloc = rs->reloc;
215
	link_order->u.reloc.p->addend = rs->addend_value;
216
 
217
	if (rs->name == NULL)
218
	  {
219
	    link_order->type = bfd_section_reloc_link_order;
220
	    if (rs->section->owner == link_info.output_bfd)
221
	      link_order->u.reloc.p->u.section = rs->section;
222
	    else
223
	      {
224
		link_order->u.reloc.p->u.section = rs->section->output_section;
225
		link_order->u.reloc.p->addend += rs->section->output_offset;
226
	      }
227
	  }
228
	else
229
	  {
230
	    link_order->type = bfd_symbol_reloc_link_order;
231
	    link_order->u.reloc.p->u.name = rs->name;
232
	  }
233
      }
234
      break;
235
 
236
    case lang_input_section_enum:
237
      {
238
	/* Create a new link_order in the output section with this
239
	   attached */
240
	asection *i = statement->input_section.section;
241
 
242
	if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
243
	    && (i->flags & SEC_EXCLUDE) == 0)
244
	  {
245
	    asection *output_section = i->output_section;
246
	    struct bfd_link_order *link_order;
247
 
248
	    ASSERT (output_section->owner == link_info.output_bfd);
249
 
250
	    if (!((output_section->flags & SEC_HAS_CONTENTS) != 0
251
		  || ((output_section->flags & SEC_LOAD) != 0
252
		      && (output_section->flags & SEC_THREAD_LOCAL))))
253
	      break;
254
 
255
	    link_order = bfd_new_link_order (link_info.output_bfd,
256
					     output_section);
257
 
258
	    if ((i->flags & SEC_NEVER_LOAD) != 0
259
		&& (i->flags & SEC_DEBUGGING) == 0)
260
	      {
261
		/* We've got a never load section inside one which is
262
		   going to be output, we'll change it into a fill.  */
263
		link_order->type = bfd_data_link_order;
264
		link_order->u.data.contents = (unsigned char *) "";
265
		link_order->u.data.size = 1;
266
	      }
267
	    else
268
	      {
269
		link_order->type = bfd_indirect_link_order;
270
		link_order->u.indirect.section = i;
271
		ASSERT (i->output_section == output_section);
272
	      }
273
	    link_order->size = i->size;
274
	    link_order->offset = i->output_offset;
275
	  }
276
      }
277
      break;
278
 
279
    case lang_padding_statement_enum:
280
      /* Make a new link_order with the right filler */
281
      {
282
	asection *output_section;
283
	struct bfd_link_order *link_order;
284
 
285
	output_section = statement->padding_statement.output_section;
286
	ASSERT (statement->padding_statement.output_section->owner
287
		== link_info.output_bfd);
288
 
289
	if (!((output_section->flags & SEC_HAS_CONTENTS) != 0
290
	      || ((output_section->flags & SEC_LOAD) != 0
291
		  && (output_section->flags & SEC_THREAD_LOCAL))))
292
	  break;
293
 
294
	link_order = bfd_new_link_order (link_info.output_bfd,
295
					 output_section);
296
	link_order->type = bfd_data_link_order;
297
	link_order->size = statement->padding_statement.size;
298
	link_order->offset = statement->padding_statement.output_offset;
299
	link_order->u.data.contents = statement->padding_statement.fill->data;
300
	link_order->u.data.size = statement->padding_statement.fill->size;
301
      }
302
      break;
303
 
304
    default:
305
      /* All the other ones fall through */
306
      break;
307
    }
308
}
309
 
310
/* Return true if NAME is the name of an unsplittable section. These
311
   are the stabs strings, dwarf strings.  */
312
 
313
static bfd_boolean
314
unsplittable_name (const char *name)
315
{
316
  if (CONST_STRNEQ (name, ".stab"))
317
    {
318
      /* There are several stab like string sections. We pattern match on
319
	 ".stab...str"  */
320
      unsigned len = strlen (name);
321
      if (strcmp (&name[len-3], "str") == 0)
322
	return TRUE;
323
    }
324
  else if (strcmp (name, "$GDB_STRINGS$") == 0)
325
    return TRUE;
326
  return FALSE;
327
}
328
 
329
/* Wander around the input sections, make sure that
330
   we'll never try and create an output section with more relocs
331
   than will fit.. Do this by always assuming the worst case, and
332
   creating new output sections with all the right bits.  */
333
#define TESTIT 1
334
static asection *
335
clone_section (bfd *abfd, asection *s, const char *name, int *count)
336
{
337
  char *tname;
338
  char *sname;
339
  unsigned int len;
340
  asection *n;
341
  struct bfd_link_hash_entry *h;
342
 
343
  /* Invent a section name from the section name and a dotted numeric
344
     suffix.   */
345
  len = strlen (name);
346
  tname = (char *) xmalloc (len + 1);
347
  memcpy (tname, name, len + 1);
348
  /* Remove a dotted number suffix, from a previous split link. */
349
  while (len && ISDIGIT (tname[len-1]))
350
    len--;
351
  if (len > 1 && tname[len-1] == '.')
352
    /* It was a dotted number. */
353
    tname[len-1] = 0;
354
 
355
  /* We want to use the whole of the original section name for the
356
     split name, but coff can be restricted to 8 character names.  */
357
  if (bfd_family_coff (abfd) && strlen (tname) > 5)
358
    {
359
      /* Some section names cannot be truncated, as the name is
360
	 used to locate some other section.  */
361
      if (CONST_STRNEQ (name, ".stab")
362
	  || strcmp (name, "$GDB_SYMBOLS$") == 0)
363
	{
364
	  einfo (_ ("%F%P: cannot create split section name for %s\n"), name);
365
	  /* Silence gcc warnings.  einfo exits, so we never reach here.  */
366
	  return NULL;
367
	}
368
      tname[5] = 0;
369
    }
370
 
371
  if ((sname = bfd_get_unique_section_name (abfd, tname, count)) == NULL
372
      || (n = bfd_make_section_anyway (abfd, sname)) == NULL
373
      || (h = bfd_link_hash_lookup (link_info.hash,
374
				    sname, TRUE, TRUE, FALSE)) == NULL)
375
    {
376
      einfo (_("%F%P: clone section failed: %E\n"));
377
      /* Silence gcc warnings.  einfo exits, so we never reach here.  */
378
      return NULL;
379
    }
380
  free (tname);
381
 
382
  /* Set up section symbol.  */
383
  h->type = bfd_link_hash_defined;
384
  h->u.def.value = 0;
385
  h->u.def.section = n;
386
 
387
  n->flags = s->flags;
388
  n->vma = s->vma;
389
  n->user_set_vma = s->user_set_vma;
390
  n->lma = s->lma;
391
  n->size = 0;
392
  n->output_offset = s->output_offset;
393
  n->output_section = n;
394
  n->orelocation = 0;
395
  n->reloc_count = 0;
396
  n->alignment_power = s->alignment_power;
397
 
398
  bfd_copy_private_section_data (abfd, s, abfd, n);
399
 
400
  return n;
401
}
402
 
403
#if TESTING
404
static void
405
ds (asection *s)
406
{
407
  struct bfd_link_order *l = s->map_head.link_order;
408
  printf ("vma %x size %x\n", s->vma, s->size);
409
  while (l)
410
    {
411
      if (l->type == bfd_indirect_link_order)
412
	{
413
	  printf ("%8x %s\n", l->offset, l->u.indirect.section->owner->filename);
414
	}
415
      else
416
	{
417
	  printf (_("%8x something else\n"), l->offset);
418
	}
419
      l = l->next;
420
    }
421
  printf ("\n");
422
}
423
 
424
dump (char *s, asection *a1, asection *a2)
425
{
426
  printf ("%s\n", s);
427
  ds (a1);
428
  ds (a2);
429
}
430
 
431
static void
432
sanity_check (bfd *abfd)
433
{
434
  asection *s;
435
  for (s = abfd->sections; s; s = s->next)
436
    {
437
      struct bfd_link_order *p;
438
      bfd_vma prev = 0;
439
      for (p = s->map_head.link_order; p; p = p->next)
440
	{
441
	  if (p->offset > 100000)
442
	    abort ();
443
	  if (p->offset < prev)
444
	    abort ();
445
	  prev = p->offset;
446
	}
447
    }
448
}
449
#else
450
#define sanity_check(a)
451
#define dump(a, b, c)
452
#endif
453
 
454
static void
455
split_sections (bfd *abfd, struct bfd_link_info *info)
456
{
457
  asection *original_sec;
458
  int nsecs = abfd->section_count;
459
  sanity_check (abfd);
460
  /* Look through all the original sections.  */
461
  for (original_sec = abfd->sections;
462
       original_sec && nsecs;
463
       original_sec = original_sec->next, nsecs--)
464
    {
465
      int count = 0;
466
      unsigned int lines = 0;
467
      unsigned int relocs = 0;
468
      bfd_size_type sec_size = 0;
469
      struct bfd_link_order *l;
470
      struct bfd_link_order *p;
471
      bfd_vma vma = original_sec->vma;
472
      asection *cursor = original_sec;
473
 
474
      /* Count up the relocations and line entries to see if anything
475
	 would be too big to fit.  Accumulate section size too.  */
476
      for (l = NULL, p = cursor->map_head.link_order; p != NULL; p = l->next)
477
	{
478
	  unsigned int thislines = 0;
479
	  unsigned int thisrelocs = 0;
480
	  bfd_size_type thissize = 0;
481
	  if (p->type == bfd_indirect_link_order)
482
	    {
483
	      asection *sec;
484
 
485
	      sec = p->u.indirect.section;
486
 
487
	      if (info->strip == strip_none
488
		  || info->strip == strip_some)
489
		thislines = sec->lineno_count;
490
 
6324 serge 491
	      if (bfd_link_relocatable (info))
5199 serge 492
		thisrelocs = sec->reloc_count;
493
 
494
	      thissize = sec->size;
495
 
496
	    }
6324 serge 497
	  else if (bfd_link_relocatable (info)
5199 serge 498
		   && (p->type == bfd_section_reloc_link_order
499
		       || p->type == bfd_symbol_reloc_link_order))
500
	    thisrelocs++;
501
 
502
	  if (l != NULL
503
	      && (thisrelocs + relocs >= config.split_by_reloc
504
		  || thislines + lines >= config.split_by_reloc
505
		  || (thissize + sec_size >= config.split_by_file))
506
	      && !unsplittable_name (cursor->name))
507
	    {
508
	      /* Create a new section and put this link order and the
509
		 following link orders into it.  */
510
	      bfd_vma shift_offset;
511
	      asection *n;
512
 
513
	      n = clone_section (abfd, cursor, original_sec->name, &count);
514
 
515
	      /* Attach the link orders to the new section and snip
516
		 them off from the old section.  */
517
	      n->map_head.link_order = p;
518
	      n->map_tail.link_order = cursor->map_tail.link_order;
519
	      cursor->map_tail.link_order = l;
520
	      l->next = NULL;
521
	      l = p;
522
 
523
	      /* Change the size of the original section and
524
		 update the vma of the new one.  */
525
 
526
	      dump ("before snip", cursor, n);
527
 
528
	      shift_offset = p->offset;
529
	      n->size = cursor->size - shift_offset;
530
	      cursor->size = shift_offset;
531
 
532
	      vma += shift_offset;
533
	      n->lma = n->vma = vma;
534
 
535
	      /* Run down the chain and change the output section to
536
		 the right one, update the offsets too.  */
537
	      do
538
		{
539
		  p->offset -= shift_offset;
540
		  if (p->type == bfd_indirect_link_order)
541
		    {
542
		      p->u.indirect.section->output_section = n;
543
		      p->u.indirect.section->output_offset = p->offset;
544
		    }
545
		  p = p->next;
546
		}
547
	      while (p);
548
 
549
	      dump ("after snip", cursor, n);
550
	      cursor = n;
551
	      relocs = thisrelocs;
552
	      lines = thislines;
553
	      sec_size = thissize;
554
	    }
555
	  else
556
	    {
557
	      l = p;
558
	      relocs += thisrelocs;
559
	      lines += thislines;
560
	      sec_size += thissize;
561
	    }
562
	}
563
    }
564
  sanity_check (abfd);
565
}
566
 
567
/* Call BFD to write out the linked file.  */
568
 
569
void
570
ldwrite (void)
571
{
572
  /* Reset error indicator, which can typically something like invalid
573
     format from opening up the .o files.  */
574
  bfd_set_error (bfd_error_no_error);
6324 serge 575
  lang_clear_os_map ();
5199 serge 576
  lang_for_each_statement (build_link_order);
577
 
578
  if (config.split_by_reloc != (unsigned) -1
579
      || config.split_by_file != (bfd_size_type) -1)
580
    split_sections (link_info.output_bfd, &link_info);
581
  if (!bfd_final_link (link_info.output_bfd, &link_info))
582
    {
583
      /* If there was an error recorded, print it out.  Otherwise assume
584
	 an appropriate error message like unknown symbol was printed
585
	 out.  */
586
 
587
      if (bfd_get_error () != bfd_error_no_error)
588
	einfo (_("%F%P: final link failed: %E\n"));
589
      else
590
	xexit (1);
591
    }
592
}