1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23: #include "sysdep.h"
24: #include "bfd.h"
25: #include "bfdlink.h"
26: #include "libiberty.h"
27: #include "safe-ctype.h"
28:
29: #include "ld.h"
30: #include "ldexp.h"
31: #include "ldlang.h"
32: #include "ldwrite.h"
33: #include "ldmisc.h"
34: #include <ldgram.h>
35: #include "ldmain.h"
36:
37:
38:
39: static void
40: build_link_order (lang_statement_union_type *statement)
41: {
42: switch (statement->header.type)
43: {
44: case lang_data_statement_enum:
45: {
46: asection *output_section;
47: struct bfd_link_order *link_order;
48: bfd_vma value;
49: bfd_boolean big_endian = FALSE;
50:
51: output_section = statement->data_statement.output_section;
52: ASSERT (output_section->owner == output_bfd);
53:
54: link_order = bfd_new_link_order (output_bfd, output_section);
55: if (link_order == NULL)
56: einfo (_("%P%F: bfd_new_link_order failed\n"));
57:
58: link_order->type = bfd_data_link_order;
59: link_order->offset = statement->data_statement.output_offset;
60: link_order->u.data.contents = xmalloc (QUAD_SIZE);
61:
62: value = statement->data_statement.value;
63:
64:
65:
66:
67:
68:
69: if (bfd_big_endian (output_bfd))
70: big_endian = TRUE;
71: else if (bfd_little_endian (output_bfd))
72: big_endian = FALSE;
73: else
74: {
75: bfd_boolean swap;
76:
77: swap = FALSE;
78: if (command_line.endian == ENDIAN_BIG)
79: big_endian = TRUE;
80: else if (command_line.endian == ENDIAN_LITTLE)
81: {
82: big_endian = FALSE;
83: swap = TRUE;
84: }
85: else if (command_line.endian == ENDIAN_UNSET)
86: {
87: big_endian = TRUE;
88: {
89: LANG_FOR_EACH_INPUT_STATEMENT (s)
90: {
91: if (s->the_bfd != NULL)
92: {
93: if (bfd_little_endian (s->the_bfd))
94: {
95: big_endian = FALSE;
96: swap = TRUE;
97: }
98: break;
99: }
100: }
101: }
102: }
103:
104: if (swap)
105: {
106: bfd_byte buffer[8];
107:
108: switch (statement->data_statement.type)
109: {
110: case QUAD:
111: case SQUAD:
112: if (sizeof (bfd_vma) >= QUAD_SIZE)
113: {
114: bfd_putl64 (value, buffer);
115: value = bfd_getb64 (buffer);
116: break;
117: }
118:
119: case LONG:
120: bfd_putl32 (value, buffer);
121: value = bfd_getb32 (buffer);
122: break;
123: case SHORT:
124: bfd_putl16 (value, buffer);
125: value = bfd_getb16 (buffer);
126: break;
127: case BYTE:
128: break;
129: default:
130: abort ();
131: }
132: }
133: }
134:
135: ASSERT (output_section->owner == output_bfd);
136: switch (statement->data_statement.type)
137: {
138: case QUAD:
139: case SQUAD:
140: if (sizeof (bfd_vma) >= QUAD_SIZE)
141: bfd_put_64 (output_bfd, value, link_order->u.data.contents);
142: else
143: {
144: bfd_vma high;
145:
146: if (statement->data_statement.type == QUAD)
147: high = 0;
148: else if ((value & 0x80000000) == 0)
149: high = 0;
150: else
151: high = (bfd_vma) -1;
152: bfd_put_32 (output_bfd, high,
153: (link_order->u.data.contents
154: + (big_endian ? 0 : 4)));
155: bfd_put_32 (output_bfd, value,
156: (link_order->u.data.contents
157: + (big_endian ? 4 : 0)));
158: }
159: link_order->size = QUAD_SIZE;
160: break;
161: case LONG:
162: bfd_put_32 (output_bfd, value, link_order->u.data.contents);
163: link_order->size = LONG_SIZE;
164: break;
165: case SHORT:
166: bfd_put_16 (output_bfd, value, link_order->u.data.contents);
167: link_order->size = SHORT_SIZE;
168: break;
169: case BYTE:
170: bfd_put_8 (output_bfd, value, link_order->u.data.contents);
171: link_order->size = BYTE_SIZE;
172: break;
173: default:
174: abort ();
175: }
176: }
177: break;
178:
179: case lang_reloc_statement_enum:
180: {
181: lang_reloc_statement_type *rs;
182: asection *output_section;
183: struct bfd_link_order *link_order;
184:
185: rs = &statement->reloc_statement;
186:
187: output_section = rs->output_section;
188: ASSERT (output_section->owner == output_bfd);
189:
190: link_order = bfd_new_link_order (output_bfd, output_section);
191: if (link_order == NULL)
192: einfo (_("%P%F: bfd_new_link_order failed\n"));
193:
194: link_order->offset = rs->output_offset;
195: link_order->size = bfd_get_reloc_size (rs->howto);
196:
197: link_order->u.reloc.p = xmalloc (sizeof (struct bfd_link_order_reloc));
198:
199: link_order->u.reloc.p->reloc = rs->reloc;
200: link_order->u.reloc.p->addend = rs->addend_value;
201:
202: if (rs->name == NULL)
203: {
204: link_order->type = bfd_section_reloc_link_order;
205: if (rs->section->owner == output_bfd)
206: link_order->u.reloc.p->u.section = rs->section;
207: else
208: {
209: link_order->u.reloc.p->u.section = rs->section->output_section;
210: link_order->u.reloc.p->addend += rs->section->output_offset;
211: }
212: }
213: else
214: {
215: link_order->type = bfd_symbol_reloc_link_order;
216: link_order->u.reloc.p->u.name = rs->name;
217: }
218: }
219: break;
220:
221: case lang_input_section_enum:
222: {
223:
224:
225: asection *i = statement->input_section.section;
226:
227: if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag
228: && (i->flags & SEC_EXCLUDE) == 0)
229: {
230: asection *output_section = i->output_section;
231:
232: ASSERT (output_section->owner == output_bfd);
233:
234: if ((output_section->flags & SEC_HAS_CONTENTS) != 0
235: || ((output_section->flags & SEC_LOAD) != 0
236: && (output_section->flags & SEC_THREAD_LOCAL)))
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:
245:
246:
247: link_order->type = bfd_data_link_order;
248: link_order->u.data.contents = (unsigned char *) "";
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: link_order->size = i->size;
258: link_order->offset = i->output_offset;
259: }
260: }
261: }
262: break;
263:
264: case lang_padding_statement_enum:
265:
266: {
267: asection *output_section;
268: struct bfd_link_order *link_order;
269:
270: output_section = statement->padding_statement.output_section;
271: ASSERT (statement->padding_statement.output_section->owner
272: == output_bfd);
273: if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
274: {
275: link_order = bfd_new_link_order (output_bfd, output_section);
276: link_order->type = bfd_data_link_order;
277: link_order->size = statement->padding_statement.size;
278: link_order->offset = statement->padding_statement.output_offset;
279: link_order->u.data.contents = statement->padding_statement.fill->data;
280: link_order->u.data.size = statement->padding_statement.fill->size;
281: }
282: }
283: break;
284:
285: default:
286:
287: break;
288: }
289: }
290:
291:
292:
293:
294: static bfd_boolean
295: unsplittable_name (const char *name)
296: {
297: if (CONST_STRNEQ (name, ".stab"))
298: {
299:
300:
301: unsigned len = strlen (name);
302: if (strcmp (&name[len-3], "str") == 0)
303: return TRUE;
304: }
305: else if (strcmp (name, "$GDB_STRINGS$") == 0)
306: return TRUE;
307: return FALSE;
308: }
309:
310:
311:
312:
313:
314: #define TESTIT 1
315: static asection *
316: clone_section (bfd *abfd, asection *s, const char *name, int *count)
317: {
318: char *tname;
319: char *sname;
320: unsigned int len;
321: asection *n;
322: struct bfd_link_hash_entry *h;
323:
324:
325:
326: len = strlen (name);
327: tname = xmalloc (len + 1);
328: memcpy (tname, name, len + 1);
329:
330: while (len && ISDIGIT (tname[len-1]))
331: len--;
332: if (len > 1 && tname[len-1] == '.')
333:
334: tname[len-1] = 0;
335:
336:
337:
338: if (bfd_family_coff (abfd) && strlen (tname) > 5)
339: {
340:
341:
342: if (CONST_STRNEQ (name, ".stab")
343: || strcmp (name, "$GDB_SYMBOLS$") == 0)
344: {
345: einfo (_ ("%F%P: cannot create split section name for %s\n"), name);
346:
347: return NULL;
348: }
349: tname[5] = 0;
350: }
351:
352: if ((sname = bfd_get_unique_section_name (abfd, tname, count)) == NULL
353: || (n = bfd_make_section_anyway (abfd, sname)) == NULL
354: || (h = bfd_link_hash_lookup (link_info.hash,
355: sname, TRUE, TRUE, FALSE)) == NULL)
356: {
357: einfo (_("%F%P: clone section failed: %E\n"));
358:
359: return NULL;
360: }
361: free (tname);
362:
363:
364: h->type = bfd_link_hash_defined;
365: h->u.def.value = 0;
366: h->u.def.section = n;
367:
368: n->flags = s->flags;
369: n->vma = s->vma;
370: n->user_set_vma = s->user_set_vma;
371: n->lma = s->lma;
372: n->size = 0;
373: n->output_offset = s->output_offset;
374: n->output_section = n;
375: n->orelocation = 0;
376: n->reloc_count = 0;
377: n->alignment_power = s->alignment_power;
378: return n;
379: }
380:
381: #if TESTING
382: static void
383: ds (asection *s)
384: {
385: struct bfd_link_order *l = s->map_head.link_order;
386: printf ("vma %x size %x\n", s->vma, s->size);
387: while (l)
388: {
389: if (l->type == bfd_indirect_link_order)
390: {
391: printf ("%8x %s\n", l->offset, l->u.indirect.section->owner->filename);
392: }
393: else
394: {
395: printf (_("%8x something else\n"), l->offset);
396: }
397: l = l->next;
398: }
399: printf ("\n");
400: }
401:
402: dump (char *s, asection *a1, asection *a2)
403: {
404: printf ("%s\n", s);
405: ds (a1);
406: ds (a2);
407: }
408:
409: static void
410: sanity_check (bfd *abfd)
411: {
412: asection *s;
413: for (s = abfd->sections; s; s = s->next)
414: {
415: struct bfd_link_order *p;
416: bfd_vma prev = 0;
417: for (p = s->map_head.link_order; p; p = p->next)
418: {
419: if (p->offset > 100000)
420: abort ();
421: if (p->offset < prev)
422: abort ();
423: prev = p->offset;
424: }
425: }
426: }
427: #else
428: #define sanity_check(a)
429: #define dump(a, b, c)
430: #endif
431:
432: static void
433: split_sections (bfd *abfd, struct bfd_link_info *info)
434: {
435: asection *original_sec;
436: int nsecs = abfd->section_count;
437: sanity_check (abfd);
438:
439: for (original_sec = abfd->sections;
440: original_sec && nsecs;
441: original_sec = original_sec->next, nsecs--)
442: {
443: int count = 0;
444: unsigned int lines = 0;
445: unsigned int relocs = 0;
446: bfd_size_type sec_size = 0;
447: struct bfd_link_order *l;
448: struct bfd_link_order *p;
449: bfd_vma vma = original_sec->vma;
450: asection *cursor = original_sec;
451:
452:
453:
454: for (l = NULL, p = cursor->map_head.link_order; p != NULL; p = l->next)
455: {
456: unsigned int thislines = 0;
457: unsigned int thisrelocs = 0;
458: bfd_size_type thissize = 0;
459: if (p->type == bfd_indirect_link_order)
460: {
461: asection *sec;
462:
463: sec = p->u.indirect.section;
464:
465: if (info->strip == strip_none
466: || info->strip == strip_some)
467: thislines = sec->lineno_count;
468:
469: if (info->relocatable)
470: thisrelocs = sec->reloc_count;
471:
472: thissize = sec->size;
473:
474: }
475: else if (info->relocatable
476: && (p->type == bfd_section_reloc_link_order
477: || p->type == bfd_symbol_reloc_link_order))
478: thisrelocs++;
479:
480: if (l != NULL
481: && (thisrelocs + relocs >= config.split_by_reloc
482: || thislines + lines >= config.split_by_reloc
483: || (thissize + sec_size >= config.split_by_file))
484: && !unsplittable_name (cursor->name))
485: {
486:
487:
488: bfd_vma shift_offset;
489: asection *n;
490:
491: n = clone_section (abfd, cursor, original_sec->name, &count);
492:
493:
494:
495: n->map_head.link_order = p;
496: n->map_tail.link_order = cursor->map_tail.link_order;
497: cursor->map_tail.link_order = l;
498: l->next = NULL;
499: l = p;
500:
501:
502:
503:
504: dump ("before snip", cursor, n);
505:
506: shift_offset = p->offset;
507: n->size = cursor->size - shift_offset;
508: cursor->size = shift_offset;
509:
510: vma += shift_offset;
511: n->lma = n->vma = vma;
512:
513:
514:
515: do
516: {
517: p->offset -= shift_offset;
518: if (p->type == bfd_indirect_link_order)
519: {
520: p->u.indirect.section->output_section = n;
521: p->u.indirect.section->output_offset = p->offset;
522: }
523: p = p->next;
524: }
525: while (p);
526:
527: dump ("after snip", cursor, n);
528: cursor = n;
529: relocs = thisrelocs;
530: lines = thislines;
531: sec_size = thissize;
532: }
533: else
534: {
535: l = p;
536: relocs += thisrelocs;
537: lines += thislines;
538: sec_size += thissize;
539: }
540: }
541: }
542: sanity_check (abfd);
543: }
544:
545:
546:
547: void
548: ldwrite (void)
549: {
550:
551:
552: bfd_set_error (bfd_error_no_error);
553: lang_for_each_statement (build_link_order);
554:
555: if (config.split_by_reloc != (unsigned) -1
556: || config.split_by_file != (bfd_size_type) -1)
557: split_sections (output_bfd, &link_info);
558: if (!bfd_final_link (output_bfd, &link_info))
559: {
560:
561:
562:
563:
564: if (bfd_get_error () != bfd_error_no_error)
565: einfo (_("%F%P: final link failed: %E\n"));
566: else
567: xexit (1);
568: }
569: }