From Richard Henderson <rth@redhat.com>:
[deliverable/binutils-gdb.git] / ld / ldwrite.c
CommitLineData
252b5132 1/* ldwrite.c -- write out the linked file
2c382fb6 2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002
252b5132
RH
3 Free Software Foundation, Inc.
4 Written by Steve Chamberlain sac@cygnus.com
5
6This file is part of GLD, the Gnu Linker.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
22#include "bfd.h"
23#include "sysdep.h"
24#include "bfdlink.h"
25#include "libiberty.h"
26
27#include "ld.h"
28#include "ldexp.h"
29#include "ldlang.h"
30#include "ldwrite.h"
31#include "ldmisc.h"
df2a7313 32#include <ldgram.h>
252b5132
RH
33#include "ldmain.h"
34
35static void build_link_order PARAMS ((lang_statement_union_type *));
a854a4a7 36static asection *clone_section PARAMS ((bfd *, asection *, const char *, int *));
252b5132
RH
37static void split_sections PARAMS ((bfd *, struct bfd_link_info *));
38
39/* Build link_order structures for the BFD linker. */
40
41static void
42build_link_order (statement)
43 lang_statement_union_type *statement;
44{
45 switch (statement->header.type)
46 {
47 case lang_data_statement_enum:
48 {
49 asection *output_section;
50 struct bfd_link_order *link_order;
51 bfd_vma value;
b34976b6 52 bfd_boolean big_endian = FALSE;
252b5132
RH
53
54 output_section = statement->data_statement.output_section;
55 ASSERT (output_section->owner == output_bfd);
56
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"));
60
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);
64
65 value = statement->data_statement.value;
66
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))
b34976b6 73 big_endian = TRUE;
252b5132 74 else if (bfd_little_endian (output_bfd))
b34976b6 75 big_endian = FALSE;
252b5132
RH
76 else
77 {
b34976b6 78 bfd_boolean swap;
252b5132 79
b34976b6 80 swap = FALSE;
252b5132 81 if (command_line.endian == ENDIAN_BIG)
b34976b6 82 big_endian = TRUE;
252b5132
RH
83 else if (command_line.endian == ENDIAN_LITTLE)
84 {
b34976b6
AM
85 big_endian = FALSE;
86 swap = TRUE;
252b5132
RH
87 }
88 else if (command_line.endian == ENDIAN_UNSET)
89 {
b34976b6 90 big_endian = TRUE;
252b5132
RH
91 {
92 LANG_FOR_EACH_INPUT_STATEMENT (s)
93 {
94 if (s->the_bfd != NULL)
95 {
96 if (bfd_little_endian (s->the_bfd))
97 {
b34976b6
AM
98 big_endian = FALSE;
99 swap = TRUE;
252b5132
RH
100 }
101 break;
102 }
103 }
104 }
105 }
106
107 if (swap)
108 {
109 bfd_byte buffer[8];
110
111 switch (statement->data_statement.type)
112 {
113 case QUAD:
114 case SQUAD:
115 if (sizeof (bfd_vma) >= QUAD_SIZE)
116 {
117 bfd_putl64 (value, buffer);
118 value = bfd_getb64 (buffer);
119 break;
120 }
121 /* Fall through. */
122 case LONG:
123 bfd_putl32 (value, buffer);
124 value = bfd_getb32 (buffer);
125 break;
126 case SHORT:
127 bfd_putl16 (value, buffer);
128 value = bfd_getb16 (buffer);
129 break;
130 case BYTE:
131 break;
132 default:
133 abort ();
134 }
135 }
136 }
137
138 ASSERT (output_section->owner == output_bfd);
139 switch (statement->data_statement.type)
140 {
141 case QUAD:
142 case SQUAD:
143 if (sizeof (bfd_vma) >= QUAD_SIZE)
144 bfd_put_64 (output_bfd, value, link_order->u.data.contents);
145 else
146 {
147 bfd_vma high;
148
149 if (statement->data_statement.type == QUAD)
150 high = 0;
151 else if ((value & 0x80000000) == 0)
152 high = 0;
153 else
154 high = (bfd_vma) -1;
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)));
161 }
162 link_order->size = QUAD_SIZE;
163 break;
164 case LONG:
165 bfd_put_32 (output_bfd, value, link_order->u.data.contents);
166 link_order->size = LONG_SIZE;
167 break;
168 case SHORT:
169 bfd_put_16 (output_bfd, value, link_order->u.data.contents);
170 link_order->size = SHORT_SIZE;
171 break;
172 case BYTE:
173 bfd_put_8 (output_bfd, value, link_order->u.data.contents);
174 link_order->size = BYTE_SIZE;
175 break;
176 default:
177 abort ();
178 }
179 }
180 break;
181
182 case lang_reloc_statement_enum:
183 {
184 lang_reloc_statement_type *rs;
185 asection *output_section;
186 struct bfd_link_order *link_order;
187
188 rs = &statement->reloc_statement;
189
190 output_section = rs->output_section;
191 ASSERT (output_section->owner == output_bfd);
192
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"));
196
197 link_order->offset = rs->output_vma;
198 link_order->size = bfd_get_reloc_size (rs->howto);
199
200 link_order->u.reloc.p =
201 ((struct bfd_link_order_reloc *)
202 xmalloc (sizeof (struct bfd_link_order_reloc)));
203
204 link_order->u.reloc.p->reloc = rs->reloc;
205 link_order->u.reloc.p->addend = rs->addend_value;
206
207 if (rs->name == NULL)
208 {
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;
212 else
213 {
214 link_order->u.reloc.p->u.section = rs->section->output_section;
215 link_order->u.reloc.p->addend += rs->section->output_offset;
216 }
217 }
218 else
219 {
220 link_order->type = bfd_symbol_reloc_link_order;
221 link_order->u.reloc.p->u.name = rs->name;
222 }
223 }
224 break;
225
226 case lang_input_section_enum:
227 /* Create a new link_order in the output section with this
228 attached */
b34976b6 229 if (!statement->input_section.ifile->just_syms_flag)
252b5132
RH
230 {
231 asection *i = statement->input_section.section;
232 asection *output_section = i->output_section;
233
234 ASSERT (output_section->owner == output_bfd);
235
13ae64f3
JJ
236 if ((output_section->flags & SEC_HAS_CONTENTS) != 0
237 || ((output_section->flags & SEC_LOAD) != 0
238 && (output_section->flags & SEC_THREAD_LOCAL)))
252b5132
RH
239 {
240 struct bfd_link_order *link_order;
241
242 link_order = bfd_new_link_order (output_bfd, output_section);
243
244 if (i->flags & SEC_NEVER_LOAD)
245 {
246 /* We've got a never load section inside one which
247 is going to be output, we'll change it into a
2c382fb6
AM
248 fill. */
249 link_order->type = bfd_data_link_order;
250 link_order->u.data.contents = "";
251 link_order->u.data.size = 1;
252b5132
RH
252 }
253 else
254 {
255 link_order->type = bfd_indirect_link_order;
256 link_order->u.indirect.section = i;
257 ASSERT (i->output_section == output_section);
258 }
259 if (i->_cooked_size)
260 link_order->size = i->_cooked_size;
261 else
262 link_order->size = bfd_get_section_size_before_reloc (i);
263 link_order->offset = i->output_offset;
264 }
265 }
266 break;
267
268 case lang_padding_statement_enum:
269 /* Make a new link_order with the right filler */
270 {
271 asection *output_section;
272 struct bfd_link_order *link_order;
273
274 output_section = statement->padding_statement.output_section;
275 ASSERT (statement->padding_statement.output_section->owner
276 == output_bfd);
277 if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
278 {
279 link_order = bfd_new_link_order (output_bfd, output_section);
2c382fb6 280 link_order->type = bfd_data_link_order;
252b5132
RH
281 link_order->size = statement->padding_statement.size;
282 link_order->offset = statement->padding_statement.output_offset;
2c382fb6
AM
283 link_order->u.data.contents = statement->padding_statement.fill->data;
284 link_order->u.data.size = statement->padding_statement.fill->size;
252b5132
RH
285 }
286 }
287 break;
288
289 default:
290 /* All the other ones fall through */
291 break;
292 }
293}
294
295/* Call BFD to write out the linked file. */
296
252b5132
RH
297/**********************************************************************/
298
252b5132
RH
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
a854a4a7 302 creating new output sections with all the right bits. */
252b5132
RH
303#define TESTIT 1
304static asection *
a854a4a7 305clone_section (abfd, s, name, count)
252b5132
RH
306 bfd *abfd;
307 asection *s;
a854a4a7 308 const char *name;
252b5132
RH
309 int *count;
310{
b3ea3584 311 char templ[6];
a854a4a7 312 char *sname;
252b5132
RH
313 asection *n;
314 struct bfd_link_hash_entry *h;
252b5132 315
a854a4a7
AM
316 /* Invent a section name from the first five chars of the base
317 section name and a digit suffix. */
b3ea3584
AM
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,
b34976b6 323 sname, TRUE, TRUE, FALSE)) == NULL)
e2eb67d9
AM
324 {
325 einfo (_("%F%P: clone section failed: %E\n"));
326 /* Silence gcc warnings. einfo exits, so we never reach here. */
327 return NULL;
328 }
b3ea3584
AM
329
330 /* Set up section symbol. */
252b5132
RH
331 h->type = bfd_link_hash_defined;
332 h->u.def.value = 0;
a854a4a7 333 h->u.def.section = n;
252b5132
RH
334
335 n->flags = s->flags;
336 n->vma = s->vma;
337 n->user_set_vma = s->user_set_vma;
338 n->lma = s->lma;
339 n->_cooked_size = 0;
340 n->_raw_size = 0;
341 n->output_offset = s->output_offset;
342 n->output_section = n;
343 n->orelocation = 0;
344 n->reloc_count = 0;
345 n->alignment_power = s->alignment_power;
346 return n;
347}
348
349#if TESTING
6d5e62f8 350static void
252b5132
RH
351ds (s)
352 asection *s;
353{
354 struct bfd_link_order *l = s->link_order_head;
355 printf ("vma %x size %x\n", s->vma, s->_raw_size);
356 while (l)
357 {
358 if (l->type == bfd_indirect_link_order)
359 {
360 printf ("%8x %s\n", l->offset, l->u.indirect.section->owner->filename);
361 }
362 else
363 {
364 printf (_("%8x something else\n"), l->offset);
365 }
366 l = l->next;
367 }
368 printf ("\n");
369}
6d5e62f8 370
252b5132
RH
371dump (s, a1, a2)
372 char *s;
373 asection *a1;
374 asection *a2;
375{
376 printf ("%s\n", s);
377 ds (a1);
378 ds (a2);
379}
380
6d5e62f8 381static void
252b5132
RH
382sanity_check (abfd)
383 bfd *abfd;
384{
385 asection *s;
386 for (s = abfd->sections; s; s = s->next)
387 {
388 struct bfd_link_order *p;
389 bfd_vma prev = 0;
390 for (p = s->link_order_head; p; p = p->next)
391 {
392 if (p->offset > 100000)
393 abort ();
394 if (p->offset < prev)
395 abort ();
396 prev = p->offset;
397 }
398 }
399}
400#else
401#define sanity_check(a)
402#define dump(a, b, c)
403#endif
404
6d5e62f8 405static void
252b5132
RH
406split_sections (abfd, info)
407 bfd *abfd;
408 struct bfd_link_info *info;
409{
410 asection *original_sec;
411 int nsecs = abfd->section_count;
412 sanity_check (abfd);
a854a4a7 413 /* Look through all the original sections. */
252b5132
RH
414 for (original_sec = abfd->sections;
415 original_sec && nsecs;
416 original_sec = original_sec->next, nsecs--)
417 {
252b5132 418 int count = 0;
a854a4a7
AM
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;
252b5132 424 bfd_vma vma = original_sec->vma;
252b5132
RH
425 asection *cursor = original_sec;
426
a854a4a7
AM
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)
252b5132 430 {
a854a4a7
AM
431 unsigned int thislines = 0;
432 unsigned int thisrelocs = 0;
433 bfd_size_type thissize = 0;
252b5132
RH
434 if (p->type == bfd_indirect_link_order)
435 {
436 asection *sec;
437
438 sec = p->u.indirect.section;
439
440 if (info->strip == strip_none
441 || info->strip == strip_some)
442 thislines = sec->lineno_count;
443
444 if (info->relocateable)
445 thisrelocs = sec->reloc_count;
446
a854a4a7
AM
447 if (sec->_cooked_size != 0)
448 thissize = sec->_cooked_size;
449 else
450 thissize = sec->_raw_size;
451
252b5132
RH
452 }
453 else if (info->relocateable
454 && (p->type == bfd_section_reloc_link_order
455 || p->type == bfd_symbol_reloc_link_order))
456 thisrelocs++;
457
a854a4a7
AM
458 if (l != NULL
459 && (thisrelocs + relocs >= config.split_by_reloc
460 || thislines + lines >= config.split_by_reloc
461 || thissize + sec_size >= config.split_by_file))
252b5132 462 {
a854a4a7
AM
463 /* Create a new section and put this link order and the
464 following link orders into it. */
465 bfd_vma shift_offset;
466 asection *n;
252b5132 467
a854a4a7 468 n = clone_section (abfd, cursor, original_sec->name, &count);
252b5132 469
a854a4a7
AM
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;
475 l->next = NULL;
476 l = p;
252b5132 477
a854a4a7
AM
478 /* Change the size of the original section and
479 update the vma of the new one. */
252b5132 480
a854a4a7 481 dump ("before snip", cursor, n);
252b5132 482
a854a4a7
AM
483 shift_offset = p->offset;
484 if (cursor->_cooked_size != 0)
485 {
486 n->_cooked_size = cursor->_cooked_size - shift_offset;
487 cursor->_cooked_size = shift_offset;
488 }
489 n->_raw_size = cursor->_raw_size - shift_offset;
490 cursor->_raw_size = shift_offset;
252b5132 491
a854a4a7
AM
492 vma += shift_offset;
493 n->lma = n->vma = vma;
252b5132 494
a854a4a7
AM
495 /* Run down the chain and change the output section to
496 the right one, update the offsets too. */
497 do
252b5132 498 {
a854a4a7
AM
499 p->offset -= shift_offset;
500 if (p->type == bfd_indirect_link_order)
252b5132 501 {
a854a4a7
AM
502 p->u.indirect.section->output_section = n;
503 p->u.indirect.section->output_offset = p->offset;
252b5132 504 }
a854a4a7 505 p = p->next;
252b5132 506 }
a854a4a7
AM
507 while (p);
508
252b5132
RH
509 dump ("after snip", cursor, n);
510 cursor = n;
511 relocs = thisrelocs;
512 lines = thislines;
a854a4a7 513 sec_size = thissize;
252b5132
RH
514 }
515 else
516 {
a854a4a7 517 l = p;
252b5132
RH
518 relocs += thisrelocs;
519 lines += thislines;
a854a4a7 520 sec_size += thissize;
252b5132 521 }
252b5132
RH
522 }
523 }
524 sanity_check (abfd);
525}
6d5e62f8 526
252b5132 527/**********************************************************************/
6d5e62f8 528
252b5132
RH
529void
530ldwrite ()
531{
532 /* Reset error indicator, which can typically something like invalid
a854a4a7 533 format from opening up the .o files. */
252b5132
RH
534 bfd_set_error (bfd_error_no_error);
535 lang_for_each_statement (build_link_order);
536
a854a4a7
AM
537 if (config.split_by_reloc != (unsigned) -1
538 || config.split_by_file != (bfd_size_type) -1)
252b5132
RH
539 split_sections (output_bfd, &link_info);
540 if (!bfd_final_link (output_bfd, &link_info))
541 {
542 /* If there was an error recorded, print it out. Otherwise assume
543 an appropriate error message like unknown symbol was printed
544 out. */
545
546 if (bfd_get_error () != bfd_error_no_error)
b3ea3584 547 einfo (_("%F%P: final link failed: %E\n"));
252b5132 548 else
6d5e62f8 549 xexit (1);
252b5132
RH
550 }
551}
This page took 0.192711 seconds and 4 git commands to generate.