1 /* ldwrite.c -- write out the linked file
2 Copyright (C) 1993 Free Software Foundation, Inc.
5 This file is part of GLD, the Gnu Linker.
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 2 of the License, or
10 (at your option) any later version.
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
33 static void build_link_order PARAMS ((lang_statement_union_type *));
34 static void print_symbol_table PARAMS ((void));
35 static void print_file_stuff PARAMS ((lang_input_statement_type *));
36 static boolean print_symbol PARAMS ((struct bfd_link_hash_entry *, PTR));
38 /* Build link_order structures for the BFD linker. */
41 build_link_order (statement)
42 lang_statement_union_type *statement;
44 switch (statement->header.type)
46 case lang_data_statement_enum:
48 asection *output_section;
49 struct bfd_link_order *link_order;
52 output_section = statement->data_statement.output_section;
53 ASSERT (output_section->owner == output_bfd);
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");
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);
63 value = statement->data_statement.value;
65 ASSERT (output_section->owner == output_bfd);
66 switch (statement->data_statement.type)
69 bfd_put_64 (output_bfd, value, link_order->u.data.contents);
70 link_order->size = QUAD_SIZE;
73 bfd_put_32 (output_bfd, value, link_order->u.data.contents);
74 link_order->size = LONG_SIZE;
77 bfd_put_16 (output_bfd, value, link_order->u.data.contents);
78 link_order->size = SHORT_SIZE;
81 bfd_put_8 (output_bfd, value, link_order->u.data.contents);
82 link_order->size = BYTE_SIZE;
90 case lang_reloc_statement_enum:
92 lang_reloc_statement_type *rs;
93 asection *output_section;
94 struct bfd_link_order *link_order;
96 rs = &statement->reloc_statement;
98 output_section = rs->output_section;
99 ASSERT (output_section->owner == output_bfd);
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");
105 link_order->offset = rs->output_vma;
106 link_order->size = bfd_get_reloc_size (rs->howto);
108 link_order->u.reloc.p =
109 ((struct bfd_link_order_reloc *)
110 xmalloc (sizeof (struct bfd_link_order_reloc)));
112 link_order->u.reloc.p->reloc = rs->reloc;
113 link_order->u.reloc.p->addend = rs->addend_value;
115 if (rs->section != (asection *) NULL)
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;
123 link_order->u.reloc.p->u.section = rs->section->output_section;
124 link_order->u.reloc.p->addend += rs->section->output_offset;
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;
136 case lang_input_section_enum:
137 /* Create a new link_order in the output section with this
139 if (statement->input_section.ifile->just_syms_flag == false)
141 asection *i = statement->input_section.section;
142 asection *output_section = i->output_section;
144 ASSERT (output_section->owner == output_bfd);
146 if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
148 struct bfd_link_order *link_order;
150 link_order = bfd_new_link_order (output_bfd, output_section);
152 if (i->flags & SEC_NEVER_LOAD)
154 /* We've got a never load section inside one which
155 is going to be output, we'll change it into a
157 link_order->type = bfd_fill_link_order;
158 link_order->u.fill.value = 0;
162 link_order->type = bfd_indirect_link_order;
163 link_order->u.indirect.section = i;
164 ASSERT (i->output_section == output_section);
167 link_order->size = i->_cooked_size;
169 link_order->size = bfd_get_section_size_before_reloc (i);
170 link_order->offset = i->output_offset;
175 case lang_padding_statement_enum:
176 /* Make a new link_order with the right filler */
178 asection *output_section;
179 struct bfd_link_order *link_order;
181 output_section = statement->padding_statement.output_section;
182 ASSERT (statement->padding_statement.output_section->owner
184 if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
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;
196 /* All the other ones fall through */
201 /* Call BFD to write out the linked file. */
204 /**********************************************************************/
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 */
213 clone_section (abfd, s, count)
219 char sname[SSIZE]; /* ?? find the name for this size */
222 /* Invent a section name - use first five
223 chars of base section name and a digit suffix */
228 for (i = 0; i < sizeof (b) - 1 && s->name[i]; i++)
231 sprintf (sname, "%s%d", b, (*count)++);
233 while (bfd_get_section_by_name (abfd, sname));
235 n = bfd_make_section_anyway (abfd, strdup (sname));
239 n->user_set_vma = s->user_set_vma;
243 n->output_offset = s->output_offset;
244 n->output_section = n;
256 struct bfd_link_order *l = s->link_order_head;
257 printf ("vma %x size %x\n", s->vma, s->_raw_size);
260 if (l->type == bfd_indirect_link_order)
262 printf ("%8x %s\n", l->offset, l->u.indirect.section->owner->filename);
266 printf ("%8x something else\n", l->offset);
287 for (s = abfd->sections; s; s = s->next)
289 struct bfd_link_order *p;
291 for (p = s->link_order_head; p; p = p->next)
293 if (p->offset > 100000)
295 if (p->offset < prev)
302 #define sanity_check(a)
303 #define dump(a, b, c)
308 split_sections (abfd, info)
310 struct bfd_link_info *info;
312 asection *original_sec;
313 int nsecs = abfd->section_count;
315 /* look through all the original sections */
316 for (original_sec = abfd->sections;
317 original_sec && nsecs;
318 original_sec = original_sec->next, nsecs--)
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))
331 struct bfd_link_order *p = *pp;
334 if (p->type == bfd_indirect_link_order)
338 sec = p->u.indirect.section;
340 if (info->strip == strip_none
341 || info->strip == strip_some)
342 thislines = sec->lineno_count;
344 if (info->relocateable)
345 thisrelocs = sec->reloc_count;
348 else if (info->relocateable
349 && (p->type == bfd_section_reloc_link_order
350 || p->type == bfd_symbol_reloc_link_order))
353 if (thisrelocs + relocs > config.split_by_reloc
354 || thislines + lines > config.split_by_reloc
355 || config.split_by_file)
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;
365 /* change the size of the original section and
366 update the vma of the new one */
368 dump ("before snip", cursor, n);
370 n->_raw_size = cursor->_raw_size - l->offset;
371 cursor->_raw_size = l->offset;
373 vma += cursor->_raw_size;
374 n->lma = n->vma = vma;
376 shift_offset = l->offset;
378 /* run down the chain and change the output section to
379 the right one, update the offsets too */
383 l->offset -= shift_offset;
384 if (l->type == bfd_indirect_link_order)
386 l->u.indirect.section->output_section = n;
387 l->u.indirect.section->output_offset = l->offset;
391 dump ("after snip", cursor, n);
398 relocs += thisrelocs;
405 /**********************************************************************/
409 lang_for_each_statement (build_link_order);
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))
414 einfo ("%F%P: final link failed: %E\n", output_bfd);
418 print_symbol_table ();
423 /* Print the symbol table. */
426 print_symbol_table ()
428 fprintf (config.map_file, "**FILES**\n\n");
429 lang_for_each_file (print_file_stuff);
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);
436 /* Print information about a file. */
440 lang_input_statement_type *f;
442 fprintf (config.map_file, " %s\n", f->filename);
443 if (f->just_syms_flag)
445 fprintf (config.map_file, " symbols only\n");
452 for (s = f->the_bfd->sections;
453 s != (asection *) NULL;
456 print_address (s->output_offset);
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);
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);
474 for (s = f->the_bfd->sections;
475 s != (asection *) NULL;
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));
483 fprintf (config.map_file, "hex \n");
489 /* Print a symbol. */
493 print_symbol (p, ignore)
494 struct bfd_link_hash_entry *p;
497 while (p->type == bfd_link_hash_indirect
498 || p->type == bfd_link_hash_warning)
503 case bfd_link_hash_new:
506 case bfd_link_hash_undefined:
507 fprintf (config.map_file, "undefined ");
508 fprintf (config.map_file, "%s ", p->root.string);
512 case bfd_link_hash_weak:
513 fprintf (config.map_file, "weak ");
514 fprintf (config.map_file, "%s ", p->root.string);
518 case bfd_link_hash_defined:
520 asection *defsec = p->u.def.section;
522 print_address (p->u.def.value);
525 fprintf (config.map_file, " %-10s",
526 bfd_section_name (output_bfd, defsec));
528 print_address (p->u.def.value + defsec->vma);
532 fprintf (config.map_file, " .......");
534 fprintf (config.map_file, " %s ", p->root.string);
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);