133965Sjdp/* ldwrite.c -- write out the linked file 2218822Sdim Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002, 3218822Sdim 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 433965Sjdp Written by Steve Chamberlain sac@cygnus.com 533965Sjdp 633965SjdpThis file is part of GLD, the Gnu Linker. 733965Sjdp 833965SjdpThis program is free software; you can redistribute it and/or modify 933965Sjdpit under the terms of the GNU General Public License as published by 1033965Sjdpthe Free Software Foundation; either version 2 of the License, or 1133965Sjdp(at your option) any later version. 1233965Sjdp 1333965SjdpThis program is distributed in the hope that it will be useful, 1433965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 1533965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1633965SjdpGNU General Public License for more details. 1733965Sjdp 1833965SjdpYou should have received a copy of the GNU General Public License 1933965Sjdpalong with this program; if not, write to the Free Software 20218822SdimFoundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2133965Sjdp 22218822Sdim#include "sysdep.h" 2333965Sjdp#include "bfd.h" 2433965Sjdp#include "bfdlink.h" 2533965Sjdp#include "libiberty.h" 26130561Sobrien#include "safe-ctype.h" 2733965Sjdp 2833965Sjdp#include "ld.h" 2933965Sjdp#include "ldexp.h" 3033965Sjdp#include "ldlang.h" 3133965Sjdp#include "ldwrite.h" 3233965Sjdp#include "ldmisc.h" 33107492Sobrien#include <ldgram.h> 3433965Sjdp#include "ldmain.h" 3533965Sjdp 3633965Sjdp/* Build link_order structures for the BFD linker. */ 3733965Sjdp 3833965Sjdpstatic void 39130561Sobrienbuild_link_order (lang_statement_union_type *statement) 4033965Sjdp{ 4133965Sjdp switch (statement->header.type) 4233965Sjdp { 4333965Sjdp case lang_data_statement_enum: 4433965Sjdp { 4533965Sjdp asection *output_section; 4633965Sjdp struct bfd_link_order *link_order; 4733965Sjdp bfd_vma value; 48130561Sobrien bfd_boolean big_endian = FALSE; 4933965Sjdp 5033965Sjdp output_section = statement->data_statement.output_section; 5133965Sjdp ASSERT (output_section->owner == output_bfd); 5233965Sjdp 5333965Sjdp link_order = bfd_new_link_order (output_bfd, output_section); 5433965Sjdp if (link_order == NULL) 5560484Sobrien einfo (_("%P%F: bfd_new_link_order failed\n")); 5633965Sjdp 5733965Sjdp link_order->type = bfd_data_link_order; 58218822Sdim link_order->offset = statement->data_statement.output_offset; 59130561Sobrien link_order->u.data.contents = xmalloc (QUAD_SIZE); 6033965Sjdp 6133965Sjdp value = statement->data_statement.value; 6233965Sjdp 6333965Sjdp /* If the endianness of the output BFD is not known, then we 6433965Sjdp base the endianness of the data on the first input file. 6533965Sjdp By convention, the bfd_put routines for an unknown 6633965Sjdp endianness are big endian, so we must swap here if the 6733965Sjdp input file is little endian. */ 6838889Sjdp if (bfd_big_endian (output_bfd)) 69130561Sobrien big_endian = TRUE; 7038889Sjdp else if (bfd_little_endian (output_bfd)) 71130561Sobrien big_endian = FALSE; 7238889Sjdp else 7333965Sjdp { 74130561Sobrien bfd_boolean swap; 7533965Sjdp 76130561Sobrien swap = FALSE; 7738889Sjdp if (command_line.endian == ENDIAN_BIG) 78130561Sobrien big_endian = TRUE; 7938889Sjdp else if (command_line.endian == ENDIAN_LITTLE) 8038889Sjdp { 81130561Sobrien big_endian = FALSE; 82130561Sobrien swap = TRUE; 8338889Sjdp } 8433965Sjdp else if (command_line.endian == ENDIAN_UNSET) 8533965Sjdp { 86130561Sobrien big_endian = TRUE; 8738889Sjdp { 8838889Sjdp LANG_FOR_EACH_INPUT_STATEMENT (s) 8938889Sjdp { 9038889Sjdp if (s->the_bfd != NULL) 9138889Sjdp { 9238889Sjdp if (bfd_little_endian (s->the_bfd)) 9338889Sjdp { 94130561Sobrien big_endian = FALSE; 95130561Sobrien swap = TRUE; 9638889Sjdp } 9738889Sjdp break; 9838889Sjdp } 9938889Sjdp } 10038889Sjdp } 10133965Sjdp } 10233965Sjdp 10333965Sjdp if (swap) 10433965Sjdp { 10533965Sjdp bfd_byte buffer[8]; 10633965Sjdp 10733965Sjdp switch (statement->data_statement.type) 10833965Sjdp { 10933965Sjdp case QUAD: 11038889Sjdp case SQUAD: 11138889Sjdp if (sizeof (bfd_vma) >= QUAD_SIZE) 11238889Sjdp { 11338889Sjdp bfd_putl64 (value, buffer); 11438889Sjdp value = bfd_getb64 (buffer); 11538889Sjdp break; 11638889Sjdp } 11738889Sjdp /* Fall through. */ 11833965Sjdp case LONG: 11933965Sjdp bfd_putl32 (value, buffer); 12033965Sjdp value = bfd_getb32 (buffer); 12133965Sjdp break; 12233965Sjdp case SHORT: 12333965Sjdp bfd_putl16 (value, buffer); 12433965Sjdp value = bfd_getb16 (buffer); 12533965Sjdp break; 12633965Sjdp case BYTE: 12733965Sjdp break; 12833965Sjdp default: 12933965Sjdp abort (); 13033965Sjdp } 13133965Sjdp } 13233965Sjdp } 13333965Sjdp 13433965Sjdp ASSERT (output_section->owner == output_bfd); 13533965Sjdp switch (statement->data_statement.type) 13633965Sjdp { 13733965Sjdp case QUAD: 13838889Sjdp case SQUAD: 13938889Sjdp if (sizeof (bfd_vma) >= QUAD_SIZE) 14038889Sjdp bfd_put_64 (output_bfd, value, link_order->u.data.contents); 14138889Sjdp else 14238889Sjdp { 14338889Sjdp bfd_vma high; 14438889Sjdp 14538889Sjdp if (statement->data_statement.type == QUAD) 14638889Sjdp high = 0; 14738889Sjdp else if ((value & 0x80000000) == 0) 14838889Sjdp high = 0; 14938889Sjdp else 15038889Sjdp high = (bfd_vma) -1; 15138889Sjdp bfd_put_32 (output_bfd, high, 15238889Sjdp (link_order->u.data.contents 15338889Sjdp + (big_endian ? 0 : 4))); 15438889Sjdp bfd_put_32 (output_bfd, value, 15538889Sjdp (link_order->u.data.contents 15638889Sjdp + (big_endian ? 4 : 0))); 15738889Sjdp } 15833965Sjdp link_order->size = QUAD_SIZE; 15933965Sjdp break; 16033965Sjdp case LONG: 16133965Sjdp bfd_put_32 (output_bfd, value, link_order->u.data.contents); 16233965Sjdp link_order->size = LONG_SIZE; 16333965Sjdp break; 16433965Sjdp case SHORT: 16533965Sjdp bfd_put_16 (output_bfd, value, link_order->u.data.contents); 16633965Sjdp link_order->size = SHORT_SIZE; 16733965Sjdp break; 16833965Sjdp case BYTE: 16933965Sjdp bfd_put_8 (output_bfd, value, link_order->u.data.contents); 17033965Sjdp link_order->size = BYTE_SIZE; 17133965Sjdp break; 17233965Sjdp default: 17333965Sjdp abort (); 17433965Sjdp } 17533965Sjdp } 17633965Sjdp break; 17733965Sjdp 17833965Sjdp case lang_reloc_statement_enum: 17933965Sjdp { 18033965Sjdp lang_reloc_statement_type *rs; 18133965Sjdp asection *output_section; 18233965Sjdp struct bfd_link_order *link_order; 18333965Sjdp 18433965Sjdp rs = &statement->reloc_statement; 18533965Sjdp 18633965Sjdp output_section = rs->output_section; 18733965Sjdp ASSERT (output_section->owner == output_bfd); 18833965Sjdp 18933965Sjdp link_order = bfd_new_link_order (output_bfd, output_section); 19033965Sjdp if (link_order == NULL) 19160484Sobrien einfo (_("%P%F: bfd_new_link_order failed\n")); 19233965Sjdp 193218822Sdim link_order->offset = rs->output_offset; 19433965Sjdp link_order->size = bfd_get_reloc_size (rs->howto); 19533965Sjdp 196130561Sobrien link_order->u.reloc.p = xmalloc (sizeof (struct bfd_link_order_reloc)); 19733965Sjdp 19833965Sjdp link_order->u.reloc.p->reloc = rs->reloc; 19933965Sjdp link_order->u.reloc.p->addend = rs->addend_value; 20033965Sjdp 20133965Sjdp if (rs->name == NULL) 20233965Sjdp { 20333965Sjdp link_order->type = bfd_section_reloc_link_order; 20433965Sjdp if (rs->section->owner == output_bfd) 20533965Sjdp link_order->u.reloc.p->u.section = rs->section; 20633965Sjdp else 20733965Sjdp { 20833965Sjdp link_order->u.reloc.p->u.section = rs->section->output_section; 20933965Sjdp link_order->u.reloc.p->addend += rs->section->output_offset; 21033965Sjdp } 21133965Sjdp } 21233965Sjdp else 21333965Sjdp { 21433965Sjdp link_order->type = bfd_symbol_reloc_link_order; 21533965Sjdp link_order->u.reloc.p->u.name = rs->name; 21633965Sjdp } 21733965Sjdp } 21833965Sjdp break; 21933965Sjdp 22033965Sjdp case lang_input_section_enum: 221218822Sdim { 222218822Sdim /* Create a new link_order in the output section with this 223218822Sdim attached */ 224218822Sdim asection *i = statement->input_section.section; 22533965Sjdp 226218822Sdim if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag 227218822Sdim && (i->flags & SEC_EXCLUDE) == 0) 228218822Sdim { 229218822Sdim asection *output_section = i->output_section; 23033965Sjdp 231218822Sdim ASSERT (output_section->owner == output_bfd); 23233965Sjdp 233218822Sdim if ((output_section->flags & SEC_HAS_CONTENTS) != 0 234218822Sdim || ((output_section->flags & SEC_LOAD) != 0 235218822Sdim && (output_section->flags & SEC_THREAD_LOCAL))) 236218822Sdim { 237218822Sdim struct bfd_link_order *link_order; 23833965Sjdp 239218822Sdim link_order = bfd_new_link_order (output_bfd, output_section); 240218822Sdim 241218822Sdim if (i->flags & SEC_NEVER_LOAD) 242218822Sdim { 243218822Sdim /* We've got a never load section inside one which 244218822Sdim is going to be output, we'll change it into a 245218822Sdim fill. */ 246218822Sdim link_order->type = bfd_data_link_order; 247218822Sdim link_order->u.data.contents = (unsigned char *) ""; 248218822Sdim link_order->u.data.size = 1; 249218822Sdim } 250218822Sdim else 251218822Sdim { 252218822Sdim link_order->type = bfd_indirect_link_order; 253218822Sdim link_order->u.indirect.section = i; 254218822Sdim ASSERT (i->output_section == output_section); 255218822Sdim } 256218822Sdim link_order->size = i->size; 257218822Sdim link_order->offset = i->output_offset; 258218822Sdim } 259218822Sdim } 260218822Sdim } 26133965Sjdp break; 26233965Sjdp 26333965Sjdp case lang_padding_statement_enum: 26433965Sjdp /* Make a new link_order with the right filler */ 26533965Sjdp { 26633965Sjdp asection *output_section; 26733965Sjdp struct bfd_link_order *link_order; 26833965Sjdp 26933965Sjdp output_section = statement->padding_statement.output_section; 27033965Sjdp ASSERT (statement->padding_statement.output_section->owner 27133965Sjdp == output_bfd); 27233965Sjdp if ((output_section->flags & SEC_HAS_CONTENTS) != 0) 27333965Sjdp { 27433965Sjdp link_order = bfd_new_link_order (output_bfd, output_section); 275104834Sobrien link_order->type = bfd_data_link_order; 27633965Sjdp link_order->size = statement->padding_statement.size; 27733965Sjdp link_order->offset = statement->padding_statement.output_offset; 278104834Sobrien link_order->u.data.contents = statement->padding_statement.fill->data; 279104834Sobrien link_order->u.data.size = statement->padding_statement.fill->size; 28033965Sjdp } 28133965Sjdp } 28233965Sjdp break; 28333965Sjdp 28433965Sjdp default: 28533965Sjdp /* All the other ones fall through */ 28633965Sjdp break; 28733965Sjdp } 28833965Sjdp} 28933965Sjdp 290130561Sobrien/* Return true if NAME is the name of an unsplittable section. These 291130561Sobrien are the stabs strings, dwarf strings. */ 29233965Sjdp 293130561Sobrienstatic bfd_boolean 294130561Sobrienunsplittable_name (const char *name) 295130561Sobrien{ 296218822Sdim if (CONST_STRNEQ (name, ".stab")) 297130561Sobrien { 298130561Sobrien /* There are several stab like string sections. We pattern match on 299130561Sobrien ".stab...str" */ 300130561Sobrien unsigned len = strlen (name); 301130561Sobrien if (strcmp (&name[len-3], "str") == 0) 302130561Sobrien return TRUE; 303130561Sobrien } 304130561Sobrien else if (strcmp (name, "$GDB_STRINGS$") == 0) 305130561Sobrien return TRUE; 306130561Sobrien return FALSE; 307130561Sobrien} 30833965Sjdp 30933965Sjdp/* Wander around the input sections, make sure that 31033965Sjdp we'll never try and create an output section with more relocs 31133965Sjdp than will fit.. Do this by always assuming the worst case, and 31277298Sobrien creating new output sections with all the right bits. */ 31333965Sjdp#define TESTIT 1 31433965Sjdpstatic asection * 315130561Sobrienclone_section (bfd *abfd, asection *s, const char *name, int *count) 31633965Sjdp{ 317130561Sobrien char *tname; 31877298Sobrien char *sname; 319130561Sobrien unsigned int len; 32033965Sjdp asection *n; 32133965Sjdp struct bfd_link_hash_entry *h; 32277298Sobrien 323130561Sobrien /* Invent a section name from the section name and a dotted numeric 324130561Sobrien suffix. */ 325130561Sobrien len = strlen (name); 326130561Sobrien tname = xmalloc (len + 1); 327130561Sobrien memcpy (tname, name, len + 1); 328130561Sobrien /* Remove a dotted number suffix, from a previous split link. */ 329130561Sobrien while (len && ISDIGIT (tname[len-1])) 330130561Sobrien len--; 331130561Sobrien if (len > 1 && tname[len-1] == '.') 332130561Sobrien /* It was a dotted number. */ 333130561Sobrien tname[len-1] = 0; 334130561Sobrien 335130561Sobrien /* We want to use the whole of the original section name for the 336130561Sobrien split name, but coff can be restricted to 8 character names. */ 337130561Sobrien if (bfd_family_coff (abfd) && strlen (tname) > 5) 338130561Sobrien { 339130561Sobrien /* Some section names cannot be truncated, as the name is 340130561Sobrien used to locate some other section. */ 341218822Sdim if (CONST_STRNEQ (name, ".stab") 342130561Sobrien || strcmp (name, "$GDB_SYMBOLS$") == 0) 343130561Sobrien { 344130561Sobrien einfo (_ ("%F%P: cannot create split section name for %s\n"), name); 345130561Sobrien /* Silence gcc warnings. einfo exits, so we never reach here. */ 346130561Sobrien return NULL; 347130561Sobrien } 348130561Sobrien tname[5] = 0; 349130561Sobrien } 350130561Sobrien 351130561Sobrien if ((sname = bfd_get_unique_section_name (abfd, tname, count)) == NULL 35277298Sobrien || (n = bfd_make_section_anyway (abfd, sname)) == NULL 35377298Sobrien || (h = bfd_link_hash_lookup (link_info.hash, 354130561Sobrien sname, TRUE, TRUE, FALSE)) == NULL) 35533965Sjdp { 35677298Sobrien einfo (_("%F%P: clone section failed: %E\n")); 35777298Sobrien /* Silence gcc warnings. einfo exits, so we never reach here. */ 35877298Sobrien return NULL; 35933965Sjdp } 360130561Sobrien free (tname); 361130561Sobrien 36277298Sobrien /* Set up section symbol. */ 36333965Sjdp h->type = bfd_link_hash_defined; 36433965Sjdp h->u.def.value = 0; 36577298Sobrien h->u.def.section = n; 36633965Sjdp 36733965Sjdp n->flags = s->flags; 36833965Sjdp n->vma = s->vma; 36933965Sjdp n->user_set_vma = s->user_set_vma; 37033965Sjdp n->lma = s->lma; 371218822Sdim n->size = 0; 37233965Sjdp n->output_offset = s->output_offset; 37333965Sjdp n->output_section = n; 37433965Sjdp n->orelocation = 0; 37533965Sjdp n->reloc_count = 0; 37633965Sjdp n->alignment_power = s->alignment_power; 37733965Sjdp return n; 37833965Sjdp} 37933965Sjdp 38033965Sjdp#if TESTING 38177298Sobrienstatic void 382130561Sobriends (asection *s) 38333965Sjdp{ 384218822Sdim struct bfd_link_order *l = s->map_head.link_order; 385218822Sdim printf ("vma %x size %x\n", s->vma, s->size); 38633965Sjdp while (l) 38733965Sjdp { 38833965Sjdp if (l->type == bfd_indirect_link_order) 38933965Sjdp { 39033965Sjdp printf ("%8x %s\n", l->offset, l->u.indirect.section->owner->filename); 39133965Sjdp } 39233965Sjdp else 39333965Sjdp { 39460484Sobrien printf (_("%8x something else\n"), l->offset); 39533965Sjdp } 39633965Sjdp l = l->next; 39733965Sjdp } 39833965Sjdp printf ("\n"); 39933965Sjdp} 40077298Sobrien 401130561Sobriendump (char *s, asection *a1, asection *a2) 40233965Sjdp{ 40333965Sjdp printf ("%s\n", s); 40433965Sjdp ds (a1); 40533965Sjdp ds (a2); 40633965Sjdp} 40733965Sjdp 40877298Sobrienstatic void 409130561Sobriensanity_check (bfd *abfd) 41033965Sjdp{ 41133965Sjdp asection *s; 41233965Sjdp for (s = abfd->sections; s; s = s->next) 41333965Sjdp { 41433965Sjdp struct bfd_link_order *p; 41533965Sjdp bfd_vma prev = 0; 416218822Sdim for (p = s->map_head.link_order; p; p = p->next) 41733965Sjdp { 41833965Sjdp if (p->offset > 100000) 41933965Sjdp abort (); 42033965Sjdp if (p->offset < prev) 42133965Sjdp abort (); 42233965Sjdp prev = p->offset; 42333965Sjdp } 42433965Sjdp } 42533965Sjdp} 42633965Sjdp#else 42733965Sjdp#define sanity_check(a) 42833965Sjdp#define dump(a, b, c) 42933965Sjdp#endif 43033965Sjdp 43177298Sobrienstatic void 432130561Sobriensplit_sections (bfd *abfd, struct bfd_link_info *info) 43333965Sjdp{ 43433965Sjdp asection *original_sec; 43533965Sjdp int nsecs = abfd->section_count; 43633965Sjdp sanity_check (abfd); 43777298Sobrien /* Look through all the original sections. */ 43833965Sjdp for (original_sec = abfd->sections; 43933965Sjdp original_sec && nsecs; 44033965Sjdp original_sec = original_sec->next, nsecs--) 44133965Sjdp { 44233965Sjdp int count = 0; 44377298Sobrien unsigned int lines = 0; 44477298Sobrien unsigned int relocs = 0; 44577298Sobrien bfd_size_type sec_size = 0; 44677298Sobrien struct bfd_link_order *l; 44777298Sobrien struct bfd_link_order *p; 44833965Sjdp bfd_vma vma = original_sec->vma; 44933965Sjdp asection *cursor = original_sec; 45033965Sjdp 45177298Sobrien /* Count up the relocations and line entries to see if anything 45277298Sobrien would be too big to fit. Accumulate section size too. */ 453218822Sdim for (l = NULL, p = cursor->map_head.link_order; p != NULL; p = l->next) 45433965Sjdp { 45577298Sobrien unsigned int thislines = 0; 45677298Sobrien unsigned int thisrelocs = 0; 45777298Sobrien bfd_size_type thissize = 0; 45833965Sjdp if (p->type == bfd_indirect_link_order) 45933965Sjdp { 46033965Sjdp asection *sec; 46133965Sjdp 46233965Sjdp sec = p->u.indirect.section; 46333965Sjdp 46433965Sjdp if (info->strip == strip_none 46533965Sjdp || info->strip == strip_some) 46633965Sjdp thislines = sec->lineno_count; 46733965Sjdp 468130561Sobrien if (info->relocatable) 46933965Sjdp thisrelocs = sec->reloc_count; 47033965Sjdp 471218822Sdim thissize = sec->size; 47277298Sobrien 47333965Sjdp } 474130561Sobrien else if (info->relocatable 47533965Sjdp && (p->type == bfd_section_reloc_link_order 47633965Sjdp || p->type == bfd_symbol_reloc_link_order)) 47733965Sjdp thisrelocs++; 47833965Sjdp 47977298Sobrien if (l != NULL 48077298Sobrien && (thisrelocs + relocs >= config.split_by_reloc 48177298Sobrien || thislines + lines >= config.split_by_reloc 482130561Sobrien || (thissize + sec_size >= config.split_by_file)) 483130561Sobrien && !unsplittable_name (cursor->name)) 48433965Sjdp { 48577298Sobrien /* Create a new section and put this link order and the 48677298Sobrien following link orders into it. */ 48777298Sobrien bfd_vma shift_offset; 48877298Sobrien asection *n; 48933965Sjdp 49077298Sobrien n = clone_section (abfd, cursor, original_sec->name, &count); 49133965Sjdp 49277298Sobrien /* Attach the link orders to the new section and snip 49377298Sobrien them off from the old section. */ 494218822Sdim n->map_head.link_order = p; 495218822Sdim n->map_tail.link_order = cursor->map_tail.link_order; 496218822Sdim cursor->map_tail.link_order = l; 49777298Sobrien l->next = NULL; 49877298Sobrien l = p; 49977298Sobrien 50077298Sobrien /* Change the size of the original section and 50177298Sobrien update the vma of the new one. */ 50277298Sobrien 50333965Sjdp dump ("before snip", cursor, n); 50433965Sjdp 50577298Sobrien shift_offset = p->offset; 506218822Sdim n->size = cursor->size - shift_offset; 507218822Sdim cursor->size = shift_offset; 50833965Sjdp 50977298Sobrien vma += shift_offset; 51033965Sjdp n->lma = n->vma = vma; 51133965Sjdp 51277298Sobrien /* Run down the chain and change the output section to 51377298Sobrien the right one, update the offsets too. */ 51477298Sobrien do 51533965Sjdp { 51677298Sobrien p->offset -= shift_offset; 51777298Sobrien if (p->type == bfd_indirect_link_order) 51833965Sjdp { 51977298Sobrien p->u.indirect.section->output_section = n; 52077298Sobrien p->u.indirect.section->output_offset = p->offset; 52133965Sjdp } 52277298Sobrien p = p->next; 52333965Sjdp } 52477298Sobrien while (p); 52577298Sobrien 52633965Sjdp dump ("after snip", cursor, n); 52733965Sjdp cursor = n; 52833965Sjdp relocs = thisrelocs; 52933965Sjdp lines = thislines; 53077298Sobrien sec_size = thissize; 53133965Sjdp } 53233965Sjdp else 53333965Sjdp { 53477298Sobrien l = p; 53533965Sjdp relocs += thisrelocs; 53633965Sjdp lines += thislines; 53777298Sobrien sec_size += thissize; 53833965Sjdp } 53933965Sjdp } 54033965Sjdp } 54133965Sjdp sanity_check (abfd); 54233965Sjdp} 54377298Sobrien 544130561Sobrien/* Call BFD to write out the linked file. */ 54577298Sobrien 54633965Sjdpvoid 547130561Sobrienldwrite (void) 54833965Sjdp{ 54933965Sjdp /* Reset error indicator, which can typically something like invalid 55077298Sobrien format from opening up the .o files. */ 55133965Sjdp bfd_set_error (bfd_error_no_error); 55233965Sjdp lang_for_each_statement (build_link_order); 55333965Sjdp 55477298Sobrien if (config.split_by_reloc != (unsigned) -1 55577298Sobrien || config.split_by_file != (bfd_size_type) -1) 55633965Sjdp split_sections (output_bfd, &link_info); 55733965Sjdp if (!bfd_final_link (output_bfd, &link_info)) 55833965Sjdp { 55933965Sjdp /* If there was an error recorded, print it out. Otherwise assume 56033965Sjdp an appropriate error message like unknown symbol was printed 56133965Sjdp out. */ 56233965Sjdp 56333965Sjdp if (bfd_get_error () != bfd_error_no_error) 56477298Sobrien einfo (_("%F%P: final link failed: %E\n")); 56533965Sjdp else 56677298Sobrien xexit (1); 56733965Sjdp } 56833965Sjdp} 569