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