X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Flinker.c;h=d8703179e5b10d8374388c1ee2b07cd8eabe7d01;hb=0c0adcc52478ebb707ed780173e18262df6eab7e;hp=21e0c9304aa7c3473f6e1ecc95c641fc46cb5dab;hpb=d00dd7dc5e415503de88614bf2ea4aafa2bca819;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/linker.c b/bfd/linker.c index 21e0c9304a..d8703179e5 100644 --- a/bfd/linker.c +++ b/bfd/linker.c @@ -1,5 +1,5 @@ /* linker.c -- BFD linker routines - Copyright (C) 1993-2018 Free Software Foundation, Inc. + Copyright (C) 1993-2020 Free Software Foundation, Inc. Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support This file is part of BFD, the Binary File Descriptor library. @@ -484,7 +484,20 @@ _bfd_link_hash_table_init /* Look up a symbol in a link hash table. If follow is TRUE, we follow bfd_link_hash_indirect and bfd_link_hash_warning links to - the real symbol. */ + the real symbol. + +.{* Return TRUE if the symbol described by a linker hash entry H +. is going to be absolute. Linker-script defined symbols can be +. converted from absolute to section-relative ones late in the +. link. Use this macro to correctly determine whether the symbol +. will actually end up absolute in output. *} +.#define bfd_is_abs_symbol(H) \ +. (((H)->type == bfd_link_hash_defined \ +. || (H)->type == bfd_link_hash_defweak) \ +. && bfd_is_abs_section ((H)->u.def.section) \ +. && !(H)->rel_from_abs) +. +*/ struct bfd_link_hash_entry * bfd_link_hash_lookup (struct bfd_link_hash_table *table, @@ -495,6 +508,9 @@ bfd_link_hash_lookup (struct bfd_link_hash_table *table, { struct bfd_link_hash_entry *ret; + if (table == NULL || string == NULL) + return NULL; + ret = ((struct bfd_link_hash_entry *) bfd_hash_lookup (&table->table, string, create, copy)); @@ -794,14 +810,13 @@ bfd_generic_link_read_symbols (bfd *abfd) symsize = bfd_get_symtab_upper_bound (abfd); if (symsize < 0) return FALSE; - bfd_get_outsymbols (abfd) = (struct bfd_symbol **) bfd_alloc (abfd, - symsize); + abfd->outsymbols = bfd_alloc (abfd, symsize); if (bfd_get_outsymbols (abfd) == NULL && symsize != 0) return FALSE; symcount = bfd_canonicalize_symtab (abfd, bfd_get_outsymbols (abfd)); if (symcount < 0) return FALSE; - bfd_get_symcount (abfd) = symcount; + abfd->symcount = symcount; } return TRUE; @@ -941,6 +956,9 @@ _bfd_generic_link_add_archive_symbols continue; } + if (arsym->name == NULL) + goto error_return; + h = bfd_link_hash_lookup (info->hash, arsym->name, FALSE, FALSE, TRUE); @@ -1145,9 +1163,9 @@ generic_link_add_symbol_list (bfd *abfd, | BSF_GLOBAL | BSF_CONSTRUCTOR | BSF_WEAK)) != 0 - || bfd_is_und_section (bfd_get_section (p)) - || bfd_is_com_section (bfd_get_section (p)) - || bfd_is_ind_section (bfd_get_section (p))) + || bfd_is_und_section (bfd_asymbol_section (p)) + || bfd_is_com_section (bfd_asymbol_section (p)) + || bfd_is_ind_section (bfd_asymbol_section (p))) { const char *name; const char *string; @@ -1173,7 +1191,7 @@ generic_link_add_symbol_list (bfd *abfd, bh = NULL; if (! (_bfd_generic_link_add_one_symbol - (info, abfd, name, p->flags, bfd_get_section (p), + (info, abfd, name, p->flags, bfd_asymbol_section (p), p->value, string, FALSE, FALSE, &bh))) return FALSE; h = (struct generic_link_hash_entry *) bh; @@ -1200,15 +1218,15 @@ generic_link_add_symbol_list (bfd *abfd, if (info->output_bfd->xvec == abfd->xvec) { if (h->sym == NULL - || (! bfd_is_und_section (bfd_get_section (p)) - && (! bfd_is_com_section (bfd_get_section (p)) - || bfd_is_und_section (bfd_get_section (h->sym))))) + || (! bfd_is_und_section (bfd_asymbol_section (p)) + && (! bfd_is_com_section (bfd_asymbol_section (p)) + || bfd_is_und_section (bfd_asymbol_section (h->sym))))) { h->sym = p; /* BSF_OLD_COMMON is a hack to support COFF reloc reading, and it should go away when the COFF linker is switched to the new version. */ - if (bfd_is_com_section (bfd_get_section (p))) + if (bfd_is_com_section (bfd_asymbol_section (p))) p->flags |= BSF_OLD_COMMON; } } @@ -1407,7 +1425,7 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, && name[1] == '_' && strcmp (name + (name[2] == '_'), "__gnu_lto_slim") == 0) _bfd_error_handler - (_("%B: plugin needed to handle lto object"), abfd); + (_("%pB: plugin needed to handle lto object"), abfd); } else row = DEF_ROW; @@ -1675,7 +1693,7 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: indirect symbol `%s' to `%s' is a loop"), + (_("%pB: indirect symbol `%s' to `%s' is a loop"), abfd, name, string); bfd_set_error (bfd_error_invalid_operation); return FALSE; @@ -1805,8 +1823,8 @@ _bfd_generic_final_link (bfd *abfd, struct bfd_link_info *info) size_t outsymalloc; struct generic_write_global_symbol_info wginfo; - bfd_get_outsymbols (abfd) = NULL; - bfd_get_symcount (abfd) = 0; + abfd->outsymbols = NULL; + abfd->symcount = 0; outsymalloc = 0; /* Mark all sections which will be included in the output file. */ @@ -1939,12 +1957,12 @@ generic_add_output_symbol (bfd *output_bfd, size_t *psymalloc, asymbol *sym) newsyms = (asymbol **) bfd_realloc (bfd_get_outsymbols (output_bfd), amt); if (newsyms == NULL) return FALSE; - bfd_get_outsymbols (output_bfd) = newsyms; + output_bfd->outsymbols = newsyms; } - bfd_get_outsymbols (output_bfd) [bfd_get_symcount (output_bfd)] = sym; + output_bfd->outsymbols[output_bfd->symcount] = sym; if (sym != NULL) - ++ bfd_get_symcount (output_bfd); + ++output_bfd->symcount; return TRUE; } @@ -2008,9 +2026,9 @@ _bfd_generic_link_output_symbols (bfd *output_bfd, | BSF_GLOBAL | BSF_CONSTRUCTOR | BSF_WEAK)) != 0 - || bfd_is_und_section (bfd_get_section (sym)) - || bfd_is_com_section (bfd_get_section (sym)) - || bfd_is_ind_section (bfd_get_section (sym))) + || bfd_is_und_section (bfd_asymbol_section (sym)) + || bfd_is_com_section (bfd_asymbol_section (sym)) + || bfd_is_ind_section (bfd_asymbol_section (sym))) { if (sym->udata.p != NULL) h = (struct generic_link_hash_entry *) sym->udata.p; @@ -2026,7 +2044,7 @@ _bfd_generic_link_output_symbols (bfd *output_bfd, the relocs in the output format being used. */ h = NULL; } - else if (bfd_is_und_section (bfd_get_section (sym))) + else if (bfd_is_und_section (bfd_asymbol_section (sym))) h = ((struct generic_link_hash_entry *) bfd_wrapped_link_hash_lookup (output_bfd, info, bfd_asymbol_name (sym), @@ -2093,12 +2111,11 @@ _bfd_generic_link_output_symbols (bfd *output_bfd, } } - /* This switch is straight from the old code in - write_file_locals in ldsym.c. */ - if (info->strip == strip_all - || (info->strip == strip_some - && bfd_hash_lookup (info->keep_hash, bfd_asymbol_name (sym), - FALSE, FALSE) == NULL)) + if ((sym->flags & BSF_KEEP) == 0 + && (info->strip == strip_all + || (info->strip == strip_some + && bfd_hash_lookup (info->keep_hash, bfd_asymbol_name (sym), + FALSE, FALSE) == NULL))) output = FALSE; else if ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0) { @@ -2112,6 +2129,8 @@ _bfd_generic_link_output_symbols (bfd *output_bfd, else output = FALSE; } + else if ((sym->flags & BSF_KEEP) != 0) + output = TRUE; else if (bfd_is_ind_section (sym->section)) output = FALSE; else if ((sym->flags & BSF_DEBUGGING) != 0) @@ -2377,13 +2396,13 @@ _bfd_generic_reloc_link_order (bfd *abfd, (*info->callbacks->reloc_overflow) (info, NULL, (link_order->type == bfd_section_reloc_link_order - ? bfd_section_name (abfd, link_order->u.reloc.p->u.section) + ? bfd_section_name (link_order->u.reloc.p->u.section) : link_order->u.reloc.p->u.name), r->howto->name, link_order->u.reloc.p->addend, NULL, NULL, 0); break; } - loc = link_order->offset * bfd_octets_per_byte (abfd); + loc = link_order->offset * bfd_octets_per_byte (abfd, sec); ok = bfd_set_section_contents (abfd, sec, buf, loc, size); free (buf); if (! ok) @@ -2450,7 +2469,7 @@ _bfd_default_link_order (bfd *abfd, static bfd_boolean default_data_link_order (bfd *abfd, - struct bfd_link_info *info ATTRIBUTE_UNUSED, + struct bfd_link_info *info, asection *sec, struct bfd_link_order *link_order) { @@ -2470,7 +2489,7 @@ default_data_link_order (bfd *abfd, fill_size = link_order->u.data.size; if (fill_size == 0) { - fill = abfd->arch_info->fill (size, bfd_big_endian (abfd), + fill = abfd->arch_info->fill (size, info->big_endian, (sec->flags & SEC_CODE) != 0); if (fill == NULL) return FALSE; @@ -2499,7 +2518,7 @@ default_data_link_order (bfd *abfd, } } - loc = link_order->offset * bfd_octets_per_byte (abfd); + loc = link_order->offset * bfd_octets_per_byte (abfd, sec); result = bfd_set_section_contents (abfd, sec, fill, loc, size); if (fill != link_order->u.data.contents) @@ -2545,7 +2564,7 @@ default_indirect_link_order (bfd *output_bfd, difficult, and sometimes impossible. */ _bfd_error_handler /* xgettext:c-format */ - (_("Attempt to do relocatable link with %s input and %s output"), + (_("attempt to do relocatable link with %s input and %s output"), bfd_get_target (input_bfd), bfd_get_target (output_bfd)); bfd_set_error (bfd_error_wrong_format); return FALSE; @@ -2582,15 +2601,15 @@ default_indirect_link_order (bfd *output_bfd, | BSF_GLOBAL | BSF_CONSTRUCTOR | BSF_WEAK)) != 0 - || bfd_is_und_section (bfd_get_section (sym)) - || bfd_is_com_section (bfd_get_section (sym)) - || bfd_is_ind_section (bfd_get_section (sym))) + || bfd_is_und_section (bfd_asymbol_section (sym)) + || bfd_is_com_section (bfd_asymbol_section (sym)) + || bfd_is_ind_section (bfd_asymbol_section (sym))) { /* sym->udata may have been set by generic_link_add_symbol_list. */ if (sym->udata.p != NULL) h = (struct bfd_link_hash_entry *) sym->udata.p; - else if (bfd_is_und_section (bfd_get_section (sym))) + else if (bfd_is_und_section (bfd_asymbol_section (sym))) h = bfd_wrapped_link_hash_lookup (output_bfd, info, bfd_asymbol_name (sym), FALSE, FALSE, TRUE); @@ -2636,7 +2655,8 @@ default_indirect_link_order (bfd *output_bfd, } /* Output the section contents. */ - loc = input_section->output_offset * bfd_octets_per_byte (output_bfd); + loc = (input_section->output_offset + * bfd_octets_per_byte (output_bfd, output_section)); if (! bfd_set_section_contents (output_bfd, output_section, new_contents, loc, input_section->size)) goto error_return; @@ -2831,7 +2851,7 @@ _bfd_handle_already_linked (asection *sec, case SEC_LINK_DUPLICATES_ONE_ONLY: info->callbacks->einfo /* xgettext:c-format */ - (_("%B: ignoring duplicate section `%A'\n"), + (_("%pB: ignoring duplicate section `%pA'\n"), sec->owner, sec); break; @@ -2841,7 +2861,7 @@ _bfd_handle_already_linked (asection *sec, else if (sec->size != l->sec->size) info->callbacks->einfo /* xgettext:c-format */ - (_("%B: duplicate section `%A' has different size\n"), + (_("%pB: duplicate section `%pA' has different size\n"), sec->owner, sec); break; @@ -2851,7 +2871,7 @@ _bfd_handle_already_linked (asection *sec, else if (sec->size != l->sec->size) info->callbacks->einfo /* xgettext:c-format */ - (_("%B: duplicate section `%A' has different size\n"), + (_("%pB: duplicate section `%pA' has different size\n"), sec->owner, sec); else if (sec->size != 0) { @@ -2860,18 +2880,18 @@ _bfd_handle_already_linked (asection *sec, if (!bfd_malloc_and_get_section (sec->owner, sec, &sec_contents)) info->callbacks->einfo /* xgettext:c-format */ - (_("%B: could not read contents of section `%A'\n"), + (_("%pB: could not read contents of section `%pA'\n"), sec->owner, sec); else if (!bfd_malloc_and_get_section (l->sec->owner, l->sec, &l_sec_contents)) info->callbacks->einfo /* xgettext:c-format */ - (_("%B: could not read contents of section `%A'\n"), + (_("%pB: could not read contents of section `%pA'\n"), l->sec->owner, l->sec); else if (memcmp (sec_contents, l_sec_contents, sec->size) != 0) info->callbacks->einfo /* xgettext:c-format */ - (_("%B: duplicate section `%A' has different contents\n"), + (_("%pB: duplicate section `%pA' has different contents\n"), sec->owner, sec); if (sec_contents) @@ -2923,7 +2943,7 @@ _bfd_generic_section_already_linked (bfd *abfd ATTRIBUTE_UNUSED, into a single large link once section, which defeats the purpose of having link once sections in the first place. */ - name = bfd_get_section_name (abfd, sec); + name = bfd_section_name (sec); already_linked_list = bfd_section_already_linked_table_lookup (name); @@ -3080,7 +3100,7 @@ bfd_generic_define_common_symbol (bfd *output_bfd, /* Increase the size of the section to align the common symbol. The alignment must be a power of two. */ - alignment = bfd_octets_per_byte (output_bfd) << power_of_two; + alignment = bfd_octets_per_byte (output_bfd, section) << power_of_two; BFD_ASSERT (alignment != 0 && (alignment & -alignment) == alignment); section->size += alignment - 1; section->size &= -alignment; @@ -3100,10 +3120,36 @@ bfd_generic_define_common_symbol (bfd *output_bfd, /* Make sure the section is allocated in memory, and make sure that it is no longer a common section. */ section->flags |= SEC_ALLOC; - section->flags &= ~SEC_IS_COMMON; + section->flags &= ~(SEC_IS_COMMON | SEC_HAS_CONTENTS); return TRUE; } +/* +FUNCTION + _bfd_generic_link_hide_symbol + +SYNOPSIS + void _bfd_generic_link_hide_symbol + (bfd *output_bfd, struct bfd_link_info *info, + struct bfd_link_hash_entry *h); + +DESCRIPTION + Hide symbol @var{h}. + This is an internal function. It should not be called from + outside the BFD library. + +.#define bfd_link_hide_symbol(output_bfd, info, h) \ +. BFD_SEND (output_bfd, _bfd_link_hide_symbol, (output_bfd, info, h)) +. +*/ + +void +_bfd_generic_link_hide_symbol (bfd *output_bfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED) +{ +} + /* FUNCTION bfd_generic_define_start_stop @@ -3359,10 +3405,10 @@ _bfd_generic_verify_endian_match (bfd *ibfd, struct bfd_link_info *info) && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN) { if (bfd_big_endian (ibfd)) - _bfd_error_handler (_("%B: compiled for a big endian system " + _bfd_error_handler (_("%pB: compiled for a big endian system " "and target is little endian"), ibfd); else - _bfd_error_handler (_("%B: compiled for a little endian system " + _bfd_error_handler (_("%pB: compiled for a little endian system " "and target is big endian"), ibfd); bfd_set_error (bfd_error_wrong_format); return FALSE; @@ -3415,6 +3461,13 @@ _bfd_nolink_bfd_is_group_section (bfd *abfd, return _bfd_bool_bfd_false_error (abfd); } +const char * +_bfd_nolink_bfd_group_name (bfd *abfd, + const asection *sec ATTRIBUTE_UNUSED) +{ + return _bfd_ptr_bfd_null_error (abfd); +} + bfd_boolean _bfd_nolink_bfd_discard_group (bfd *abfd, asection *sec ATTRIBUTE_UNUSED) {