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