1 /* ldwrite.c -- write out the linked file
2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002
3 Free Software Foundation, Inc.
4 Written by Steve Chamberlain sac@cygnus.com
6 This file is part of GLD, the Gnu Linker.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25 #include "libiberty.h"
35 static void build_link_order PARAMS ((lang_statement_union_type *));
36 static asection *clone_section PARAMS ((bfd *, asection *, const char *, int *));
37 static void split_sections PARAMS ((bfd *, struct bfd_link_info *));
39 /* Build link_order structures for the BFD linker. */
42 build_link_order (statement)
43 lang_statement_union_type *statement;
45 switch (statement->header.type)
47 case lang_data_statement_enum:
49 asection *output_section;
50 struct bfd_link_order *link_order;
52 boolean big_endian = false;
54 output_section = statement->data_statement.output_section;
55 ASSERT (output_section->owner == output_bfd);
57 link_order = bfd_new_link_order (output_bfd, output_section);
58 if (link_order == NULL)
59 einfo (_("%P%F: bfd_new_link_order failed\n"));
61 link_order->type = bfd_data_link_order;
62 link_order->offset = statement->data_statement.output_vma;
63 link_order->u.data.contents = (bfd_byte *) xmalloc (QUAD_SIZE);
65 value = statement->data_statement.value;
67 /* If the endianness of the output BFD is not known, then we
68 base the endianness of the data on the first input file.
69 By convention, the bfd_put routines for an unknown
70 endianness are big endian, so we must swap here if the
71 input file is little endian. */
72 if (bfd_big_endian (output_bfd))
74 else if (bfd_little_endian (output_bfd))
81 if (command_line.endian == ENDIAN_BIG)
83 else if (command_line.endian == ENDIAN_LITTLE)
88 else if (command_line.endian == ENDIAN_UNSET)
92 LANG_FOR_EACH_INPUT_STATEMENT (s)
94 if (s->the_bfd != NULL)
96 if (bfd_little_endian (s->the_bfd))
111 switch (statement->data_statement.type)
115 if (sizeof (bfd_vma) >= QUAD_SIZE)
117 bfd_putl64 (value, buffer);
118 value = bfd_getb64 (buffer);
123 bfd_putl32 (value, buffer);
124 value = bfd_getb32 (buffer);
127 bfd_putl16 (value, buffer);
128 value = bfd_getb16 (buffer);
138 ASSERT (output_section->owner == output_bfd);
139 switch (statement->data_statement.type)
143 if (sizeof (bfd_vma) >= QUAD_SIZE)
144 bfd_put_64 (output_bfd, value, link_order->u.data.contents);
149 if (statement->data_statement.type == QUAD)
151 else if ((value & 0x80000000) == 0)
155 bfd_put_32 (output_bfd, high,
156 (link_order->u.data.contents
157 + (big_endian ? 0 : 4)));
158 bfd_put_32 (output_bfd, value,
159 (link_order->u.data.contents
160 + (big_endian ? 4 : 0)));
162 link_order->size = QUAD_SIZE;
165 bfd_put_32 (output_bfd, value, link_order->u.data.contents);
166 link_order->size = LONG_SIZE;
169 bfd_put_16 (output_bfd, value, link_order->u.data.contents);
170 link_order->size = SHORT_SIZE;
173 bfd_put_8 (output_bfd, value, link_order->u.data.contents);
174 link_order->size = BYTE_SIZE;
182 case lang_reloc_statement_enum:
184 lang_reloc_statement_type *rs;
185 asection *output_section;
186 struct bfd_link_order *link_order;
188 rs = &statement->reloc_statement;
190 output_section = rs->output_section;
191 ASSERT (output_section->owner == output_bfd);
193 link_order = bfd_new_link_order (output_bfd, output_section);
194 if (link_order == NULL)
195 einfo (_("%P%F: bfd_new_link_order failed\n"));
197 link_order->offset = rs->output_vma;
198 link_order->size = bfd_get_reloc_size (rs->howto);
200 link_order->u.reloc.p =
201 ((struct bfd_link_order_reloc *)
202 xmalloc (sizeof (struct bfd_link_order_reloc)));
204 link_order->u.reloc.p->reloc = rs->reloc;
205 link_order->u.reloc.p->addend = rs->addend_value;
207 if (rs->name == NULL)
209 link_order->type = bfd_section_reloc_link_order;
210 if (rs->section->owner == output_bfd)
211 link_order->u.reloc.p->u.section = rs->section;
214 link_order->u.reloc.p->u.section = rs->section->output_section;
215 link_order->u.reloc.p->addend += rs->section->output_offset;
220 link_order->type = bfd_symbol_reloc_link_order;
221 link_order->u.reloc.p->u.name = rs->name;
226 case lang_input_section_enum:
227 /* Create a new link_order in the output section with this
229 if (statement->input_section.ifile->just_syms_flag == false)
231 asection *i = statement->input_section.section;
232 asection *output_section = i->output_section;
234 ASSERT (output_section->owner == output_bfd);
236 if ((output_section->flags & SEC_HAS_CONTENTS) != 0
237 || ((output_section->flags & SEC_LOAD) != 0
238 && (output_section->flags & SEC_THREAD_LOCAL)))
240 struct bfd_link_order *link_order;
242 link_order = bfd_new_link_order (output_bfd, output_section);
244 if (i->flags & SEC_NEVER_LOAD)
246 /* We've got a never load section inside one which
247 is going to be output, we'll change it into a
249 link_order->type = bfd_data_link_order;
250 link_order->u.data.contents = "";
251 link_order->u.data.size = 1;
255 link_order->type = bfd_indirect_link_order;
256 link_order->u.indirect.section = i;
257 ASSERT (i->output_section == output_section);
260 link_order->size = i->_cooked_size;
262 link_order->size = bfd_get_section_size_before_reloc (i);
263 link_order->offset = i->output_offset;
268 case lang_padding_statement_enum:
269 /* Make a new link_order with the right filler */
271 asection *output_section;
272 struct bfd_link_order *link_order;
274 output_section = statement->padding_statement.output_section;
275 ASSERT (statement->padding_statement.output_section->owner
277 if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
279 link_order = bfd_new_link_order (output_bfd, output_section);
280 link_order->type = bfd_data_link_order;
281 link_order->size = statement->padding_statement.size;
282 link_order->offset = statement->padding_statement.output_offset;
283 link_order->u.data.contents = statement->padding_statement.fill->data;
284 link_order->u.data.size = statement->padding_statement.fill->size;
290 /* All the other ones fall through */
295 /* Call BFD to write out the linked file. */
297 /**********************************************************************/
299 /* Wander around the input sections, make sure that
300 we'll never try and create an output section with more relocs
301 than will fit.. Do this by always assuming the worst case, and
302 creating new output sections with all the right bits. */
305 clone_section (abfd, s, name, count)
314 struct bfd_link_hash_entry *h;
316 /* Invent a section name from the first five chars of the base
317 section name and a digit suffix. */
318 strncpy (templ, name, sizeof (templ) - 1);
319 templ[sizeof (templ) - 1] = '\0';
320 if ((sname = bfd_get_unique_section_name (abfd, templ, count)) == NULL
321 || (n = bfd_make_section_anyway (abfd, sname)) == NULL
322 || (h = bfd_link_hash_lookup (link_info.hash,
323 sname, true, true, false)) == NULL)
325 einfo (_("%F%P: clone section failed: %E\n"));
326 /* Silence gcc warnings. einfo exits, so we never reach here. */
330 /* Set up section symbol. */
331 h->type = bfd_link_hash_defined;
333 h->u.def.section = n;
337 n->user_set_vma = s->user_set_vma;
341 n->output_offset = s->output_offset;
342 n->output_section = n;
345 n->alignment_power = s->alignment_power;
354 struct bfd_link_order *l = s->link_order_head;
355 printf ("vma %x size %x\n", s->vma, s->_raw_size);
358 if (l->type == bfd_indirect_link_order)
360 printf ("%8x %s\n", l->offset, l->u.indirect.section->owner->filename);
364 printf (_("%8x something else\n"), l->offset);
386 for (s = abfd->sections; s; s = s->next)
388 struct bfd_link_order *p;
390 for (p = s->link_order_head; p; p = p->next)
392 if (p->offset > 100000)
394 if (p->offset < prev)
401 #define sanity_check(a)
402 #define dump(a, b, c)
406 split_sections (abfd, info)
408 struct bfd_link_info *info;
410 asection *original_sec;
411 int nsecs = abfd->section_count;
413 /* Look through all the original sections. */
414 for (original_sec = abfd->sections;
415 original_sec && nsecs;
416 original_sec = original_sec->next, nsecs--)
419 unsigned int lines = 0;
420 unsigned int relocs = 0;
421 bfd_size_type sec_size = 0;
422 struct bfd_link_order *l;
423 struct bfd_link_order *p;
424 bfd_vma vma = original_sec->vma;
425 asection *cursor = original_sec;
427 /* Count up the relocations and line entries to see if anything
428 would be too big to fit. Accumulate section size too. */
429 for (l = NULL, p = cursor->link_order_head; p != NULL; p = l->next)
431 unsigned int thislines = 0;
432 unsigned int thisrelocs = 0;
433 bfd_size_type thissize = 0;
434 if (p->type == bfd_indirect_link_order)
438 sec = p->u.indirect.section;
440 if (info->strip == strip_none
441 || info->strip == strip_some)
442 thislines = sec->lineno_count;
444 if (info->relocateable)
445 thisrelocs = sec->reloc_count;
447 if (sec->_cooked_size != 0)
448 thissize = sec->_cooked_size;
450 thissize = sec->_raw_size;
453 else if (info->relocateable
454 && (p->type == bfd_section_reloc_link_order
455 || p->type == bfd_symbol_reloc_link_order))
459 && (thisrelocs + relocs >= config.split_by_reloc
460 || thislines + lines >= config.split_by_reloc
461 || thissize + sec_size >= config.split_by_file))
463 /* Create a new section and put this link order and the
464 following link orders into it. */
465 bfd_vma shift_offset;
468 n = clone_section (abfd, cursor, original_sec->name, &count);
470 /* Attach the link orders to the new section and snip
471 them off from the old section. */
472 n->link_order_head = p;
473 n->link_order_tail = cursor->link_order_tail;
474 cursor->link_order_tail = l;
478 /* Change the size of the original section and
479 update the vma of the new one. */
481 dump ("before snip", cursor, n);
483 shift_offset = p->offset;
484 if (cursor->_cooked_size != 0)
486 n->_cooked_size = cursor->_cooked_size - shift_offset;
487 cursor->_cooked_size = shift_offset;
489 n->_raw_size = cursor->_raw_size - shift_offset;
490 cursor->_raw_size = shift_offset;
493 n->lma = n->vma = vma;
495 /* Run down the chain and change the output section to
496 the right one, update the offsets too. */
499 p->offset -= shift_offset;
500 if (p->type == bfd_indirect_link_order)
502 p->u.indirect.section->output_section = n;
503 p->u.indirect.section->output_offset = p->offset;
509 dump ("after snip", cursor, n);
518 relocs += thisrelocs;
520 sec_size += thissize;
527 /**********************************************************************/
532 /* Reset error indicator, which can typically something like invalid
533 format from opening up the .o files. */
534 bfd_set_error (bfd_error_no_error);
535 lang_for_each_statement (build_link_order);
537 if (config.split_by_reloc != (unsigned) -1
538 || config.split_by_file != (bfd_size_type) -1)
539 split_sections (output_bfd, &link_info);
540 if (!bfd_final_link (output_bfd, &link_info))
542 /* If there was an error recorded, print it out. Otherwise assume
543 an appropriate error message like unknown symbol was printed
546 if (bfd_get_error () != bfd_error_no_error)
547 einfo (_("%F%P: final link failed: %E\n"));