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