xref: /openbsd-src/gnu/usr.bin/binutils/ld/ldwrite.c (revision 007c2a4539b8b8aaa95c5e73e77620090abe113b)
12159047fSniklas /* ldwrite.c -- write out the linked file
2*007c2a45Smiod    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002, 2003
3b305b0f1Sespie    Free Software Foundation, Inc.
42159047fSniklas    Written by Steve Chamberlain sac@cygnus.com
52159047fSniklas 
62159047fSniklas This file is part of GLD, the Gnu Linker.
72159047fSniklas 
82159047fSniklas This program is free software; you can redistribute it and/or modify
92159047fSniklas it under the terms of the GNU General Public License as published by
102159047fSniklas the Free Software Foundation; either version 2 of the License, or
112159047fSniklas (at your option) any later version.
122159047fSniklas 
132159047fSniklas This program is distributed in the hope that it will be useful,
142159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
152159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
162159047fSniklas GNU General Public License for more details.
172159047fSniklas 
182159047fSniklas You should have received a copy of the GNU General Public License
192159047fSniklas along with this program; if not, write to the Free Software
202159047fSniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
212159047fSniklas 
222159047fSniklas #include "bfd.h"
232159047fSniklas #include "sysdep.h"
242159047fSniklas #include "bfdlink.h"
25191aa565Sniklas #include "libiberty.h"
26*007c2a45Smiod #include "safe-ctype.h"
272159047fSniklas 
282159047fSniklas #include "ld.h"
292159047fSniklas #include "ldexp.h"
302159047fSniklas #include "ldlang.h"
312159047fSniklas #include "ldwrite.h"
322159047fSniklas #include "ldmisc.h"
33c074d1c9Sdrahn #include <ldgram.h>
342159047fSniklas #include "ldmain.h"
352159047fSniklas 
362159047fSniklas /* Build link_order structures for the BFD linker.  */
372159047fSniklas 
382159047fSniklas static void
build_link_order(lang_statement_union_type * statement)39*007c2a45Smiod build_link_order (lang_statement_union_type *statement)
402159047fSniklas {
412159047fSniklas   switch (statement->header.type)
422159047fSniklas     {
432159047fSniklas     case lang_data_statement_enum:
442159047fSniklas       {
452159047fSniklas 	asection *output_section;
462159047fSniklas 	struct bfd_link_order *link_order;
472159047fSniklas 	bfd_vma value;
48c074d1c9Sdrahn 	bfd_boolean big_endian = FALSE;
492159047fSniklas 
502159047fSniklas 	output_section = statement->data_statement.output_section;
512159047fSniklas 	ASSERT (output_section->owner == output_bfd);
522159047fSniklas 
532159047fSniklas 	link_order = bfd_new_link_order (output_bfd, output_section);
542159047fSniklas 	if (link_order == NULL)
55b305b0f1Sespie 	  einfo (_("%P%F: bfd_new_link_order failed\n"));
562159047fSniklas 
572159047fSniklas 	link_order->type = bfd_data_link_order;
582159047fSniklas 	link_order->offset = statement->data_statement.output_vma;
59*007c2a45Smiod 	link_order->u.data.contents = xmalloc (QUAD_SIZE);
602159047fSniklas 
612159047fSniklas 	value = statement->data_statement.value;
622159047fSniklas 
63191aa565Sniklas 	/* If the endianness of the output BFD is not known, then we
64191aa565Sniklas 	   base the endianness of the data on the first input file.
65191aa565Sniklas 	   By convention, the bfd_put routines for an unknown
66191aa565Sniklas 	   endianness are big endian, so we must swap here if the
67191aa565Sniklas 	   input file is little endian.  */
68b305b0f1Sespie 	if (bfd_big_endian (output_bfd))
69c074d1c9Sdrahn 	  big_endian = TRUE;
70b305b0f1Sespie 	else if (bfd_little_endian (output_bfd))
71c074d1c9Sdrahn 	  big_endian = FALSE;
72b305b0f1Sespie 	else
73191aa565Sniklas 	  {
74c074d1c9Sdrahn 	    bfd_boolean swap;
75191aa565Sniklas 
76c074d1c9Sdrahn 	    swap = FALSE;
77b305b0f1Sespie 	    if (command_line.endian == ENDIAN_BIG)
78c074d1c9Sdrahn 	      big_endian = TRUE;
79b305b0f1Sespie 	    else if (command_line.endian == ENDIAN_LITTLE)
80b305b0f1Sespie 	      {
81c074d1c9Sdrahn 		big_endian = FALSE;
82c074d1c9Sdrahn 		swap = TRUE;
83b305b0f1Sespie 	      }
84191aa565Sniklas 	    else if (command_line.endian == ENDIAN_UNSET)
85191aa565Sniklas 	      {
86c074d1c9Sdrahn 		big_endian = TRUE;
87b305b0f1Sespie 		{
88191aa565Sniklas 		  LANG_FOR_EACH_INPUT_STATEMENT (s)
89191aa565Sniklas 		    {
90191aa565Sniklas 		      if (s->the_bfd != NULL)
91191aa565Sniklas 			{
92191aa565Sniklas 			  if (bfd_little_endian (s->the_bfd))
93b305b0f1Sespie 			    {
94c074d1c9Sdrahn 			      big_endian = FALSE;
95c074d1c9Sdrahn 			      swap = TRUE;
96b305b0f1Sespie 			    }
97191aa565Sniklas 			  break;
98191aa565Sniklas 			}
99191aa565Sniklas 		    }
100191aa565Sniklas 		}
101b305b0f1Sespie 	      }
102191aa565Sniklas 
103191aa565Sniklas 	    if (swap)
104191aa565Sniklas 	      {
105191aa565Sniklas 		bfd_byte buffer[8];
106191aa565Sniklas 
107191aa565Sniklas 		switch (statement->data_statement.type)
108191aa565Sniklas 		  {
109191aa565Sniklas 		  case QUAD:
110b305b0f1Sespie 		  case SQUAD:
111b305b0f1Sespie 		    if (sizeof (bfd_vma) >= QUAD_SIZE)
112b305b0f1Sespie 		      {
113191aa565Sniklas 			bfd_putl64 (value, buffer);
114191aa565Sniklas 			value = bfd_getb64 (buffer);
115191aa565Sniklas 			break;
116b305b0f1Sespie 		      }
117b305b0f1Sespie 		    /* Fall through.  */
118191aa565Sniklas 		  case LONG:
119191aa565Sniklas 		    bfd_putl32 (value, buffer);
120191aa565Sniklas 		    value = bfd_getb32 (buffer);
121191aa565Sniklas 		    break;
122191aa565Sniklas 		  case SHORT:
123191aa565Sniklas 		    bfd_putl16 (value, buffer);
124191aa565Sniklas 		    value = bfd_getb16 (buffer);
125191aa565Sniklas 		    break;
126191aa565Sniklas 		  case BYTE:
127191aa565Sniklas 		    break;
128191aa565Sniklas 		  default:
129191aa565Sniklas 		    abort ();
130191aa565Sniklas 		  }
131191aa565Sniklas 	      }
132191aa565Sniklas 	  }
133191aa565Sniklas 
1342159047fSniklas 	ASSERT (output_section->owner == output_bfd);
1352159047fSniklas 	switch (statement->data_statement.type)
1362159047fSniklas 	  {
1372159047fSniklas 	  case QUAD:
138b305b0f1Sespie 	  case SQUAD:
139b305b0f1Sespie 	    if (sizeof (bfd_vma) >= QUAD_SIZE)
1402159047fSniklas 	      bfd_put_64 (output_bfd, value, link_order->u.data.contents);
141b305b0f1Sespie 	    else
142b305b0f1Sespie 	      {
143b305b0f1Sespie 		bfd_vma high;
144b305b0f1Sespie 
145b305b0f1Sespie 		if (statement->data_statement.type == QUAD)
146b305b0f1Sespie 		  high = 0;
147b305b0f1Sespie 		else if ((value & 0x80000000) == 0)
148b305b0f1Sespie 		  high = 0;
149b305b0f1Sespie 		else
150b305b0f1Sespie 		  high = (bfd_vma) -1;
151b305b0f1Sespie 		bfd_put_32 (output_bfd, high,
152b305b0f1Sespie 			    (link_order->u.data.contents
153b305b0f1Sespie 			     + (big_endian ? 0 : 4)));
154b305b0f1Sespie 		bfd_put_32 (output_bfd, value,
155b305b0f1Sespie 			    (link_order->u.data.contents
156b305b0f1Sespie 			     + (big_endian ? 4 : 0)));
157b305b0f1Sespie 	      }
1582159047fSniklas 	    link_order->size = QUAD_SIZE;
1592159047fSniklas 	    break;
1602159047fSniklas 	  case LONG:
1612159047fSniklas 	    bfd_put_32 (output_bfd, value, link_order->u.data.contents);
1622159047fSniklas 	    link_order->size = LONG_SIZE;
1632159047fSniklas 	    break;
1642159047fSniklas 	  case SHORT:
1652159047fSniklas 	    bfd_put_16 (output_bfd, value, link_order->u.data.contents);
1662159047fSniklas 	    link_order->size = SHORT_SIZE;
1672159047fSniklas 	    break;
1682159047fSniklas 	  case BYTE:
1692159047fSniklas 	    bfd_put_8 (output_bfd, value, link_order->u.data.contents);
1702159047fSniklas 	    link_order->size = BYTE_SIZE;
1712159047fSniklas 	    break;
1722159047fSniklas 	  default:
1732159047fSniklas 	    abort ();
1742159047fSniklas 	  }
1752159047fSniklas       }
1762159047fSniklas       break;
1772159047fSniklas 
1782159047fSniklas     case lang_reloc_statement_enum:
1792159047fSniklas       {
1802159047fSniklas 	lang_reloc_statement_type *rs;
1812159047fSniklas 	asection *output_section;
1822159047fSniklas 	struct bfd_link_order *link_order;
1832159047fSniklas 
1842159047fSniklas 	rs = &statement->reloc_statement;
1852159047fSniklas 
1862159047fSniklas 	output_section = rs->output_section;
1872159047fSniklas 	ASSERT (output_section->owner == output_bfd);
1882159047fSniklas 
1892159047fSniklas 	link_order = bfd_new_link_order (output_bfd, output_section);
1902159047fSniklas 	if (link_order == NULL)
191b305b0f1Sespie 	  einfo (_("%P%F: bfd_new_link_order failed\n"));
1922159047fSniklas 
1932159047fSniklas 	link_order->offset = rs->output_vma;
1942159047fSniklas 	link_order->size = bfd_get_reloc_size (rs->howto);
1952159047fSniklas 
196*007c2a45Smiod 	link_order->u.reloc.p = xmalloc (sizeof (struct bfd_link_order_reloc));
1972159047fSniklas 
1982159047fSniklas 	link_order->u.reloc.p->reloc = rs->reloc;
1992159047fSniklas 	link_order->u.reloc.p->addend = rs->addend_value;
2002159047fSniklas 
2012159047fSniklas 	if (rs->name == NULL)
2022159047fSniklas 	  {
2032159047fSniklas 	    link_order->type = bfd_section_reloc_link_order;
2042159047fSniklas 	    if (rs->section->owner == output_bfd)
2052159047fSniklas 	      link_order->u.reloc.p->u.section = rs->section;
2062159047fSniklas 	    else
2072159047fSniklas 	      {
2082159047fSniklas 		link_order->u.reloc.p->u.section = rs->section->output_section;
2092159047fSniklas 		link_order->u.reloc.p->addend += rs->section->output_offset;
2102159047fSniklas 	      }
2112159047fSniklas 	  }
2122159047fSniklas 	else
2132159047fSniklas 	  {
2142159047fSniklas 	    link_order->type = bfd_symbol_reloc_link_order;
2152159047fSniklas 	    link_order->u.reloc.p->u.name = rs->name;
2162159047fSniklas 	  }
2172159047fSniklas       }
2182159047fSniklas       break;
2192159047fSniklas 
2202159047fSniklas     case lang_input_section_enum:
2212159047fSniklas       /* Create a new link_order in the output section with this
2222159047fSniklas 	 attached */
223c074d1c9Sdrahn       if (!statement->input_section.ifile->just_syms_flag)
2242159047fSniklas 	{
2252159047fSniklas 	  asection *i = statement->input_section.section;
2262159047fSniklas 	  asection *output_section = i->output_section;
2272159047fSniklas 
2282159047fSniklas 	  ASSERT (output_section->owner == output_bfd);
2292159047fSniklas 
230c074d1c9Sdrahn 	  if ((output_section->flags & SEC_HAS_CONTENTS) != 0
231c074d1c9Sdrahn 	      || ((output_section->flags & SEC_LOAD) != 0
232c074d1c9Sdrahn 		  && (output_section->flags & SEC_THREAD_LOCAL)))
2332159047fSniklas 	    {
2342159047fSniklas 	      struct bfd_link_order *link_order;
2352159047fSniklas 
2362159047fSniklas 	      link_order = bfd_new_link_order (output_bfd, output_section);
2372159047fSniklas 
2382159047fSniklas 	      if (i->flags & SEC_NEVER_LOAD)
2392159047fSniklas 		{
2402159047fSniklas 		  /* We've got a never load section inside one which
2412159047fSniklas 		     is going to be output, we'll change it into a
242c074d1c9Sdrahn 		     fill.  */
243c074d1c9Sdrahn 		  link_order->type = bfd_data_link_order;
244c074d1c9Sdrahn 		  link_order->u.data.contents = "";
245c074d1c9Sdrahn 		  link_order->u.data.size = 1;
2462159047fSniklas 		}
2472159047fSniklas 	      else
2482159047fSniklas 		{
2492159047fSniklas 		  link_order->type = bfd_indirect_link_order;
2502159047fSniklas 		  link_order->u.indirect.section = i;
2512159047fSniklas 		  ASSERT (i->output_section == output_section);
2522159047fSniklas 		}
2532159047fSniklas 	      if (i->_cooked_size)
2542159047fSniklas 		link_order->size = i->_cooked_size;
2552159047fSniklas 	      else
2562159047fSniklas 		link_order->size = bfd_get_section_size_before_reloc (i);
2572159047fSniklas 	      link_order->offset = i->output_offset;
2582159047fSniklas 	    }
2592159047fSniklas 	}
2602159047fSniklas       break;
2612159047fSniklas 
2622159047fSniklas     case lang_padding_statement_enum:
2632159047fSniklas       /* Make a new link_order with the right filler */
2642159047fSniklas       {
2652159047fSniklas 	asection *output_section;
2662159047fSniklas 	struct bfd_link_order *link_order;
2672159047fSniklas 
2682159047fSniklas 	output_section = statement->padding_statement.output_section;
2692159047fSniklas 	ASSERT (statement->padding_statement.output_section->owner
2702159047fSniklas 		== output_bfd);
2712159047fSniklas 	if ((output_section->flags & SEC_HAS_CONTENTS) != 0)
2722159047fSniklas 	  {
2732159047fSniklas 	    link_order = bfd_new_link_order (output_bfd, output_section);
274c074d1c9Sdrahn 	    link_order->type = bfd_data_link_order;
2752159047fSniklas 	    link_order->size = statement->padding_statement.size;
2762159047fSniklas 	    link_order->offset = statement->padding_statement.output_offset;
277c074d1c9Sdrahn 	    link_order->u.data.contents = statement->padding_statement.fill->data;
278c074d1c9Sdrahn 	    link_order->u.data.size = statement->padding_statement.fill->size;
2792159047fSniklas 	  }
2802159047fSniklas       }
2812159047fSniklas       break;
2822159047fSniklas 
2832159047fSniklas     default:
2842159047fSniklas       /* All the other ones fall through */
2852159047fSniklas       break;
2862159047fSniklas     }
2872159047fSniklas }
2882159047fSniklas 
289*007c2a45Smiod /* Return true if NAME is the name of an unsplittable section. These
290*007c2a45Smiod    are the stabs strings, dwarf strings.  */
2912159047fSniklas 
292*007c2a45Smiod static bfd_boolean
unsplittable_name(const char * name)293*007c2a45Smiod unsplittable_name (const char *name)
294*007c2a45Smiod {
295*007c2a45Smiod   if (strncmp (name, ".stab", 5) == 0)
296*007c2a45Smiod     {
297*007c2a45Smiod       /* There are several stab like string sections. We pattern match on
298*007c2a45Smiod 	 ".stab...str"  */
299*007c2a45Smiod       unsigned len = strlen (name);
300*007c2a45Smiod       if (strcmp (&name[len-3], "str") == 0)
301*007c2a45Smiod 	return TRUE;
302*007c2a45Smiod     }
303*007c2a45Smiod   else if (strcmp (name, "$GDB_STRINGS$") == 0)
304*007c2a45Smiod     return TRUE;
305*007c2a45Smiod   return FALSE;
306*007c2a45Smiod }
3072159047fSniklas 
3082159047fSniklas /* Wander around the input sections, make sure that
3092159047fSniklas    we'll never try and create an output section with more relocs
3102159047fSniklas    than will fit.. Do this by always assuming the worst case, and
311b55d4692Sfgsch    creating new output sections with all the right bits.  */
3122159047fSniklas #define TESTIT 1
3132159047fSniklas static asection *
clone_section(bfd * abfd,asection * s,const char * name,int * count)314*007c2a45Smiod clone_section (bfd *abfd, asection *s, const char *name, int *count)
3152159047fSniklas {
316*007c2a45Smiod   char *tname;
317b55d4692Sfgsch   char *sname;
318*007c2a45Smiod   unsigned int len;
3192159047fSniklas   asection *n;
3202159047fSniklas   struct bfd_link_hash_entry *h;
321b55d4692Sfgsch 
322*007c2a45Smiod   /* Invent a section name from the section name and a dotted numeric
323*007c2a45Smiod      suffix.   */
324*007c2a45Smiod   len = strlen (name);
325*007c2a45Smiod   tname = xmalloc (len + 1);
326*007c2a45Smiod   memcpy (tname, name, len + 1);
327*007c2a45Smiod   /* Remove a dotted number suffix, from a previous split link. */
328*007c2a45Smiod   while (len && ISDIGIT (tname[len-1]))
329*007c2a45Smiod     len--;
330*007c2a45Smiod   if (len > 1 && tname[len-1] == '.')
331*007c2a45Smiod     /* It was a dotted number. */
332*007c2a45Smiod     tname[len-1] = 0;
333*007c2a45Smiod 
334*007c2a45Smiod   /* We want to use the whole of the original section name for the
335*007c2a45Smiod      split name, but coff can be restricted to 8 character names.  */
336*007c2a45Smiod   if (bfd_family_coff (abfd) && strlen (tname) > 5)
337*007c2a45Smiod     {
338*007c2a45Smiod       /* Some section names cannot be truncated, as the name is
339*007c2a45Smiod 	 used to locate some other section.  */
340*007c2a45Smiod       if (strncmp (name, ".stab", 5) == 0
341*007c2a45Smiod 	  || strcmp (name, "$GDB_SYMBOLS$") == 0)
342*007c2a45Smiod 	{
343*007c2a45Smiod 	  einfo (_ ("%F%P: cannot create split section name for %s\n"), name);
344*007c2a45Smiod 	  /* Silence gcc warnings.  einfo exits, so we never reach here.  */
345*007c2a45Smiod 	  return NULL;
346*007c2a45Smiod 	}
347*007c2a45Smiod       tname[5] = 0;
348*007c2a45Smiod     }
349*007c2a45Smiod 
350*007c2a45Smiod   if ((sname = bfd_get_unique_section_name (abfd, tname, count)) == NULL
351b55d4692Sfgsch       || (n = bfd_make_section_anyway (abfd, sname)) == NULL
352b55d4692Sfgsch       || (h = bfd_link_hash_lookup (link_info.hash,
353c074d1c9Sdrahn 				    sname, TRUE, TRUE, FALSE)) == NULL)
3542159047fSniklas     {
355b55d4692Sfgsch       einfo (_("%F%P: clone section failed: %E\n"));
356b55d4692Sfgsch       /* Silence gcc warnings.  einfo exits, so we never reach here.  */
357b55d4692Sfgsch       return NULL;
3582159047fSniklas     }
359*007c2a45Smiod   free (tname);
3602159047fSniklas 
361b55d4692Sfgsch   /* Set up section symbol.  */
3622159047fSniklas   h->type = bfd_link_hash_defined;
3632159047fSniklas   h->u.def.value = 0;
3642159047fSniklas   h->u.def.section = n;
3652159047fSniklas 
3662159047fSniklas   n->flags = s->flags;
3672159047fSniklas   n->vma = s->vma;
3682159047fSniklas   n->user_set_vma = s->user_set_vma;
3692159047fSniklas   n->lma = s->lma;
3702159047fSniklas   n->_cooked_size = 0;
3712159047fSniklas   n->_raw_size = 0;
3722159047fSniklas   n->output_offset = s->output_offset;
3732159047fSniklas   n->output_section = n;
3742159047fSniklas   n->orelocation = 0;
3752159047fSniklas   n->reloc_count = 0;
3762159047fSniklas   n->alignment_power = s->alignment_power;
3772159047fSniklas   return n;
3782159047fSniklas }
3792159047fSniklas 
3802159047fSniklas #if TESTING
3812159047fSniklas static void
ds(asection * s)382*007c2a45Smiod ds (asection *s)
3832159047fSniklas {
3842159047fSniklas   struct bfd_link_order *l = s->link_order_head;
3852159047fSniklas   printf ("vma %x size %x\n", s->vma, s->_raw_size);
3862159047fSniklas   while (l)
3872159047fSniklas     {
3882159047fSniklas       if (l->type == bfd_indirect_link_order)
3892159047fSniklas 	{
3902159047fSniklas 	  printf ("%8x %s\n", l->offset, l->u.indirect.section->owner->filename);
3912159047fSniklas 	}
3922159047fSniklas       else
3932159047fSniklas 	{
394b305b0f1Sespie 	  printf (_("%8x something else\n"), l->offset);
3952159047fSniklas 	}
3962159047fSniklas       l = l->next;
3972159047fSniklas     }
3982159047fSniklas   printf ("\n");
3992159047fSniklas }
400b55d4692Sfgsch 
dump(char * s,asection * a1,asection * a2)401*007c2a45Smiod dump (char *s, asection *a1, asection *a2)
4022159047fSniklas {
4032159047fSniklas   printf ("%s\n", s);
4042159047fSniklas   ds (a1);
4052159047fSniklas   ds (a2);
4062159047fSniklas }
4072159047fSniklas 
4082159047fSniklas static void
sanity_check(bfd * abfd)409*007c2a45Smiod sanity_check (bfd *abfd)
4102159047fSniklas {
4112159047fSniklas   asection *s;
4122159047fSniklas   for (s = abfd->sections; s; s = s->next)
4132159047fSniklas     {
4142159047fSniklas       struct bfd_link_order *p;
4152159047fSniklas       bfd_vma prev = 0;
4162159047fSniklas       for (p = s->link_order_head; p; p = p->next)
4172159047fSniklas 	{
4182159047fSniklas 	  if (p->offset > 100000)
4192159047fSniklas 	    abort ();
4202159047fSniklas 	  if (p->offset < prev)
4212159047fSniklas 	    abort ();
4222159047fSniklas 	  prev = p->offset;
4232159047fSniklas 	}
4242159047fSniklas     }
4252159047fSniklas }
4262159047fSniklas #else
4272159047fSniklas #define sanity_check(a)
4282159047fSniklas #define dump(a, b, c)
4292159047fSniklas #endif
4302159047fSniklas 
431b305b0f1Sespie static void
split_sections(bfd * abfd,struct bfd_link_info * info)432*007c2a45Smiod split_sections (bfd *abfd, struct bfd_link_info *info)
4332159047fSniklas {
4342159047fSniklas   asection *original_sec;
4352159047fSniklas   int nsecs = abfd->section_count;
4362159047fSniklas   sanity_check (abfd);
437b55d4692Sfgsch   /* Look through all the original sections.  */
4382159047fSniklas   for (original_sec = abfd->sections;
4392159047fSniklas        original_sec && nsecs;
4402159047fSniklas        original_sec = original_sec->next, nsecs--)
4412159047fSniklas     {
4422159047fSniklas       int count = 0;
443b55d4692Sfgsch       unsigned int lines = 0;
444b55d4692Sfgsch       unsigned int relocs = 0;
445b55d4692Sfgsch       bfd_size_type sec_size = 0;
446b55d4692Sfgsch       struct bfd_link_order *l;
447b55d4692Sfgsch       struct bfd_link_order *p;
4482159047fSniklas       bfd_vma vma = original_sec->vma;
4492159047fSniklas       asection *cursor = original_sec;
4502159047fSniklas 
451b55d4692Sfgsch       /* Count up the relocations and line entries to see if anything
452b55d4692Sfgsch 	 would be too big to fit.  Accumulate section size too.  */
453b55d4692Sfgsch       for (l = NULL, p = cursor->link_order_head; p != NULL; p = l->next)
4542159047fSniklas 	{
455b55d4692Sfgsch 	  unsigned int thislines = 0;
456b55d4692Sfgsch 	  unsigned int thisrelocs = 0;
457b55d4692Sfgsch 	  bfd_size_type thissize = 0;
4582159047fSniklas 	  if (p->type == bfd_indirect_link_order)
4592159047fSniklas 	    {
4602159047fSniklas 	      asection *sec;
4612159047fSniklas 
4622159047fSniklas 	      sec = p->u.indirect.section;
4632159047fSniklas 
4642159047fSniklas 	      if (info->strip == strip_none
4652159047fSniklas 		  || info->strip == strip_some)
4662159047fSniklas 		thislines = sec->lineno_count;
4672159047fSniklas 
468*007c2a45Smiod 	      if (info->relocatable)
4692159047fSniklas 		thisrelocs = sec->reloc_count;
4702159047fSniklas 
471b55d4692Sfgsch 	      if (sec->_cooked_size != 0)
472b55d4692Sfgsch 		thissize = sec->_cooked_size;
473b55d4692Sfgsch 	      else
474b55d4692Sfgsch 		thissize = sec->_raw_size;
475b55d4692Sfgsch 
4762159047fSniklas 	    }
477*007c2a45Smiod 	  else if (info->relocatable
4782159047fSniklas 		   && (p->type == bfd_section_reloc_link_order
4792159047fSniklas 		       || p->type == bfd_symbol_reloc_link_order))
4802159047fSniklas 	    thisrelocs++;
4812159047fSniklas 
482b55d4692Sfgsch 	  if (l != NULL
483b55d4692Sfgsch 	      && (thisrelocs + relocs >= config.split_by_reloc
484b55d4692Sfgsch 		  || thislines + lines >= config.split_by_reloc
485*007c2a45Smiod 		  || (thissize + sec_size >= config.split_by_file))
486*007c2a45Smiod 	      && !unsplittable_name (cursor->name))
4872159047fSniklas 	    {
488b55d4692Sfgsch 	      /* Create a new section and put this link order and the
489b55d4692Sfgsch 		 following link orders into it.  */
490b55d4692Sfgsch 	      bfd_vma shift_offset;
491b55d4692Sfgsch 	      asection *n;
4922159047fSniklas 
493b55d4692Sfgsch 	      n = clone_section (abfd, cursor, original_sec->name, &count);
494b55d4692Sfgsch 
495b55d4692Sfgsch 	      /* Attach the link orders to the new section and snip
496b55d4692Sfgsch 		 them off from the old section.  */
497b55d4692Sfgsch 	      n->link_order_head = p;
498b55d4692Sfgsch 	      n->link_order_tail = cursor->link_order_tail;
499b55d4692Sfgsch 	      cursor->link_order_tail = l;
500b55d4692Sfgsch 	      l->next = NULL;
501b55d4692Sfgsch 	      l = p;
502b55d4692Sfgsch 
503b55d4692Sfgsch 	      /* Change the size of the original section and
504b55d4692Sfgsch 		 update the vma of the new one.  */
5052159047fSniklas 
5062159047fSniklas 	      dump ("before snip", cursor, n);
5072159047fSniklas 
508b55d4692Sfgsch 	      shift_offset = p->offset;
509b55d4692Sfgsch 	      if (cursor->_cooked_size != 0)
510b55d4692Sfgsch 		{
511b55d4692Sfgsch 		  n->_cooked_size = cursor->_cooked_size - shift_offset;
512b55d4692Sfgsch 		  cursor->_cooked_size = shift_offset;
513b55d4692Sfgsch 		}
514b55d4692Sfgsch 	      n->_raw_size = cursor->_raw_size - shift_offset;
515b55d4692Sfgsch 	      cursor->_raw_size = shift_offset;
5162159047fSniklas 
517b55d4692Sfgsch 	      vma += shift_offset;
5182159047fSniklas 	      n->lma = n->vma = vma;
5192159047fSniklas 
520b55d4692Sfgsch 	      /* Run down the chain and change the output section to
521b55d4692Sfgsch 		 the right one, update the offsets too.  */
522b55d4692Sfgsch 	      do
5232159047fSniklas 		{
524b55d4692Sfgsch 		  p->offset -= shift_offset;
525b55d4692Sfgsch 		  if (p->type == bfd_indirect_link_order)
5262159047fSniklas 		    {
527b55d4692Sfgsch 		      p->u.indirect.section->output_section = n;
528b55d4692Sfgsch 		      p->u.indirect.section->output_offset = p->offset;
5292159047fSniklas 		    }
530b55d4692Sfgsch 		  p = p->next;
5312159047fSniklas 		}
532b55d4692Sfgsch 	      while (p);
533b55d4692Sfgsch 
5342159047fSniklas 	      dump ("after snip", cursor, n);
5352159047fSniklas 	      cursor = n;
5362159047fSniklas 	      relocs = thisrelocs;
5372159047fSniklas 	      lines = thislines;
538b55d4692Sfgsch 	      sec_size = thissize;
5392159047fSniklas 	    }
5402159047fSniklas 	  else
5412159047fSniklas 	    {
542b55d4692Sfgsch 	      l = p;
5432159047fSniklas 	      relocs += thisrelocs;
5442159047fSniklas 	      lines += thislines;
545b55d4692Sfgsch 	      sec_size += thissize;
5462159047fSniklas 	    }
5472159047fSniklas 	}
5482159047fSniklas     }
5492159047fSniklas   sanity_check (abfd);
5502159047fSniklas }
551b55d4692Sfgsch 
552*007c2a45Smiod /* Call BFD to write out the linked file.  */
553b55d4692Sfgsch 
5542159047fSniklas void
ldwrite(void)555*007c2a45Smiod ldwrite (void)
5562159047fSniklas {
5572159047fSniklas   /* Reset error indicator, which can typically something like invalid
558b55d4692Sfgsch      format from opening up the .o files.  */
5592159047fSniklas   bfd_set_error (bfd_error_no_error);
5602159047fSniklas   lang_for_each_statement (build_link_order);
5612159047fSniklas 
562b55d4692Sfgsch   if (config.split_by_reloc != (unsigned) -1
563b55d4692Sfgsch       || config.split_by_file != (bfd_size_type) -1)
5642159047fSniklas     split_sections (output_bfd, &link_info);
5652159047fSniklas   if (!bfd_final_link (output_bfd, &link_info))
5662159047fSniklas     {
5672159047fSniklas       /* If there was an error recorded, print it out.  Otherwise assume
5682159047fSniklas 	 an appropriate error message like unknown symbol was printed
5692159047fSniklas 	 out.  */
5702159047fSniklas 
5712159047fSniklas       if (bfd_get_error () != bfd_error_no_error)
572b55d4692Sfgsch 	einfo (_("%F%P: final link failed: %E\n"));
5732159047fSniklas       else
5742159047fSniklas 	xexit (1);
5752159047fSniklas     }
5762159047fSniklas }
577