X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=ld%2Fldwrite.c;h=5624dfdf4c0a5c22232c9facba346af624efcb45;hb=ddf5db90a175756b3a5c39ee87d549d9f9d09d28;hp=56c4d0a3434c9e73793a47a282872e2bc30b9205;hpb=5718918d7aeb65ee118cd7f2cbcc3f1a4cde4ff6;p=deliverable%2Fbinutils-gdb.git diff --git a/ld/ldwrite.c b/ld/ldwrite.c index 56c4d0a343..5624dfdf4c 100644 --- a/ld/ldwrite.c +++ b/ld/ldwrite.c @@ -1,28 +1,29 @@ /* ldwrite.c -- write out the linked file - Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002, - 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1991-2020 Free Software Foundation, Inc. Written by Steve Chamberlain sac@cygnus.com -This file is part of GLD, the Gnu Linker. + This file is part of the GNU Binutils. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ -#include "bfd.h" #include "sysdep.h" +#include "bfd.h" #include "bfdlink.h" #include "libiberty.h" +#include "ctf-api.h" #include "safe-ctype.h" #include "ld.h" @@ -45,99 +46,68 @@ build_link_order (lang_statement_union_type *statement) asection *output_section; struct bfd_link_order *link_order; bfd_vma value; - bfd_boolean big_endian = FALSE; output_section = statement->data_statement.output_section; - ASSERT (output_section->owner == output_bfd); + ASSERT (output_section->owner == link_info.output_bfd); + + if (!((output_section->flags & SEC_HAS_CONTENTS) != 0 + || ((output_section->flags & SEC_LOAD) != 0 + && (output_section->flags & SEC_THREAD_LOCAL)))) + break; - link_order = bfd_new_link_order (output_bfd, output_section); + link_order = bfd_new_link_order (link_info.output_bfd, output_section); if (link_order == NULL) - einfo (_("%P%F: bfd_new_link_order failed\n")); + einfo (_("%F%P: bfd_new_link_order failed\n")); link_order->type = bfd_data_link_order; - link_order->offset = statement->data_statement.output_vma; - link_order->u.data.contents = xmalloc (QUAD_SIZE); + link_order->offset = statement->data_statement.output_offset; + link_order->u.data.contents = (bfd_byte *) xmalloc (QUAD_SIZE); value = statement->data_statement.value; - /* If the endianness of the output BFD is not known, then we - base the endianness of the data on the first input file. - By convention, the bfd_put routines for an unknown + /* By convention, the bfd_put routines for an unknown endianness are big endian, so we must swap here if the - input file is little endian. */ - if (bfd_big_endian (output_bfd)) - big_endian = TRUE; - else if (bfd_little_endian (output_bfd)) - big_endian = FALSE; - else + input is little endian. */ + if (!bfd_big_endian (link_info.output_bfd) + && !bfd_little_endian (link_info.output_bfd) + && !link_info.big_endian) { - bfd_boolean swap; - - swap = FALSE; - if (command_line.endian == ENDIAN_BIG) - big_endian = TRUE; - else if (command_line.endian == ENDIAN_LITTLE) - { - big_endian = FALSE; - swap = TRUE; - } - else if (command_line.endian == ENDIAN_UNSET) - { - big_endian = TRUE; - { - LANG_FOR_EACH_INPUT_STATEMENT (s) - { - if (s->the_bfd != NULL) - { - if (bfd_little_endian (s->the_bfd)) - { - big_endian = FALSE; - swap = TRUE; - } - break; - } - } - } - } + bfd_byte buffer[8]; - if (swap) + switch (statement->data_statement.type) { - bfd_byte buffer[8]; - - switch (statement->data_statement.type) + case QUAD: + case SQUAD: + if (sizeof (bfd_vma) >= QUAD_SIZE) { - case QUAD: - case SQUAD: - if (sizeof (bfd_vma) >= QUAD_SIZE) - { - bfd_putl64 (value, buffer); - value = bfd_getb64 (buffer); - break; - } - /* Fall through. */ - case LONG: - bfd_putl32 (value, buffer); - value = bfd_getb32 (buffer); - break; - case SHORT: - bfd_putl16 (value, buffer); - value = bfd_getb16 (buffer); + bfd_putl64 (value, buffer); + value = bfd_getb64 (buffer); break; - case BYTE: - break; - default: - abort (); } + /* Fall through. */ + case LONG: + bfd_putl32 (value, buffer); + value = bfd_getb32 (buffer); + break; + case SHORT: + bfd_putl16 (value, buffer); + value = bfd_getb16 (buffer); + break; + case BYTE: + break; + default: + abort (); } } - ASSERT (output_section->owner == output_bfd); + ASSERT (output_section->owner == link_info.output_bfd); switch (statement->data_statement.type) { case QUAD: case SQUAD: if (sizeof (bfd_vma) >= QUAD_SIZE) - bfd_put_64 (output_bfd, value, link_order->u.data.contents); + bfd_put_64 (link_info.output_bfd, value, + link_order->u.data.contents); else { bfd_vma high; @@ -148,30 +118,34 @@ build_link_order (lang_statement_union_type *statement) high = 0; else high = (bfd_vma) -1; - bfd_put_32 (output_bfd, high, + bfd_put_32 (link_info.output_bfd, high, (link_order->u.data.contents - + (big_endian ? 0 : 4))); - bfd_put_32 (output_bfd, value, + + (link_info.big_endian ? 0 : 4))); + bfd_put_32 (link_info.output_bfd, value, (link_order->u.data.contents - + (big_endian ? 4 : 0))); + + (link_info.big_endian ? 4 : 0))); } link_order->size = QUAD_SIZE; break; case LONG: - bfd_put_32 (output_bfd, value, link_order->u.data.contents); + bfd_put_32 (link_info.output_bfd, value, + link_order->u.data.contents); link_order->size = LONG_SIZE; break; case SHORT: - bfd_put_16 (output_bfd, value, link_order->u.data.contents); + bfd_put_16 (link_info.output_bfd, value, + link_order->u.data.contents); link_order->size = SHORT_SIZE; break; case BYTE: - bfd_put_8 (output_bfd, value, link_order->u.data.contents); + bfd_put_8 (link_info.output_bfd, value, + link_order->u.data.contents); link_order->size = BYTE_SIZE; break; default: abort (); } + link_order->u.data.size = link_order->size; } break; @@ -184,16 +158,22 @@ build_link_order (lang_statement_union_type *statement) rs = &statement->reloc_statement; output_section = rs->output_section; - ASSERT (output_section->owner == output_bfd); + ASSERT (output_section->owner == link_info.output_bfd); - link_order = bfd_new_link_order (output_bfd, output_section); + if (!((output_section->flags & SEC_HAS_CONTENTS) != 0 + || ((output_section->flags & SEC_LOAD) != 0 + && (output_section->flags & SEC_THREAD_LOCAL)))) + break; + + link_order = bfd_new_link_order (link_info.output_bfd, output_section); if (link_order == NULL) - einfo (_("%P%F: bfd_new_link_order failed\n")); + einfo (_("%F%P: bfd_new_link_order failed\n")); - link_order->offset = rs->output_vma; + link_order->offset = rs->output_offset; link_order->size = bfd_get_reloc_size (rs->howto); - link_order->u.reloc.p = xmalloc (sizeof (struct bfd_link_order_reloc)); + link_order->u.reloc.p = (struct bfd_link_order_reloc *) + xmalloc (sizeof (struct bfd_link_order_reloc)); link_order->u.reloc.p->reloc = rs->reloc; link_order->u.reloc.p->addend = rs->addend_value; @@ -201,7 +181,7 @@ build_link_order (lang_statement_union_type *statement) if (rs->name == NULL) { link_order->type = bfd_section_reloc_link_order; - if (rs->section->owner == output_bfd) + if (rs->section->owner == link_info.output_bfd) link_order->u.reloc.p->u.section = rs->section; else { @@ -218,43 +198,48 @@ build_link_order (lang_statement_union_type *statement) break; case lang_input_section_enum: - /* Create a new link_order in the output section with this - attached */ - if (!statement->input_section.ifile->just_syms_flag - && (statement->input_section.section->flags & SEC_EXCLUDE) == 0) - { - asection *i = statement->input_section.section; - asection *output_section = i->output_section; + { + /* Create a new link_order in the output section with this + attached */ + asection *i = statement->input_section.section; - ASSERT (output_section->owner == output_bfd); + if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS + && (i->flags & SEC_EXCLUDE) == 0) + { + asection *output_section = i->output_section; + struct bfd_link_order *link_order; - if ((output_section->flags & SEC_HAS_CONTENTS) != 0 - || ((output_section->flags & SEC_LOAD) != 0 - && (output_section->flags & SEC_THREAD_LOCAL))) - { - struct bfd_link_order *link_order; + ASSERT (output_section->owner == link_info.output_bfd); - link_order = bfd_new_link_order (output_bfd, output_section); + if (!((output_section->flags & SEC_HAS_CONTENTS) != 0 + || ((output_section->flags & SEC_LOAD) != 0 + && (output_section->flags & SEC_THREAD_LOCAL)))) + break; - if (i->flags & SEC_NEVER_LOAD) - { - /* We've got a never load section inside one which - is going to be output, we'll change it into a - fill. */ - link_order->type = bfd_data_link_order; - link_order->u.data.contents = (unsigned char *) ""; - link_order->u.data.size = 1; - } - else - { - link_order->type = bfd_indirect_link_order; - link_order->u.indirect.section = i; - ASSERT (i->output_section == output_section); - } - link_order->size = i->size; - link_order->offset = i->output_offset; - } - } + link_order = bfd_new_link_order (link_info.output_bfd, + output_section); + if (link_order == NULL) + einfo (_("%F%P: bfd_new_link_order failed\n")); + + if ((i->flags & SEC_NEVER_LOAD) != 0 + && (i->flags & SEC_DEBUGGING) == 0) + { + /* We've got a never load section inside one which is + going to be output, we'll change it into a fill. */ + link_order->type = bfd_data_link_order; + link_order->u.data.contents = (unsigned char *) ""; + link_order->u.data.size = 1; + } + else + { + link_order->type = bfd_indirect_link_order; + link_order->u.indirect.section = i; + ASSERT (i->output_section == output_section); + } + link_order->size = i->size; + link_order->offset = i->output_offset; + } + } break; case lang_padding_statement_enum: @@ -265,16 +250,22 @@ build_link_order (lang_statement_union_type *statement) output_section = statement->padding_statement.output_section; ASSERT (statement->padding_statement.output_section->owner - == output_bfd); - if ((output_section->flags & SEC_HAS_CONTENTS) != 0) - { - link_order = bfd_new_link_order (output_bfd, output_section); - link_order->type = bfd_data_link_order; - link_order->size = statement->padding_statement.size; - link_order->offset = statement->padding_statement.output_offset; - link_order->u.data.contents = statement->padding_statement.fill->data; - link_order->u.data.size = statement->padding_statement.fill->size; - } + == link_info.output_bfd); + + if (!((output_section->flags & SEC_HAS_CONTENTS) != 0 + || ((output_section->flags & SEC_LOAD) != 0 + && (output_section->flags & SEC_THREAD_LOCAL)))) + break; + + link_order = bfd_new_link_order (link_info.output_bfd, + output_section); + if (link_order == NULL) + einfo (_("%F%P: bfd_new_link_order failed\n")); + link_order->type = bfd_data_link_order; + link_order->size = statement->padding_statement.size; + link_order->offset = statement->padding_statement.output_offset; + link_order->u.data.contents = statement->padding_statement.fill->data; + link_order->u.data.size = statement->padding_statement.fill->size; } break; @@ -290,7 +281,7 @@ build_link_order (lang_statement_union_type *statement) static bfd_boolean unsplittable_name (const char *name) { - if (strncmp (name, ".stab", 5) == 0) + if (CONST_STRNEQ (name, ".stab")) { /* There are several stab like string sections. We pattern match on ".stab...str" */ @@ -313,14 +304,14 @@ clone_section (bfd *abfd, asection *s, const char *name, int *count) { char *tname; char *sname; - unsigned int len; + unsigned int len; asection *n; struct bfd_link_hash_entry *h; /* Invent a section name from the section name and a dotted numeric suffix. */ len = strlen (name); - tname = xmalloc (len + 1); + tname = (char *) xmalloc (len + 1); memcpy (tname, name, len + 1); /* Remove a dotted number suffix, from a previous split link. */ while (len && ISDIGIT (tname[len-1])) @@ -335,7 +326,7 @@ clone_section (bfd *abfd, asection *s, const char *name, int *count) { /* Some section names cannot be truncated, as the name is used to locate some other section. */ - if (strncmp (name, ".stab", 5) == 0 + if (CONST_STRNEQ (name, ".stab") || strcmp (name, "$GDB_SYMBOLS$") == 0) { einfo (_ ("%F%P: cannot create split section name for %s\n"), name); @@ -344,7 +335,7 @@ clone_section (bfd *abfd, asection *s, const char *name, int *count) } tname[5] = 0; } - + if ((sname = bfd_get_unique_section_name (abfd, tname, count)) == NULL || (n = bfd_make_section_anyway (abfd, sname)) == NULL || (h = bfd_link_hash_lookup (link_info.hash, @@ -355,7 +346,7 @@ clone_section (bfd *abfd, asection *s, const char *name, int *count) return NULL; } free (tname); - + /* Set up section symbol. */ h->type = bfd_link_hash_defined; h->u.def.value = 0; @@ -371,6 +362,9 @@ clone_section (bfd *abfd, asection *s, const char *name, int *count) n->orelocation = 0; n->reloc_count = 0; n->alignment_power = s->alignment_power; + + bfd_copy_private_section_data (abfd, s, abfd, n); + return n; } @@ -378,18 +372,14 @@ clone_section (bfd *abfd, asection *s, const char *name, int *count) static void ds (asection *s) { - struct bfd_link_order *l = s->link_order_head; + struct bfd_link_order *l = s->map_head.link_order; printf ("vma %x size %x\n", s->vma, s->size); while (l) { if (l->type == bfd_indirect_link_order) - { - printf ("%8x %s\n", l->offset, l->u.indirect.section->owner->filename); - } + printf ("%8x %s\n", l->offset, l->u.indirect.section->owner->filename); else - { - printf (_("%8x something else\n"), l->offset); - } + printf (_("%8x something else\n"), l->offset); l = l->next; } printf ("\n"); @@ -410,7 +400,7 @@ sanity_check (bfd *abfd) { struct bfd_link_order *p; bfd_vma prev = 0; - for (p = s->link_order_head; p; p = p->next) + for (p = s->map_head.link_order; p; p = p->next) { if (p->offset > 100000) abort (); @@ -447,7 +437,7 @@ split_sections (bfd *abfd, struct bfd_link_info *info) /* Count up the relocations and line entries to see if anything would be too big to fit. Accumulate section size too. */ - for (l = NULL, p = cursor->link_order_head; p != NULL; p = l->next) + for (l = NULL, p = cursor->map_head.link_order; p != NULL; p = l->next) { unsigned int thislines = 0; unsigned int thisrelocs = 0; @@ -462,13 +452,13 @@ split_sections (bfd *abfd, struct bfd_link_info *info) || info->strip == strip_some) thislines = sec->lineno_count; - if (info->relocatable) + if (bfd_link_relocatable (info)) thisrelocs = sec->reloc_count; thissize = sec->size; } - else if (info->relocatable + else if (bfd_link_relocatable (info) && (p->type == bfd_section_reloc_link_order || p->type == bfd_symbol_reloc_link_order)) thisrelocs++; @@ -488,9 +478,9 @@ split_sections (bfd *abfd, struct bfd_link_info *info) /* Attach the link orders to the new section and snip them off from the old section. */ - n->link_order_head = p; - n->link_order_tail = cursor->link_order_tail; - cursor->link_order_tail = l; + n->map_head.link_order = p; + n->map_tail.link_order = cursor->map_tail.link_order; + cursor->map_tail.link_order = l; l->next = NULL; l = p; @@ -546,12 +536,13 @@ ldwrite (void) /* Reset error indicator, which can typically something like invalid format from opening up the .o files. */ bfd_set_error (bfd_error_no_error); + lang_clear_os_map (); lang_for_each_statement (build_link_order); if (config.split_by_reloc != (unsigned) -1 || config.split_by_file != (bfd_size_type) -1) - split_sections (output_bfd, &link_info); - if (!bfd_final_link (output_bfd, &link_info)) + split_sections (link_info.output_bfd, &link_info); + if (!bfd_final_link (link_info.output_bfd, &link_info)) { /* If there was an error recorded, print it out. Otherwise assume an appropriate error message like unknown symbol was printed