xref: /netbsd-src/external/gpl3/binutils/dist/ld/ldwrite.c (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
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