* interp.c (BUSERROR): New macro.
[deliverable/binutils-gdb.git] / ld / ldwrite.c
CommitLineData
4a6afc88
ILT
1/* ldwrite.c -- write out the linked file
2 Copyright (C) 1993 Free Software Foundation, Inc.
3 Written by Steve Chamberlain sac@cygnus.com
fcf276c4 4
2fa0b342
DHW
5This file is part of GLD, the Gnu Linker.
6
2e2bf962 7This program is free software; you can redistribute it and/or modify
2fa0b342 8it under the terms of the GNU General Public License as published by
2e2bf962
SC
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
2fa0b342 11
2e2bf962 12This program is distributed in the hope that it will be useful,
2fa0b342
DHW
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
2e2bf962
SC
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
2fa0b342 20
2fa0b342 21#include "bfd.h"
2e2bf962 22#include "sysdep.h"
4a6afc88 23#include "bfdlink.h"
2fa0b342 24
2fa0b342 25#include "ld.h"
fcf276c4
ILT
26#include "ldexp.h"
27#include "ldlang.h"
2fa0b342
DHW
28#include "ldwrite.h"
29#include "ldmisc.h"
2e2bf962 30#include "ldgram.h"
fcf276c4 31#include "ldmain.h"
4a6afc88
ILT
32
33static void build_link_order PARAMS ((lang_statement_union_type *));
34static void print_symbol_table PARAMS ((void));
35static void print_file_stuff PARAMS ((lang_input_statement_type *));
36static boolean print_symbol PARAMS ((struct bfd_link_hash_entry *, PTR));
37
38/* Build link_order structures for the BFD linker. */
2fa0b342
DHW
39
40static void
4a6afc88
ILT
41build_link_order (statement)
42 lang_statement_union_type *statement;
43{
44 switch (statement->header.type)
45 {
46 case lang_data_statement_enum:
4a6afc88 47 {
885ae6b9
SC
48 asection *output_section;
49 struct bfd_link_order *link_order;
50 bfd_vma value;
51
52 output_section = statement->data_statement.output_section;
53 ASSERT (output_section->owner == output_bfd);
54
55 link_order = bfd_new_link_order (output_bfd, output_section);
56 if (link_order == NULL)
57 einfo ("%P%F: bfd_new_link_order failed");
58
59 link_order->type = bfd_data_link_order;
60 link_order->offset = statement->data_statement.output_vma;
61 link_order->u.data.contents = (bfd_byte *) xmalloc (QUAD_SIZE);
62
63 value = statement->data_statement.value;
4a6afc88
ILT
64
65 ASSERT (output_section->owner == output_bfd);
66 switch (statement->data_statement.type)
67 {
4fdbafb2 68 case QUAD:
885ae6b9
SC
69 bfd_put_64 (output_bfd, value, link_order->u.data.contents);
70 link_order->size = QUAD_SIZE;
4fdbafb2 71 break;
4a6afc88 72 case LONG:
885ae6b9
SC
73 bfd_put_32 (output_bfd, value, link_order->u.data.contents);
74 link_order->size = LONG_SIZE;
4a6afc88
ILT
75 break;
76 case SHORT:
885ae6b9
SC
77 bfd_put_16 (output_bfd, value, link_order->u.data.contents);
78 link_order->size = SHORT_SIZE;
4a6afc88
ILT
79 break;
80 case BYTE:
885ae6b9
SC
81 bfd_put_8 (output_bfd, value, link_order->u.data.contents);
82 link_order->size = BYTE_SIZE;
4a6afc88
ILT
83 break;
84 default:
85 abort ();
86 }
4a6afc88
ILT
87 }
88 break;
89
4fdbafb2
ILT
90 case lang_reloc_statement_enum:
91 {
92 lang_reloc_statement_type *rs;
93 asection *output_section;
94 struct bfd_link_order *link_order;
95
96 rs = &statement->reloc_statement;
97
98 output_section = rs->output_section;
99 ASSERT (output_section->owner == output_bfd);
100
101 link_order = bfd_new_link_order (output_bfd, output_section);
102 if (link_order == NULL)
103 einfo ("%P%F: bfd_new_link_order failed");
104
105 link_order->offset = rs->output_vma;
106 link_order->size = bfd_get_reloc_size (rs->howto);
107
108 link_order->u.reloc.p =
109 ((struct bfd_link_order_reloc *)
110 xmalloc (sizeof (struct bfd_link_order_reloc)));
111
112 link_order->u.reloc.p->reloc = rs->reloc;
113 link_order->u.reloc.p->addend = rs->addend_value;
114
115 if (rs->section != (asection *) NULL)
116 {
117 ASSERT (rs->name == (const char *) NULL);
118 link_order->type = bfd_section_reloc_link_order;
119 if (rs->section->owner == output_bfd)
120 link_order->u.reloc.p->u.section = rs->section;
121 else
122 {
123 link_order->u.reloc.p->u.section = rs->section->output_section;
124 link_order->u.reloc.p->addend += rs->section->output_offset;
125 }
126 }
127 else
128 {
129 ASSERT (rs->name != (const char *) NULL);
130 link_order->type = bfd_symbol_reloc_link_order;
131 link_order->u.reloc.p->u.name = rs->name;
132 }
133 }
134 break;
135
4a6afc88
ILT
136 case lang_input_section_enum:
137 /* Create a new link_order in the output section with this
138 attached */
139 if (statement->input_section.ifile->just_syms_flag == false)
140 {
141 asection *i = statement->input_section.section;
142 asection *output_section = i->output_section;
143
144 ASSERT (output_section->owner == output_bfd);
145
146 if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
147 {
148 struct bfd_link_order *link_order;
149
150 link_order = bfd_new_link_order (output_bfd, output_section);
151
152 if (i->flags & SEC_NEVER_LOAD)
153 {
154 /* We've got a never load section inside one which
155 is going to be output, we'll change it into a
156 fill link_order */
157 link_order->type = bfd_fill_link_order;
158 link_order->u.fill.value = 0;
159 }
160 else
161 {
162 link_order->type = bfd_indirect_link_order;
163 link_order->u.indirect.section = i;
164 ASSERT (i->output_section == output_section);
165 }
4fdbafb2
ILT
166 if (i->_cooked_size)
167 link_order->size = i->_cooked_size;
168 else
169 link_order->size = bfd_get_section_size_before_reloc (i);
4a6afc88
ILT
170 link_order->offset = i->output_offset;
171 }
172 }
173 break;
174
175 case lang_padding_statement_enum:
176 /* Make a new link_order with the right filler */
177 {
178 asection *output_section;
179 struct bfd_link_order *link_order;
180
181 output_section = statement->padding_statement.output_section;
182 ASSERT (statement->padding_statement.output_section->owner
183 == output_bfd);
184 if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
185 {
186 link_order = bfd_new_link_order (output_bfd, output_section);
187 link_order->type = bfd_fill_link_order;
188 link_order->size = statement->padding_statement.size;
189 link_order->offset = statement->padding_statement.output_offset;
190 link_order->u.fill.value = statement->padding_statement.fill;
191 }
192 }
193 break;
194
195 default:
196 /* All the other ones fall through */
197 break;
198 }
199}
200
201/* Call BFD to write out the linked file. */
202
885ae6b9
SC
203
204/**********************************************************************/
205
206
207/* Wander around the input sections, make sure that
208 we'll never try and create an output section with more relocs
209 than will fit.. Do this by always assuming the worst case, and
210 creating new output sections with all the right bits */
211#define TESTIT 1
212static asection *
213clone_section (abfd, s, count)
214 bfd *abfd;
215 asection *s;
216 int *count;
217{
218#define SSIZE 8
219 char sname[SSIZE]; /* ?? find the name for this size */
220 asection *n;
221
222 /* Invent a section name - use first five
223 chars of base section name and a digit suffix */
224 do
225 {
226 int i;
227 char b[6];
228 for (i = 0; i < sizeof (b) - 1 && s->name[i]; i++)
229 b[i] = s->name[i];
230 b[i] = 0;
231 sprintf (sname, "%s%d", b, (*count)++);
232 }
233 while (bfd_get_section_by_name (abfd, sname));
234
235 n = bfd_make_section_anyway (abfd, strdup (sname));
236
237 n->flags = s->flags;
238 n->vma = s->vma;
239 n->user_set_vma = s->user_set_vma;
240 n->lma = s->lma;
241 n->_cooked_size = 0;
242 n->_raw_size = 0;
243 n->output_offset = s->output_offset;
244 n->output_section = n;
245 n->orelocation = 0;
246 n->reloc_count = 0;
247
248 return n;
249}
250
251#if TESTING
252static void
253ds (s)
254 asection *s;
255{
256 struct bfd_link_order *l = s->link_order_head;
257 printf ("vma %x size %x\n", s->vma, s->_raw_size);
258 while (l)
259 {
260 if (l->type == bfd_indirect_link_order)
261 {
262 printf ("%8x %s\n", l->offset, l->u.indirect.section->owner->filename);
263 }
264 else
265 {
266 printf ("%8x something else\n", l->offset);
267 }
268 l = l->next;
269 }
270 printf ("\n");
271}
272dump (s, a1, a2)
273 char *s;
274 asection *a1;
275 asection *a2;
276{
277 printf ("%s\n", s);
278 ds (a1);
279 ds (a2);
280}
281
282static void
283sanity_check (abfd)
284 bfd *abfd;
285{
286 asection *s;
287 for (s = abfd->sections; s; s = s->next)
288 {
289 struct bfd_link_order *p;
290 bfd_vma prev = 0;
291 for (p = s->link_order_head; p; p = p->next)
292 {
293 if (p->offset > 100000)
294 abort ();
295 if (p->offset < prev)
296 abort ();
297 prev = p->offset;
298 }
299 }
300}
301#else
302#define sanity_check(a)
303#define dump(a, b, c)
304#endif
305
306
307void
308split_sections (abfd, info)
309 bfd *abfd;
310 struct bfd_link_info *info;
311{
312 asection *original_sec;
313 int nsecs = abfd->section_count;
314 sanity_check (abfd);
315 /* look through all the original sections */
316 for (original_sec = abfd->sections;
317 original_sec && nsecs;
318 original_sec = original_sec->next, nsecs--)
319 {
320 int count = 0;
321 int lines = 0;
322 int relocs = 0;
323 struct bfd_link_order **pp;
324 bfd_vma vma = original_sec->vma;
325 bfd_vma shift_offset = 0;
326 asection *cursor = original_sec;
327 /* count up the relocations and line entries to see if
328 anything would be too big to fit */
329 for (pp = &(cursor->link_order_head); *pp; pp = &((*pp)->next))
330 {
331 struct bfd_link_order *p = *pp;
332 int thislines = 0;
333 int thisrelocs = 0;
334 if (p->type == bfd_indirect_link_order)
335 {
336 asection *sec;
337
338 sec = p->u.indirect.section;
339
340 if (info->strip == strip_none
341 || info->strip == strip_some)
342 thislines = sec->lineno_count;
343
344 if (info->relocateable)
345 thisrelocs = sec->reloc_count;
346
347 }
348 else if (info->relocateable
349 && (p->type == bfd_section_reloc_link_order
350 || p->type == bfd_symbol_reloc_link_order))
351 thisrelocs++;
352
353 if (thisrelocs + relocs > config.split_by_reloc
354 || thislines + lines > config.split_by_reloc
355 || config.split_by_file)
356 {
357 /* create a new section and put this link order and the
358 following link orders into it */
359 struct bfd_link_order *l = p;
360 asection *n = clone_section (abfd, cursor, &count);
361 *pp = NULL; /* Snip off link orders from old section */
362 n->link_order_head = l; /* attach to new section */
363 pp = &n->link_order_head;
364
365 /* change the size of the original section and
366 update the vma of the new one */
367
368 dump ("before snip", cursor, n);
369
370 n->_raw_size = cursor->_raw_size - l->offset;
371 cursor->_raw_size = l->offset;
372
373 vma += cursor->_raw_size;
374 n->lma = n->vma = vma;
375
376 shift_offset = l->offset;
377
378 /* run down the chain and change the output section to
379 the right one, update the offsets too */
380
381 while (l)
382 {
383 l->offset -= shift_offset;
384 if (l->type == bfd_indirect_link_order)
385 {
386 l->u.indirect.section->output_section = n;
387 l->u.indirect.section->output_offset = l->offset;
388 }
389 l = l->next;
390 }
391 dump ("after snip", cursor, n);
392 cursor = n;
393 relocs = thisrelocs;
394 lines = thislines;
395 }
396 else
397 {
398 relocs += thisrelocs;
399 lines += thislines;
400 }
401 }
402 }
403 sanity_check (abfd);
404}
405/**********************************************************************/
4a6afc88
ILT
406void
407ldwrite ()
2fa0b342 408{
4a6afc88 409 lang_for_each_statement (build_link_order);
2fa0b342 410
885ae6b9
SC
411 if (config.split_by_reloc || config.split_by_file)
412 split_sections (output_bfd, &link_info);
413 if (!bfd_final_link (output_bfd, &link_info))
4fdbafb2 414 einfo ("%F%P: final link failed: %E\n", output_bfd);
2fa0b342 415
4a6afc88 416 if (config.map_file)
fcf276c4 417 {
4a6afc88
ILT
418 print_symbol_table ();
419 lang_map ();
fcf276c4 420 }
2fa0b342
DHW
421}
422
4a6afc88 423/* Print the symbol table. */
2fa0b342 424
fcf276c4 425static void
4a6afc88 426print_symbol_table ()
2fa0b342 427{
4a6afc88
ILT
428 fprintf (config.map_file, "**FILES**\n\n");
429 lang_for_each_file (print_file_stuff);
430
431 fprintf (config.map_file, "**GLOBAL SYMBOLS**\n\n");
432 fprintf (config.map_file, "offset section offset symbol\n");
433 bfd_link_hash_traverse (link_info.hash, print_symbol, (PTR) NULL);
2fa0b342
DHW
434}
435
4a6afc88
ILT
436/* Print information about a file. */
437
438static void
439print_file_stuff (f)
885ae6b9 440 lang_input_statement_type *f;
4a6afc88
ILT
441{
442 fprintf (config.map_file, " %s\n", f->filename);
443 if (f->just_syms_flag)
444 {
445 fprintf (config.map_file, " symbols only\n");
446 }
447 else
448 {
449 asection *s;
450 if (true)
451 {
452 for (s = f->the_bfd->sections;
453 s != (asection *) NULL;
454 s = s->next)
455 {
456 print_address (s->output_offset);
457 if (s->reloc_done)
458 {
459 fprintf (config.map_file, " %08x 2**%2ud %s\n",
460 (unsigned) bfd_get_section_size_after_reloc (s),
461 s->alignment_power, s->name);
462 }
463
464 else
465 {
466 fprintf (config.map_file, " %08x 2**%2ud %s\n",
467 (unsigned) bfd_get_section_size_before_reloc (s),
468 s->alignment_power, s->name);
469 }
470 }
471 }
472 else
473 {
474 for (s = f->the_bfd->sections;
475 s != (asection *) NULL;
476 s = s->next)
477 {
478 fprintf (config.map_file, "%s ", s->name);
479 print_address (s->output_offset);
480 fprintf (config.map_file, "(%x)",
481 (unsigned) bfd_get_section_size_after_reloc (s));
482 }
483 fprintf (config.map_file, "hex \n");
484 }
485 }
486 print_nl ();
487}
488
489/* Print a symbol. */
490
4fdbafb2 491/*ARGSUSED*/
4a6afc88
ILT
492static boolean
493print_symbol (p, ignore)
494 struct bfd_link_hash_entry *p;
495 PTR ignore;
2fa0b342 496{
4a6afc88
ILT
497 while (p->type == bfd_link_hash_indirect
498 || p->type == bfd_link_hash_warning)
499 p = p->u.i.link;
500
885ae6b9 501 switch (p->type)
4a6afc88
ILT
502 {
503 case bfd_link_hash_new:
504 abort ();
fcf276c4 505
4a6afc88
ILT
506 case bfd_link_hash_undefined:
507 fprintf (config.map_file, "undefined ");
508 fprintf (config.map_file, "%s ", p->root.string);
885ae6b9 509 print_nl ();
4a6afc88 510 break;
fcf276c4 511
4a6afc88
ILT
512 case bfd_link_hash_weak:
513 fprintf (config.map_file, "weak ");
514 fprintf (config.map_file, "%s ", p->root.string);
885ae6b9 515 print_nl ();
4a6afc88 516 break;
fcf276c4 517
885ae6b9 518 case bfd_link_hash_defined:
4a6afc88
ILT
519 {
520 asection *defsec = p->u.def.section;
fcf276c4 521
4a6afc88
ILT
522 print_address (p->u.def.value);
523 if (defsec)
524 {
525 fprintf (config.map_file, " %-10s",
526 bfd_section_name (output_bfd, defsec));
527 print_space ();
528 print_address (p->u.def.value + defsec->vma);
529 }
530 else
531 {
532 fprintf (config.map_file, " .......");
533 }
534 fprintf (config.map_file, " %s ", p->root.string);
535 }
885ae6b9 536 print_nl ();
4a6afc88 537 break;
fcf276c4 538
4a6afc88
ILT
539 case bfd_link_hash_common:
540 fprintf (config.map_file, "common ");
541 print_address (p->u.c.size);
542 fprintf (config.map_file, " %s ", p->root.string);
543 print_nl ();
544 break;
2e2bf962 545
4a6afc88
ILT
546 default:
547 abort ();
548 }
2e2bf962 549
4a6afc88 550 return true;
2fa0b342 551}
This page took 0.16791 seconds and 4 git commands to generate.