Rev 5199 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5199 | serge | 1 | /* ldwrite.c -- write out the linked file |
6324 | serge | 2 | Copyright (C) 1991-2015 Free Software Foundation, Inc. |
5199 | serge | 3 | Written by Steve Chamberlain sac@cygnus.com |
4 | |||
5 | This file is part of the GNU Binutils. |
||
6 | |||
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 3 of the License, or |
||
10 | (at your option) any later version. |
||
11 | |||
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. |
||
16 | |||
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., 51 Franklin Street - Fifth Floor, Boston, |
||
20 | MA 02110-1301, USA. */ |
||
21 | |||
22 | #include "sysdep.h" |
||
23 | #include "bfd.h" |
||
24 | #include "bfdlink.h" |
||
25 | #include "libiberty.h" |
||
26 | #include "safe-ctype.h" |
||
27 | |||
28 | #include "ld.h" |
||
29 | #include "ldexp.h" |
||
30 | #include "ldlang.h" |
||
31 | #include "ldwrite.h" |
||
32 | #include "ldmisc.h" |
||
33 | #include |
||
34 | #include "ldmain.h" |
||
35 | |||
36 | /* Build link_order structures for the BFD linker. */ |
||
37 | |||
38 | static void |
||
39 | build_link_order (lang_statement_union_type *statement) |
||
40 | { |
||
41 | switch (statement->header.type) |
||
42 | { |
||
43 | case lang_data_statement_enum: |
||
44 | { |
||
45 | asection *output_section; |
||
46 | struct bfd_link_order *link_order; |
||
47 | bfd_vma value; |
||
48 | bfd_boolean big_endian = FALSE; |
||
49 | |||
50 | output_section = statement->data_statement.output_section; |
||
51 | ASSERT (output_section->owner == link_info.output_bfd); |
||
52 | |||
53 | if (!((output_section->flags & SEC_HAS_CONTENTS) != 0 |
||
54 | || ((output_section->flags & SEC_LOAD) != 0 |
||
55 | && (output_section->flags & SEC_THREAD_LOCAL)))) |
||
56 | break; |
||
57 | |||
58 | link_order = bfd_new_link_order (link_info.output_bfd, output_section); |
||
59 | if (link_order == NULL) |
||
60 | einfo (_("%P%F: bfd_new_link_order failed\n")); |
||
61 | |||
62 | link_order->type = bfd_data_link_order; |
||
63 | link_order->offset = statement->data_statement.output_offset; |
||
64 | link_order->u.data.contents = (bfd_byte *) xmalloc (QUAD_SIZE); |
||
65 | |||
66 | value = statement->data_statement.value; |
||
67 | |||
68 | /* If the endianness of the output BFD is not known, then we |
||
69 | base the endianness of the data on the first input file. |
||
70 | By convention, the bfd_put routines for an unknown |
||
71 | endianness are big endian, so we must swap here if the |
||
72 | input file is little endian. */ |
||
73 | if (bfd_big_endian (link_info.output_bfd)) |
||
74 | big_endian = TRUE; |
||
75 | else if (bfd_little_endian (link_info.output_bfd)) |
||
76 | big_endian = FALSE; |
||
77 | else |
||
78 | { |
||
79 | bfd_boolean swap; |
||
80 | |||
81 | swap = FALSE; |
||
82 | if (command_line.endian == ENDIAN_BIG) |
||
83 | big_endian = TRUE; |
||
84 | else if (command_line.endian == ENDIAN_LITTLE) |
||
85 | { |
||
86 | big_endian = FALSE; |
||
87 | swap = TRUE; |
||
88 | } |
||
89 | else if (command_line.endian == ENDIAN_UNSET) |
||
90 | { |
||
91 | big_endian = TRUE; |
||
92 | { |
||
93 | LANG_FOR_EACH_INPUT_STATEMENT (s) |
||
94 | { |
||
95 | if (s->the_bfd != NULL) |
||
96 | { |
||
97 | if (bfd_little_endian (s->the_bfd)) |
||
98 | { |
||
99 | big_endian = FALSE; |
||
100 | swap = TRUE; |
||
101 | } |
||
102 | break; |
||
103 | } |
||
104 | } |
||
105 | } |
||
106 | } |
||
107 | |||
108 | if (swap) |
||
109 | { |
||
110 | bfd_byte buffer[8]; |
||
111 | |||
112 | switch (statement->data_statement.type) |
||
113 | { |
||
114 | case QUAD: |
||
115 | case SQUAD: |
||
116 | if (sizeof (bfd_vma) >= QUAD_SIZE) |
||
117 | { |
||
118 | bfd_putl64 (value, buffer); |
||
119 | value = bfd_getb64 (buffer); |
||
120 | break; |
||
121 | } |
||
122 | /* Fall through. */ |
||
123 | case LONG: |
||
124 | bfd_putl32 (value, buffer); |
||
125 | value = bfd_getb32 (buffer); |
||
126 | break; |
||
127 | case SHORT: |
||
128 | bfd_putl16 (value, buffer); |
||
129 | value = bfd_getb16 (buffer); |
||
130 | break; |
||
131 | case BYTE: |
||
132 | break; |
||
133 | default: |
||
134 | abort (); |
||
135 | } |
||
136 | } |
||
137 | } |
||
138 | |||
139 | ASSERT (output_section->owner == link_info.output_bfd); |
||
140 | switch (statement->data_statement.type) |
||
141 | { |
||
142 | case QUAD: |
||
143 | case SQUAD: |
||
144 | if (sizeof (bfd_vma) >= QUAD_SIZE) |
||
145 | bfd_put_64 (link_info.output_bfd, value, |
||
146 | link_order->u.data.contents); |
||
147 | else |
||
148 | { |
||
149 | bfd_vma high; |
||
150 | |||
151 | if (statement->data_statement.type == QUAD) |
||
152 | high = 0; |
||
153 | else if ((value & 0x80000000) == 0) |
||
154 | high = 0; |
||
155 | else |
||
156 | high = (bfd_vma) -1; |
||
157 | bfd_put_32 (link_info.output_bfd, high, |
||
158 | (link_order->u.data.contents |
||
159 | + (big_endian ? 0 : 4))); |
||
160 | bfd_put_32 (link_info.output_bfd, value, |
||
161 | (link_order->u.data.contents |
||
162 | + (big_endian ? 4 : 0))); |
||
163 | } |
||
164 | link_order->size = QUAD_SIZE; |
||
165 | break; |
||
166 | case LONG: |
||
167 | bfd_put_32 (link_info.output_bfd, value, |
||
168 | link_order->u.data.contents); |
||
169 | link_order->size = LONG_SIZE; |
||
170 | break; |
||
171 | case SHORT: |
||
172 | bfd_put_16 (link_info.output_bfd, value, |
||
173 | link_order->u.data.contents); |
||
174 | link_order->size = SHORT_SIZE; |
||
175 | break; |
||
176 | case BYTE: |
||
177 | bfd_put_8 (link_info.output_bfd, value, |
||
178 | link_order->u.data.contents); |
||
179 | link_order->size = BYTE_SIZE; |
||
180 | break; |
||
181 | default: |
||
182 | abort (); |
||
183 | } |
||
184 | link_order->u.data.size = link_order->size; |
||
185 | } |
||
186 | break; |
||
187 | |||
188 | case lang_reloc_statement_enum: |
||
189 | { |
||
190 | lang_reloc_statement_type *rs; |
||
191 | asection *output_section; |
||
192 | struct bfd_link_order *link_order; |
||
193 | |||
194 | rs = &statement->reloc_statement; |
||
195 | |||
196 | output_section = rs->output_section; |
||
197 | ASSERT (output_section->owner == link_info.output_bfd); |
||
198 | |||
199 | if (!((output_section->flags & SEC_HAS_CONTENTS) != 0 |
||
200 | || ((output_section->flags & SEC_LOAD) != 0 |
||
201 | && (output_section->flags & SEC_THREAD_LOCAL)))) |
||
202 | break; |
||
203 | |||
204 | link_order = bfd_new_link_order (link_info.output_bfd, output_section); |
||
205 | if (link_order == NULL) |
||
206 | einfo (_("%P%F: bfd_new_link_order failed\n")); |
||
207 | |||
208 | link_order->offset = rs->output_offset; |
||
209 | link_order->size = bfd_get_reloc_size (rs->howto); |
||
210 | |||
211 | link_order->u.reloc.p = (struct bfd_link_order_reloc *) |
||
212 | xmalloc (sizeof (struct bfd_link_order_reloc)); |
||
213 | |||
214 | link_order->u.reloc.p->reloc = rs->reloc; |
||
215 | link_order->u.reloc.p->addend = rs->addend_value; |
||
216 | |||
217 | if (rs->name == NULL) |
||
218 | { |
||
219 | link_order->type = bfd_section_reloc_link_order; |
||
220 | if (rs->section->owner == link_info.output_bfd) |
||
221 | link_order->u.reloc.p->u.section = rs->section; |
||
222 | else |
||
223 | { |
||
224 | link_order->u.reloc.p->u.section = rs->section->output_section; |
||
225 | link_order->u.reloc.p->addend += rs->section->output_offset; |
||
226 | } |
||
227 | } |
||
228 | else |
||
229 | { |
||
230 | link_order->type = bfd_symbol_reloc_link_order; |
||
231 | link_order->u.reloc.p->u.name = rs->name; |
||
232 | } |
||
233 | } |
||
234 | break; |
||
235 | |||
236 | case lang_input_section_enum: |
||
237 | { |
||
238 | /* Create a new link_order in the output section with this |
||
239 | attached */ |
||
240 | asection *i = statement->input_section.section; |
||
241 | |||
242 | if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS |
||
243 | && (i->flags & SEC_EXCLUDE) == 0) |
||
244 | { |
||
245 | asection *output_section = i->output_section; |
||
246 | struct bfd_link_order *link_order; |
||
247 | |||
248 | ASSERT (output_section->owner == link_info.output_bfd); |
||
249 | |||
250 | if (!((output_section->flags & SEC_HAS_CONTENTS) != 0 |
||
251 | || ((output_section->flags & SEC_LOAD) != 0 |
||
252 | && (output_section->flags & SEC_THREAD_LOCAL)))) |
||
253 | break; |
||
254 | |||
255 | link_order = bfd_new_link_order (link_info.output_bfd, |
||
256 | output_section); |
||
257 | |||
258 | if ((i->flags & SEC_NEVER_LOAD) != 0 |
||
259 | && (i->flags & SEC_DEBUGGING) == 0) |
||
260 | { |
||
261 | /* We've got a never load section inside one which is |
||
262 | going to be output, we'll change it into a fill. */ |
||
263 | link_order->type = bfd_data_link_order; |
||
264 | link_order->u.data.contents = (unsigned char *) ""; |
||
265 | link_order->u.data.size = 1; |
||
266 | } |
||
267 | else |
||
268 | { |
||
269 | link_order->type = bfd_indirect_link_order; |
||
270 | link_order->u.indirect.section = i; |
||
271 | ASSERT (i->output_section == output_section); |
||
272 | } |
||
273 | link_order->size = i->size; |
||
274 | link_order->offset = i->output_offset; |
||
275 | } |
||
276 | } |
||
277 | break; |
||
278 | |||
279 | case lang_padding_statement_enum: |
||
280 | /* Make a new link_order with the right filler */ |
||
281 | { |
||
282 | asection *output_section; |
||
283 | struct bfd_link_order *link_order; |
||
284 | |||
285 | output_section = statement->padding_statement.output_section; |
||
286 | ASSERT (statement->padding_statement.output_section->owner |
||
287 | == link_info.output_bfd); |
||
288 | |||
289 | if (!((output_section->flags & SEC_HAS_CONTENTS) != 0 |
||
290 | || ((output_section->flags & SEC_LOAD) != 0 |
||
291 | && (output_section->flags & SEC_THREAD_LOCAL)))) |
||
292 | break; |
||
293 | |||
294 | link_order = bfd_new_link_order (link_info.output_bfd, |
||
295 | output_section); |
||
296 | link_order->type = bfd_data_link_order; |
||
297 | link_order->size = statement->padding_statement.size; |
||
298 | link_order->offset = statement->padding_statement.output_offset; |
||
299 | link_order->u.data.contents = statement->padding_statement.fill->data; |
||
300 | link_order->u.data.size = statement->padding_statement.fill->size; |
||
301 | } |
||
302 | break; |
||
303 | |||
304 | default: |
||
305 | /* All the other ones fall through */ |
||
306 | break; |
||
307 | } |
||
308 | } |
||
309 | |||
310 | /* Return true if NAME is the name of an unsplittable section. These |
||
311 | are the stabs strings, dwarf strings. */ |
||
312 | |||
313 | static bfd_boolean |
||
314 | unsplittable_name (const char *name) |
||
315 | { |
||
316 | if (CONST_STRNEQ (name, ".stab")) |
||
317 | { |
||
318 | /* There are several stab like string sections. We pattern match on |
||
319 | ".stab...str" */ |
||
320 | unsigned len = strlen (name); |
||
321 | if (strcmp (&name[len-3], "str") == 0) |
||
322 | return TRUE; |
||
323 | } |
||
324 | else if (strcmp (name, "$GDB_STRINGS$") == 0) |
||
325 | return TRUE; |
||
326 | return FALSE; |
||
327 | } |
||
328 | |||
329 | /* Wander around the input sections, make sure that |
||
330 | we'll never try and create an output section with more relocs |
||
331 | than will fit.. Do this by always assuming the worst case, and |
||
332 | creating new output sections with all the right bits. */ |
||
333 | #define TESTIT 1 |
||
334 | static asection * |
||
335 | clone_section (bfd *abfd, asection *s, const char *name, int *count) |
||
336 | { |
||
337 | char *tname; |
||
338 | char *sname; |
||
339 | unsigned int len; |
||
340 | asection *n; |
||
341 | struct bfd_link_hash_entry *h; |
||
342 | |||
343 | /* Invent a section name from the section name and a dotted numeric |
||
344 | suffix. */ |
||
345 | len = strlen (name); |
||
346 | tname = (char *) xmalloc (len + 1); |
||
347 | memcpy (tname, name, len + 1); |
||
348 | /* Remove a dotted number suffix, from a previous split link. */ |
||
349 | while (len && ISDIGIT (tname[len-1])) |
||
350 | len--; |
||
351 | if (len > 1 && tname[len-1] == '.') |
||
352 | /* It was a dotted number. */ |
||
353 | tname[len-1] = 0; |
||
354 | |||
355 | /* We want to use the whole of the original section name for the |
||
356 | split name, but coff can be restricted to 8 character names. */ |
||
357 | if (bfd_family_coff (abfd) && strlen (tname) > 5) |
||
358 | { |
||
359 | /* Some section names cannot be truncated, as the name is |
||
360 | used to locate some other section. */ |
||
361 | if (CONST_STRNEQ (name, ".stab") |
||
362 | || strcmp (name, "$GDB_SYMBOLS$") == 0) |
||
363 | { |
||
364 | einfo (_ ("%F%P: cannot create split section name for %s\n"), name); |
||
365 | /* Silence gcc warnings. einfo exits, so we never reach here. */ |
||
366 | return NULL; |
||
367 | } |
||
368 | tname[5] = 0; |
||
369 | } |
||
370 | |||
371 | if ((sname = bfd_get_unique_section_name (abfd, tname, count)) == NULL |
||
372 | || (n = bfd_make_section_anyway (abfd, sname)) == NULL |
||
373 | || (h = bfd_link_hash_lookup (link_info.hash, |
||
374 | sname, TRUE, TRUE, FALSE)) == NULL) |
||
375 | { |
||
376 | einfo (_("%F%P: clone section failed: %E\n")); |
||
377 | /* Silence gcc warnings. einfo exits, so we never reach here. */ |
||
378 | return NULL; |
||
379 | } |
||
380 | free (tname); |
||
381 | |||
382 | /* Set up section symbol. */ |
||
383 | h->type = bfd_link_hash_defined; |
||
384 | h->u.def.value = 0; |
||
385 | h->u.def.section = n; |
||
386 | |||
387 | n->flags = s->flags; |
||
388 | n->vma = s->vma; |
||
389 | n->user_set_vma = s->user_set_vma; |
||
390 | n->lma = s->lma; |
||
391 | n->size = 0; |
||
392 | n->output_offset = s->output_offset; |
||
393 | n->output_section = n; |
||
394 | n->orelocation = 0; |
||
395 | n->reloc_count = 0; |
||
396 | n->alignment_power = s->alignment_power; |
||
397 | |||
398 | bfd_copy_private_section_data (abfd, s, abfd, n); |
||
399 | |||
400 | return n; |
||
401 | } |
||
402 | |||
403 | #if TESTING |
||
404 | static void |
||
405 | ds (asection *s) |
||
406 | { |
||
407 | struct bfd_link_order *l = s->map_head.link_order; |
||
408 | printf ("vma %x size %x\n", s->vma, s->size); |
||
409 | while (l) |
||
410 | { |
||
411 | if (l->type == bfd_indirect_link_order) |
||
412 | { |
||
413 | printf ("%8x %s\n", l->offset, l->u.indirect.section->owner->filename); |
||
414 | } |
||
415 | else |
||
416 | { |
||
417 | printf (_("%8x something else\n"), l->offset); |
||
418 | } |
||
419 | l = l->next; |
||
420 | } |
||
421 | printf ("\n"); |
||
422 | } |
||
423 | |||
424 | dump (char *s, asection *a1, asection *a2) |
||
425 | { |
||
426 | printf ("%s\n", s); |
||
427 | ds (a1); |
||
428 | ds (a2); |
||
429 | } |
||
430 | |||
431 | static void |
||
432 | sanity_check (bfd *abfd) |
||
433 | { |
||
434 | asection *s; |
||
435 | for (s = abfd->sections; s; s = s->next) |
||
436 | { |
||
437 | struct bfd_link_order *p; |
||
438 | bfd_vma prev = 0; |
||
439 | for (p = s->map_head.link_order; p; p = p->next) |
||
440 | { |
||
441 | if (p->offset > 100000) |
||
442 | abort (); |
||
443 | if (p->offset < prev) |
||
444 | abort (); |
||
445 | prev = p->offset; |
||
446 | } |
||
447 | } |
||
448 | } |
||
449 | #else |
||
450 | #define sanity_check(a) |
||
451 | #define dump(a, b, c) |
||
452 | #endif |
||
453 | |||
454 | static void |
||
455 | split_sections (bfd *abfd, struct bfd_link_info *info) |
||
456 | { |
||
457 | asection *original_sec; |
||
458 | int nsecs = abfd->section_count; |
||
459 | sanity_check (abfd); |
||
460 | /* Look through all the original sections. */ |
||
461 | for (original_sec = abfd->sections; |
||
462 | original_sec && nsecs; |
||
463 | original_sec = original_sec->next, nsecs--) |
||
464 | { |
||
465 | int count = 0; |
||
466 | unsigned int lines = 0; |
||
467 | unsigned int relocs = 0; |
||
468 | bfd_size_type sec_size = 0; |
||
469 | struct bfd_link_order *l; |
||
470 | struct bfd_link_order *p; |
||
471 | bfd_vma vma = original_sec->vma; |
||
472 | asection *cursor = original_sec; |
||
473 | |||
474 | /* Count up the relocations and line entries to see if anything |
||
475 | would be too big to fit. Accumulate section size too. */ |
||
476 | for (l = NULL, p = cursor->map_head.link_order; p != NULL; p = l->next) |
||
477 | { |
||
478 | unsigned int thislines = 0; |
||
479 | unsigned int thisrelocs = 0; |
||
480 | bfd_size_type thissize = 0; |
||
481 | if (p->type == bfd_indirect_link_order) |
||
482 | { |
||
483 | asection *sec; |
||
484 | |||
485 | sec = p->u.indirect.section; |
||
486 | |||
487 | if (info->strip == strip_none |
||
488 | || info->strip == strip_some) |
||
489 | thislines = sec->lineno_count; |
||
490 | |||
6324 | serge | 491 | if (bfd_link_relocatable (info)) |
5199 | serge | 492 | thisrelocs = sec->reloc_count; |
493 | |||
494 | thissize = sec->size; |
||
495 | |||
496 | } |
||
6324 | serge | 497 | else if (bfd_link_relocatable (info) |
5199 | serge | 498 | && (p->type == bfd_section_reloc_link_order |
499 | || p->type == bfd_symbol_reloc_link_order)) |
||
500 | thisrelocs++; |
||
501 | |||
502 | if (l != NULL |
||
503 | && (thisrelocs + relocs >= config.split_by_reloc |
||
504 | || thislines + lines >= config.split_by_reloc |
||
505 | || (thissize + sec_size >= config.split_by_file)) |
||
506 | && !unsplittable_name (cursor->name)) |
||
507 | { |
||
508 | /* Create a new section and put this link order and the |
||
509 | following link orders into it. */ |
||
510 | bfd_vma shift_offset; |
||
511 | asection *n; |
||
512 | |||
513 | n = clone_section (abfd, cursor, original_sec->name, &count); |
||
514 | |||
515 | /* Attach the link orders to the new section and snip |
||
516 | them off from the old section. */ |
||
517 | n->map_head.link_order = p; |
||
518 | n->map_tail.link_order = cursor->map_tail.link_order; |
||
519 | cursor->map_tail.link_order = l; |
||
520 | l->next = NULL; |
||
521 | l = p; |
||
522 | |||
523 | /* Change the size of the original section and |
||
524 | update the vma of the new one. */ |
||
525 | |||
526 | dump ("before snip", cursor, n); |
||
527 | |||
528 | shift_offset = p->offset; |
||
529 | n->size = cursor->size - shift_offset; |
||
530 | cursor->size = shift_offset; |
||
531 | |||
532 | vma += shift_offset; |
||
533 | n->lma = n->vma = vma; |
||
534 | |||
535 | /* Run down the chain and change the output section to |
||
536 | the right one, update the offsets too. */ |
||
537 | do |
||
538 | { |
||
539 | p->offset -= shift_offset; |
||
540 | if (p->type == bfd_indirect_link_order) |
||
541 | { |
||
542 | p->u.indirect.section->output_section = n; |
||
543 | p->u.indirect.section->output_offset = p->offset; |
||
544 | } |
||
545 | p = p->next; |
||
546 | } |
||
547 | while (p); |
||
548 | |||
549 | dump ("after snip", cursor, n); |
||
550 | cursor = n; |
||
551 | relocs = thisrelocs; |
||
552 | lines = thislines; |
||
553 | sec_size = thissize; |
||
554 | } |
||
555 | else |
||
556 | { |
||
557 | l = p; |
||
558 | relocs += thisrelocs; |
||
559 | lines += thislines; |
||
560 | sec_size += thissize; |
||
561 | } |
||
562 | } |
||
563 | } |
||
564 | sanity_check (abfd); |
||
565 | } |
||
566 | |||
567 | /* Call BFD to write out the linked file. */ |
||
568 | |||
569 | void |
||
570 | ldwrite (void) |
||
571 | { |
||
572 | /* Reset error indicator, which can typically something like invalid |
||
573 | format from opening up the .o files. */ |
||
574 | bfd_set_error (bfd_error_no_error); |
||
6324 | serge | 575 | lang_clear_os_map (); |
5199 | serge | 576 | lang_for_each_statement (build_link_order); |
577 | |||
578 | if (config.split_by_reloc != (unsigned) -1 |
||
579 | || config.split_by_file != (bfd_size_type) -1) |
||
580 | split_sections (link_info.output_bfd, &link_info); |
||
581 | if (!bfd_final_link (link_info.output_bfd, &link_info)) |
||
582 | { |
||
583 | /* If there was an error recorded, print it out. Otherwise assume |
||
584 | an appropriate error message like unknown symbol was printed |
||
585 | out. */ |
||
586 | |||
587 | if (bfd_get_error () != bfd_error_no_error) |
||
588 | einfo (_("%F%P: final link failed: %E\n")); |
||
589 | else |
||
590 | xexit (1); |
||
591 | } |
||
592 | }> |