New test cases for java support.
[deliverable/binutils-gdb.git] / ld / ldwrite.c
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
5
6 This file is part of GLD, the Gnu Linker.
7
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.
12
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.
17
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. */
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"
32 #include "ldgram.h"
33 #include "ldmain.h"
34
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 *));
38
39 /* Build link_order structures for the BFD linker. */
40
41 static void
42 build_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;
52 boolean big_endian = false;
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))
73 big_endian = true;
74 else if (bfd_little_endian (output_bfd))
75 big_endian = false;
76 else
77 {
78 boolean swap;
79
80 swap = false;
81 if (command_line.endian == ENDIAN_BIG)
82 big_endian = true;
83 else if (command_line.endian == ENDIAN_LITTLE)
84 {
85 big_endian = false;
86 swap = true;
87 }
88 else if (command_line.endian == ENDIAN_UNSET)
89 {
90 big_endian = true;
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 {
98 big_endian = false;
99 swap = true;
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 */
229 if (statement->input_section.ifile->just_syms_flag == false)
230 {
231 asection *i = statement->input_section.section;
232 asection *output_section = i->output_section;
233
234 ASSERT (output_section->owner == output_bfd);
235
236 if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
237 {
238 struct bfd_link_order *link_order;
239
240 link_order = bfd_new_link_order (output_bfd, output_section);
241
242 if (i->flags & SEC_NEVER_LOAD)
243 {
244 /* We've got a never load section inside one which
245 is going to be output, we'll change it into a
246 fill. */
247 link_order->type = bfd_data_link_order;
248 link_order->u.data.contents = "";
249 link_order->u.data.size = 1;
250 }
251 else
252 {
253 link_order->type = bfd_indirect_link_order;
254 link_order->u.indirect.section = i;
255 ASSERT (i->output_section == output_section);
256 }
257 if (i->_cooked_size)
258 link_order->size = i->_cooked_size;
259 else
260 link_order->size = bfd_get_section_size_before_reloc (i);
261 link_order->offset = i->output_offset;
262 }
263 }
264 break;
265
266 case lang_padding_statement_enum:
267 /* Make a new link_order with the right filler */
268 {
269 asection *output_section;
270 struct bfd_link_order *link_order;
271
272 output_section = statement->padding_statement.output_section;
273 ASSERT (statement->padding_statement.output_section->owner
274 == output_bfd);
275 if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
276 {
277 link_order = bfd_new_link_order (output_bfd, output_section);
278 link_order->type = bfd_data_link_order;
279 link_order->size = statement->padding_statement.size;
280 link_order->offset = statement->padding_statement.output_offset;
281 link_order->u.data.contents = statement->padding_statement.fill->data;
282 link_order->u.data.size = statement->padding_statement.fill->size;
283 }
284 }
285 break;
286
287 default:
288 /* All the other ones fall through */
289 break;
290 }
291 }
292
293 /* Call BFD to write out the linked file. */
294
295 /**********************************************************************/
296
297 /* Wander around the input sections, make sure that
298 we'll never try and create an output section with more relocs
299 than will fit.. Do this by always assuming the worst case, and
300 creating new output sections with all the right bits. */
301 #define TESTIT 1
302 static asection *
303 clone_section (abfd, s, name, count)
304 bfd *abfd;
305 asection *s;
306 const char *name;
307 int *count;
308 {
309 char templ[6];
310 char *sname;
311 asection *n;
312 struct bfd_link_hash_entry *h;
313
314 /* Invent a section name from the first five chars of the base
315 section name and a digit suffix. */
316 strncpy (templ, name, sizeof (templ) - 1);
317 templ[sizeof (templ) - 1] = '\0';
318 if ((sname = bfd_get_unique_section_name (abfd, templ, count)) == NULL
319 || (n = bfd_make_section_anyway (abfd, sname)) == NULL
320 || (h = bfd_link_hash_lookup (link_info.hash,
321 sname, true, true, false)) == NULL)
322 {
323 einfo (_("%F%P: clone section failed: %E\n"));
324 /* Silence gcc warnings. einfo exits, so we never reach here. */
325 return NULL;
326 }
327
328 /* Set up section symbol. */
329 h->type = bfd_link_hash_defined;
330 h->u.def.value = 0;
331 h->u.def.section = n;
332
333 n->flags = s->flags;
334 n->vma = s->vma;
335 n->user_set_vma = s->user_set_vma;
336 n->lma = s->lma;
337 n->_cooked_size = 0;
338 n->_raw_size = 0;
339 n->output_offset = s->output_offset;
340 n->output_section = n;
341 n->orelocation = 0;
342 n->reloc_count = 0;
343 n->alignment_power = s->alignment_power;
344 return n;
345 }
346
347 #if TESTING
348 static void
349 ds (s)
350 asection *s;
351 {
352 struct bfd_link_order *l = s->link_order_head;
353 printf ("vma %x size %x\n", s->vma, s->_raw_size);
354 while (l)
355 {
356 if (l->type == bfd_indirect_link_order)
357 {
358 printf ("%8x %s\n", l->offset, l->u.indirect.section->owner->filename);
359 }
360 else
361 {
362 printf (_("%8x something else\n"), l->offset);
363 }
364 l = l->next;
365 }
366 printf ("\n");
367 }
368
369 dump (s, a1, a2)
370 char *s;
371 asection *a1;
372 asection *a2;
373 {
374 printf ("%s\n", s);
375 ds (a1);
376 ds (a2);
377 }
378
379 static void
380 sanity_check (abfd)
381 bfd *abfd;
382 {
383 asection *s;
384 for (s = abfd->sections; s; s = s->next)
385 {
386 struct bfd_link_order *p;
387 bfd_vma prev = 0;
388 for (p = s->link_order_head; p; p = p->next)
389 {
390 if (p->offset > 100000)
391 abort ();
392 if (p->offset < prev)
393 abort ();
394 prev = p->offset;
395 }
396 }
397 }
398 #else
399 #define sanity_check(a)
400 #define dump(a, b, c)
401 #endif
402
403 static void
404 split_sections (abfd, info)
405 bfd *abfd;
406 struct bfd_link_info *info;
407 {
408 asection *original_sec;
409 int nsecs = abfd->section_count;
410 sanity_check (abfd);
411 /* Look through all the original sections. */
412 for (original_sec = abfd->sections;
413 original_sec && nsecs;
414 original_sec = original_sec->next, nsecs--)
415 {
416 int count = 0;
417 unsigned int lines = 0;
418 unsigned int relocs = 0;
419 bfd_size_type sec_size = 0;
420 struct bfd_link_order *l;
421 struct bfd_link_order *p;
422 bfd_vma vma = original_sec->vma;
423 asection *cursor = original_sec;
424
425 /* Count up the relocations and line entries to see if anything
426 would be too big to fit. Accumulate section size too. */
427 for (l = NULL, p = cursor->link_order_head; p != NULL; p = l->next)
428 {
429 unsigned int thislines = 0;
430 unsigned int thisrelocs = 0;
431 bfd_size_type thissize = 0;
432 if (p->type == bfd_indirect_link_order)
433 {
434 asection *sec;
435
436 sec = p->u.indirect.section;
437
438 if (info->strip == strip_none
439 || info->strip == strip_some)
440 thislines = sec->lineno_count;
441
442 if (info->relocateable)
443 thisrelocs = sec->reloc_count;
444
445 if (sec->_cooked_size != 0)
446 thissize = sec->_cooked_size;
447 else
448 thissize = sec->_raw_size;
449
450 }
451 else if (info->relocateable
452 && (p->type == bfd_section_reloc_link_order
453 || p->type == bfd_symbol_reloc_link_order))
454 thisrelocs++;
455
456 if (l != NULL
457 && (thisrelocs + relocs >= config.split_by_reloc
458 || thislines + lines >= config.split_by_reloc
459 || thissize + sec_size >= config.split_by_file))
460 {
461 /* Create a new section and put this link order and the
462 following link orders into it. */
463 bfd_vma shift_offset;
464 asection *n;
465
466 n = clone_section (abfd, cursor, original_sec->name, &count);
467
468 /* Attach the link orders to the new section and snip
469 them off from the old section. */
470 n->link_order_head = p;
471 n->link_order_tail = cursor->link_order_tail;
472 cursor->link_order_tail = l;
473 l->next = NULL;
474 l = p;
475
476 /* Change the size of the original section and
477 update the vma of the new one. */
478
479 dump ("before snip", cursor, n);
480
481 shift_offset = p->offset;
482 if (cursor->_cooked_size != 0)
483 {
484 n->_cooked_size = cursor->_cooked_size - shift_offset;
485 cursor->_cooked_size = shift_offset;
486 }
487 n->_raw_size = cursor->_raw_size - shift_offset;
488 cursor->_raw_size = shift_offset;
489
490 vma += shift_offset;
491 n->lma = n->vma = vma;
492
493 /* Run down the chain and change the output section to
494 the right one, update the offsets too. */
495 do
496 {
497 p->offset -= shift_offset;
498 if (p->type == bfd_indirect_link_order)
499 {
500 p->u.indirect.section->output_section = n;
501 p->u.indirect.section->output_offset = p->offset;
502 }
503 p = p->next;
504 }
505 while (p);
506
507 dump ("after snip", cursor, n);
508 cursor = n;
509 relocs = thisrelocs;
510 lines = thislines;
511 sec_size = thissize;
512 }
513 else
514 {
515 l = p;
516 relocs += thisrelocs;
517 lines += thislines;
518 sec_size += thissize;
519 }
520 }
521 }
522 sanity_check (abfd);
523 }
524
525 /**********************************************************************/
526
527 void
528 ldwrite ()
529 {
530 /* Reset error indicator, which can typically something like invalid
531 format from opening up the .o files. */
532 bfd_set_error (bfd_error_no_error);
533 lang_for_each_statement (build_link_order);
534
535 if (config.split_by_reloc != (unsigned) -1
536 || config.split_by_file != (bfd_size_type) -1)
537 split_sections (output_bfd, &link_info);
538 if (!bfd_final_link (output_bfd, &link_info))
539 {
540 /* If there was an error recorded, print it out. Otherwise assume
541 an appropriate error message like unknown symbol was printed
542 out. */
543
544 if (bfd_get_error () != bfd_error_no_error)
545 einfo (_("%F%P: final link failed: %E\n"));
546 else
547 xexit (1);
548 }
549 }
This page took 0.046053 seconds and 4 git commands to generate.