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