X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf32-i386.c;h=6f4f7f47186ce5cef8078b44313c1d183755c2d6;hb=e822f2cda9bc484adb5f8860050640a5c6f1ced9;hp=e74da3af620b16769b3a413775d793abb962cceb;hpb=3b4c384407ebbdd9ed4ad5057080b3be038b8748;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index e74da3af62..6f4f7f4718 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -1,5 +1,5 @@ /* Intel 80386/80486-specific support for 32-bit ELF - Copyright (C) 1993-2018 Free Software Foundation, Inc. + Copyright (C) 1993-2020 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -194,7 +194,7 @@ static reloc_howto_type elf_howto_table[]= #endif static reloc_howto_type * -elf_i386_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, +elf_i386_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code) { switch (code) @@ -346,11 +346,13 @@ elf_i386_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, return &elf_howto_table[R_386_GNU_VTENTRY - R_386_vt_offset]; default: - break; + TRACE ("Unknown"); + /* xgettext:c-format */ + _bfd_error_handler (_("%pB: unsupported relocation type: %#x"), + abfd, (int) code); + bfd_set_error (bfd_error_bad_value); + return NULL; } - - TRACE ("Unknown"); - return 0; } static reloc_howto_type * @@ -368,7 +370,7 @@ elf_i386_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, } static reloc_howto_type * -elf_i386_rtype_to_howto (bfd *abfd, unsigned r_type) +elf_i386_rtype_to_howto (unsigned r_type) { unsigned int indx; @@ -379,25 +381,30 @@ elf_i386_rtype_to_howto (bfd *abfd, unsigned r_type) >= R_386_ext2 - R_386_ext) && ((indx = r_type - R_386_vt_offset) - R_386_ext2 >= R_386_vt - R_386_ext2)) - { - /* xgettext:c-format */ - _bfd_error_handler (_("%B: invalid relocation type %d"), - abfd, (int) r_type); - indx = R_386_NONE; - } + return NULL; /* PR 17512: file: 0f67f69d. */ if (elf_howto_table [indx].type != r_type) return NULL; return &elf_howto_table[indx]; } -static void -elf_i386_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, +static bfd_boolean +elf_i386_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst) { unsigned int r_type = ELF32_R_TYPE (dst->r_info); - cache_ptr->howto = elf_i386_rtype_to_howto (abfd, r_type); + + if ((cache_ptr->howto = elf_i386_rtype_to_howto (r_type)) == NULL) + { + /* xgettext:c-format */ + _bfd_error_handler (_("%pB: unsupported relocation type %#x"), + abfd, r_type); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + + return TRUE; } /* Return whether a symbol name implies a local label. The UnixWare @@ -759,6 +766,12 @@ static const struct elf_x86_lazy_plt_layout elf_i386_lazy_plt = sizeof (elf_i386_lazy_plt0_entry), /* plt0_entry_size */ elf_i386_lazy_plt_entry, /* plt_entry */ LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ + NULL, /* plt_tlsdesc_entry */ + 0, /* plt_tlsdesc_entry_size*/ + 0, /* plt_tlsdesc_got1_offset */ + 0, /* plt_tlsdesc_got2_offset */ + 0, /* plt_tlsdesc_got1_insn_end */ + 0, /* plt_tlsdesc_got2_insn_end */ 2, /* plt0_got1_offset */ 8, /* plt0_got2_offset */ 0, /* plt0_got2_insn_end */ @@ -791,6 +804,12 @@ static const struct elf_x86_lazy_plt_layout elf_i386_lazy_ibt_plt = sizeof (elf_i386_lazy_ibt_plt0_entry), /* plt0_entry_size */ elf_i386_lazy_ibt_plt_entry, /* plt_entry */ LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ + NULL, /* plt_tlsdesc_entry */ + 0, /* plt_tlsdesc_entry_size*/ + 0, /* plt_tlsdesc_got1_offset */ + 0, /* plt_tlsdesc_got2_offset */ + 0, /* plt_tlsdesc_got1_insn_end */ + 0, /* plt_tlsdesc_got2_insn_end */ 2, /* plt0_got1_offset */ 8, /* plt0_got2_offset */ 0, /* plt0_got2_insn_end */ @@ -824,14 +843,6 @@ static const struct elf_x86_non_lazy_plt_layout elf_i386_non_lazy_ibt_plt = #define PLTRESOLVE_RELOCS 2 #define PLT_NON_JUMP_SLOT_RELOCS 2 -/* These are the standard parameters. */ -static const struct elf_x86_backend_data elf_i386_arch_bed = - { - is_normal /* os */ - }; - -#define elf_backend_arch_data &elf_i386_arch_bed - /* Return TRUE if the TLS access code sequence support transition from R_TYPE. */ @@ -1132,8 +1143,8 @@ elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd, reloc_howto_type *from, *to; const char *name; - from = elf_i386_rtype_to_howto (abfd, from_type); - to = elf_i386_rtype_to_howto (abfd, to_type); + from = elf_i386_rtype_to_howto (from_type); + to = elf_i386_rtype_to_howto (to_type); if (h) name = h->root.root.string; @@ -1156,10 +1167,10 @@ elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd, _bfd_error_handler /* xgettext:c-format */ - (_("%B: TLS transition from %s to %s against `%s' at %#Lx " - "in section `%A' failed"), + (_("%pB: TLS transition from %s to %s against `%s'" + " at %#" PRIx64 " in section `%pA' failed"), abfd, from->name, to->name, name, - rel->r_offset, sec); + (uint64_t) rel->r_offset, sec); bfd_set_error (bfd_error_bad_value); return FALSE; } @@ -1207,6 +1218,7 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr, bfd_vma nop_offset; bfd_boolean is_pic; bfd_boolean to_reloc_32; + bfd_boolean abs_symbol; unsigned int r_type; unsigned int r_symndx; bfd_vma roff = irel->r_offset; @@ -1230,6 +1242,21 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr, modrm = bfd_get_8 (abfd, contents + roff - 1); baseless = (modrm & 0xc7) == 0x5; + if (h) + { + /* NB: Also set linker_def via SYMBOL_REFERENCES_LOCAL_P. */ + local_ref = SYMBOL_REFERENCES_LOCAL_P (link_info, h); + isym = NULL; + abs_symbol = ABS_SYMBOL_P (h); + } + else + { + local_ref = TRUE; + isym = bfd_sym_from_r_symndx (&htab->sym_cache, abfd, + r_symndx); + abs_symbol = isym->st_shndx == SHN_ABS; + } + if (baseless && is_pic) { /* For PIC, disallow R_386_GOT32X without a base register @@ -1237,17 +1264,13 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr, const char *name; if (h == NULL) - { - isym = bfd_sym_from_r_symndx (&htab->sym_cache, abfd, - r_symndx); - name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); - } + name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); else name = h->root.root.string; _bfd_error_handler /* xgettext:c-format */ - (_("%B: direct GOT relocation R_386_GOT32X against `%s' without base" + (_("%pB: direct GOT relocation R_386_GOT32X against `%s' without base" " register can not be used when making a shared object"), abfd, name); return FALSE; @@ -1275,9 +1298,6 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr, goto convert_load; } - /* NB: Also set linker_def via SYMBOL_REFERENCES_LOCAL_P. */ - local_ref = SYMBOL_REFERENCES_LOCAL_P (link_info, h); - /* Undefined weak symbol is only bound locally in executable and its reference is resolved as 0. */ if (h->root.type == bfd_link_hash_undefweak @@ -1308,7 +1328,7 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr, && local_ref) { /* The function is locally defined. */ -convert_branch: + convert_branch: /* Convert R_386_GOT32X to R_386_PC32. */ if (modrm == 0x15 || (modrm & 0xf8) == 0x90) { @@ -1324,8 +1344,8 @@ convert_branch: } else { - nop = link_info->call_nop_byte; - if (link_info->call_nop_as_suffix) + nop = htab->params->call_nop_byte; + if (htab->params->call_nop_as_suffix) { nop_offset = roff + 3; irel->r_offset -= 1; @@ -1374,9 +1394,12 @@ convert_branch: || h->root.type == bfd_link_hash_defweak) && local_ref)) { -convert_load: + convert_load: if (opcode == 0x8b) { + if (abs_symbol && local_ref) + to_reloc_32 = TRUE; + if (to_reloc_32) { /* Convert "mov foo@GOT[(%reg1)], %reg2" to @@ -1456,15 +1479,6 @@ elf_i386_check_relocs (bfd *abfd, if (bfd_link_relocatable (info)) return TRUE; - /* Don't do anything special with non-loaded, non-alloced sections. - In particular, any relocs in such sections should not affect GOT - and PLT reference counting (ie. we don't allow them to create GOT - or PLT entries), there's no possibility or desire to optimize TLS - relocs, and there's not much point in propagating relocs to shared - libs that the dynamic linker won't relocate. */ - if ((sec->flags & SEC_ALLOC) == 0) - return TRUE; - htab = elf_x86_hash_table (info, I386_ELF_DATA); if (htab == NULL) { @@ -1500,6 +1514,7 @@ elf_i386_check_relocs (bfd *abfd, Elf_Internal_Sym *isym; const char *name; bfd_boolean size_reloc; + bfd_boolean no_dynreloc; r_symndx = ELF32_R_SYM (rel->r_info); r_type = ELF32_R_TYPE (rel->r_info); @@ -1507,7 +1522,7 @@ elf_i386_check_relocs (bfd *abfd, if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr)) { /* xgettext:c-format */ - _bfd_error_handler (_("%B: bad symbol index: %d"), + _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd, r_symndx); goto error_return; } @@ -1556,10 +1571,6 @@ elf_i386_check_relocs (bfd *abfd, /* It is referenced by a non-shared object. */ h->ref_regular = 1; - - if (h->type == STT_GNU_IFUNC) - elf_tdata (info->output_bfd)->has_gnu_symbols - |= elf_gnu_symbol_ifunc; } if (r_type == R_386_GOT32X @@ -1572,6 +1583,10 @@ elf_i386_check_relocs (bfd *abfd, goto error_return; } + if (!_bfd_elf_x86_valid_reloc_p (sec, info, htab, rel, h, isym, + symtab_hdr, &no_dynreloc)) + return FALSE; + if (! elf_i386_tls_transition (info, abfd, sec, contents, symtab_hdr, sym_hashes, &r_type, GOT_UNKNOWN, @@ -1704,7 +1719,7 @@ elf_i386_check_relocs (bfd *abfd, NULL); _bfd_error_handler /* xgettext:c-format */ - (_("%B: `%s' accessed both as normal and " + (_("%pB: `%s' accessed both as normal and " "thread local symbol"), abfd, name); bfd_set_error (bfd_error_bad_value); @@ -1724,7 +1739,7 @@ elf_i386_check_relocs (bfd *abfd, case R_386_GOTOFF: case R_386_GOTPC: -create_got: + create_got: if (r_type != R_386_TLS_IE) { if (eh != NULL) @@ -1754,7 +1769,7 @@ create_got: case R_386_PC32: if (eh != NULL && (sec->flags & SEC_CODE) != 0) eh->zero_undefweak |= 0x2; -do_relocation: + do_relocation: /* We are called after all symbols have been resolved. Only relocation against STT_GNU_IFUNC symbol must go through PLT. */ @@ -1776,7 +1791,7 @@ do_relocation: { _bfd_error_handler /* xgettext:c-format */ - (_("%B: unsupported non-PIC call to IFUNC `%s'"), + (_("%pB: unsupported non-PIC call to IFUNC `%s'"), abfd, h->root.root.string); bfd_set_error (bfd_error_bad_value); goto error_return; @@ -1811,9 +1826,10 @@ do_relocation: } size_reloc = FALSE; -do_size: - if (NEED_DYNAMIC_RELOCATION_P (info, h, sec, r_type, - R_386_32)) + do_size: + if (!no_dynreloc + && NEED_DYNAMIC_RELOCATION_P (info, FALSE, h, sec, r_type, + R_386_32)) { struct elf_dyn_relocs *p; struct elf_dyn_relocs **head; @@ -1834,7 +1850,7 @@ do_size: relocations we need for this symbol. */ if (h != NULL) { - head = &eh->dyn_relocs; + head = &h->dyn_relocs; } else { @@ -1860,7 +1876,7 @@ do_size: p = *head; if (p == NULL || p->sec != sec) { - bfd_size_type amt = sizeof *p; + size_t amt = sizeof *p; p = (struct elf_dyn_relocs *) bfd_alloc (htab->elf.dynobj, amt); if (p == NULL) @@ -1889,9 +1905,7 @@ do_size: /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_386_GNU_VTENTRY: - BFD_ASSERT (h != NULL); - if (h != NULL - && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset)) goto error_return; break; @@ -1918,7 +1932,7 @@ do_size: return TRUE; -error_return: + error_return: if (elf_section_data (sec)->this_hdr.contents != contents) free (contents); sec->check_relocs_failed = 1; @@ -1935,7 +1949,7 @@ elf_i386_fake_sections (bfd *abfd ATTRIBUTE_UNUSED, { const char *name; - name = bfd_get_section_name (abfd, sec); + name = bfd_section_name (sec); /* This is an ugly, but unfortunately necessary hack that is needed when producing EFI binaries on x86. It tells @@ -2009,7 +2023,11 @@ elf_i386_relocate_section (bfd *output_bfd, if (htab == NULL) return FALSE; - BFD_ASSERT (is_x86_elf (input_bfd, htab)); + if (!is_x86_elf (input_bfd, htab)) + { + bfd_set_error (bfd_error_wrong_format); + return FALSE; + } symtab_hdr = &elf_symtab_hdr (input_bfd); sym_hashes = elf_sym_hashes (input_bfd); @@ -2017,7 +2035,7 @@ elf_i386_relocate_section (bfd *output_bfd, local_tlsdesc_gotents = elf_x86_local_tlsdesc_gotent (input_bfd); /* We have to handle relocations in vxworks .tls_vars sections specially, because the dynamic loader is 'weird'. */ - is_vxworks_tls = (htab->target_os == is_vxworks + is_vxworks_tls = (htab->elf.target_os == is_vxworks && bfd_link_pic (info) && !strcmp (input_section->output_section->name, ".tls_vars")); @@ -2057,15 +2075,10 @@ elf_i386_relocate_section (bfd *output_bfd, continue; } - if ((indx = r_type) >= R_386_standard - && ((indx = r_type - R_386_ext_offset) - R_386_standard - >= R_386_ext - R_386_standard) - && ((indx = r_type - R_386_tls_offset) - R_386_ext - >= R_386_ext2 - R_386_ext)) + howto = elf_i386_rtype_to_howto (r_type); + if (howto == NULL) return _bfd_unrecognized_reloc (input_bfd, input_section, r_type); - howto = elf_howto_table + indx; - r_symndx = ELF32_R_SYM (rel->r_info); h = NULL; sym = NULL; @@ -2178,7 +2191,7 @@ elf_i386_relocate_section (bfd *output_bfd, if (sec != NULL && discarded_section (sec)) { _bfd_clear_contents (howto, input_bfd, input_section, - contents + rel->r_offset); + contents, rel->r_offset); wrel->r_offset = rel->r_offset; wrel->r_info = 0; wrel->r_addend = 0; @@ -2214,6 +2227,10 @@ elf_i386_relocate_section (bfd *output_bfd, if ((input_section->flags & SEC_ALLOC) == 0) { + /* If this is a SHT_NOTE section without SHF_ALLOC, treat + STT_GNU_IFUNC symbol as STT_FUNC. */ + if (elf_section_type (input_section) == SHT_NOTE) + goto skip_ifunc; /* Dynamic relocs are not propagated for SEC_DEBUGGING sections because such sections are not SEC_ALLOC and thus ld.so will not process them. */ @@ -2346,7 +2363,7 @@ elf_i386_relocate_section (bfd *output_bfd, switch (r_type) { default: -bad_ifunc_reloc: + bad_ifunc_reloc: if (h->root.root.string) name = h->root.root.string; else @@ -2354,7 +2371,7 @@ bad_ifunc_reloc: NULL); _bfd_error_handler /* xgettext:c-format */ - (_("%B: relocation %s against STT_GNU_IFUNC " + (_("%pB: relocation %s against STT_GNU_IFUNC " "symbol `%s' isn't supported"), input_bfd, howto->name, name); bfd_set_error (bfd_error_bad_value); @@ -2370,7 +2387,7 @@ bad_ifunc_reloc: asection *sreloc; bfd_vma offset; -do_ifunc_pointer: + do_ifunc_pointer: /* Need a dynamic relocation to get the real function adddress. */ offset = _bfd_elf_section_offset (output_bfd, @@ -2387,7 +2404,7 @@ do_ifunc_pointer: if (POINTER_LOCAL_IFUNC_P (info, h)) { - info->callbacks->minfo (_("Local IFUNC function `%s' in %B\n"), + info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"), h->root.root.string, h->root.u.def.section->owner); @@ -2433,72 +2450,14 @@ do_ifunc_pointer: } } + skip_ifunc: resolved_to_zero = (eh != NULL && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh)); switch (r_type) { case R_386_GOT32X: - /* Avoid optimizing _DYNAMIC since ld.so may use its - link-time address. */ - if (h == htab->elf.hdynamic) - goto r_386_got32; - - if (bfd_link_pic (info)) - { - /* It is OK to convert mov to lea and convert indirect - branch to direct branch. It is OK to convert adc, - add, and, cmp, or, sbb, sub, test, xor only when PIC - is false. */ - unsigned int opcode, addend; - addend = bfd_get_32 (input_bfd, contents + rel->r_offset); - if (addend != 0) - goto r_386_got32; - opcode = bfd_get_8 (input_bfd, contents + rel->r_offset - 2); - if (opcode != 0x8b && opcode != 0xff) - goto r_386_got32; - } - - /* Resolve "mov GOT[(%reg)], %reg", - "call/jmp *GOT[(%reg)]", "test %reg, foo@GOT[(%reg)]" - and "binop foo@GOT[(%reg)], %reg". */ - if (h == NULL - || (h->plt.offset == (bfd_vma) -1 - && h->got.offset == (bfd_vma) -1) - || htab->elf.sgotplt == NULL) - abort (); - - offplt = (htab->elf.sgotplt->output_section->vma - + htab->elf.sgotplt->output_offset); - - /* It is relative to .got.plt section. */ - if (h->got.offset != (bfd_vma) -1) - /* Use GOT entry. Mask off the least significant bit in - GOT offset which may be set by R_386_GOT32 processing - below. */ - relocation = (htab->elf.sgot->output_section->vma - + htab->elf.sgot->output_offset - + (h->got.offset & ~1) - offplt); - else - /* Use GOTPLT entry. */ - relocation = (h->plt.offset / plt_entry_size - - htab->plt.has_plt0 + 3) * 4; - - if (!bfd_link_pic (info)) - { - /* If not PIC, add the .got.plt section address for - baseless addressing. */ - unsigned int modrm; - modrm = bfd_get_8 (input_bfd, contents + rel->r_offset - 1); - if ((modrm & 0xc7) == 0x5) - relocation += offplt; - } - - unresolved_reloc = FALSE; - break; - case R_386_GOT32: -r_386_got32: /* Relocation is to the entry for this symbol in the global offset table. */ if (htab->elf.sgot == NULL) @@ -2593,7 +2552,7 @@ r_386_got32: we don't know what the GOT base is. */ const char *name; -disallow_got32: + disallow_got32: if (h == NULL || h->root.root.string == NULL) name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, NULL); @@ -2602,7 +2561,7 @@ disallow_got32: _bfd_error_handler /* xgettext:c-format */ - (_("%B: direct GOT relocation %s against `%s'" + (_("%pB: direct GOT relocation %s against `%s'" " without base register can not be used" " when making a shared object"), input_bfd, howto->name, name); @@ -2652,7 +2611,7 @@ disallow_got32: _bfd_error_handler /* xgettext:c-format */ - (_("%B: relocation R_386_GOTOFF against undefined %s" + (_("%pB: relocation R_386_GOTOFF against undefined %s" " `%s' can not be used when making a shared object"), input_bfd, v, h->root.root.string); bfd_set_error (bfd_error_bad_value); @@ -2665,7 +2624,7 @@ disallow_got32: { _bfd_error_handler /* xgettext:c-format */ - (_("%B: relocation R_386_GOTOFF against protected %s" + (_("%pB: relocation R_386_GOTOFF against protected %s" " `%s' can not be used when making a shared object"), input_bfd, h->type == STT_FUNC ? "function" : "data", @@ -2746,7 +2705,7 @@ disallow_got32: || is_vxworks_tls) break; - if (GENERATE_DYNAMIC_RELOCATION_P (info, eh, r_type, + if (GENERATE_DYNAMIC_RELOCATION_P (info, eh, r_type, sec, FALSE, resolved_to_zero, (r_type == R_386_PC32))) { @@ -3442,21 +3401,21 @@ disallow_got32: { _bfd_error_handler /* xgettext:c-format */ - (_("%B(%A+%#Lx): unresolvable %s relocation against symbol `%s'"), + (_("%pB(%pA+%#" PRIx64 "): unresolvable %s relocation against symbol `%s'"), input_bfd, input_section, - rel->r_offset, + (uint64_t) rel->r_offset, howto->name, h->root.root.string); return FALSE; } -do_relocation: + do_relocation: r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents, rel->r_offset, relocation, 0); -check_relocation_error: + check_relocation_error: if (r != bfd_reloc_ok) { const char *name; @@ -3471,7 +3430,7 @@ check_relocation_error: if (name == NULL) return FALSE; if (*name == '\0') - name = bfd_section_name (input_bfd, sec); + name = bfd_section_name (sec); } if (r == bfd_reloc_overflow) @@ -3482,9 +3441,9 @@ check_relocation_error: { _bfd_error_handler /* xgettext:c-format */ - (_("%B(%A+%#Lx): reloc against `%s': error %d"), + (_("%pB(%pA+%#" PRIx64 "): reloc against `%s': error %d"), input_bfd, input_section, - rel->r_offset, name, (int) r); + (uint64_t) rel->r_offset, name, (int) r); return FALSE; } } @@ -3630,7 +3589,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, resolved_plt->contents + plt_offset + htab->plt.plt_got_offset); - if (htab->target_os == is_vxworks) + if (htab->elf.target_os == is_vxworks) { int s, k, reloc_index; @@ -3693,7 +3652,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, + got_offset); if (PLT_LOCAL_IFUNC_P (info, h)) { - info->callbacks->minfo (_("Local IFUNC function `%s' in %B\n"), + info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"), h->root.root.string, h->root.u.def.section->owner); @@ -3793,6 +3752,8 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, sym->st_value = 0; } + _bfd_x86_elf_link_fixup_ifunc_symbol (info, htab, h, sym); + /* Don't generate dynamic GOT relocation against undefined weak symbol in executable. */ if (h->got.offset != (bfd_vma) -1 @@ -3832,7 +3793,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, } if (SYMBOL_REFERENCES_LOCAL_P (info, h)) { - info->callbacks->minfo (_("Local IFUNC function `%s' in %B\n"), + info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"), h->root.root.string, h->root.u.def.section->owner); @@ -3888,7 +3849,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd, else { BFD_ASSERT((h->got.offset & 1) == 0); -do_glob_dat: + do_glob_dat: bfd_put_32 (output_bfd, (bfd_vma) 0, htab->elf.sgot->contents + h->got.offset); rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT); @@ -4046,7 +4007,7 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd, htab->elf.splt->contents + htab->lazy_plt->plt0_got2_offset); - if (htab->target_os == is_vxworks) + if (htab->elf.target_os == is_vxworks) { Elf_Internal_Rela rel; int num_plts = (htab->elf.splt->size @@ -4187,7 +4148,7 @@ elf_i386_get_synthetic_symtab (bfd *abfd, lazy_plt = NULL; non_lazy_ibt_plt = NULL; lazy_ibt_plt = NULL; - switch (get_elf_x86_backend_data (abfd)->target_os) + switch (get_elf_backend_data (abfd)->target_os) { case is_normal: case is_solaris: @@ -4201,6 +4162,8 @@ elf_i386_get_synthetic_symtab (bfd *abfd, case is_nacl: lazy_plt = &elf_i386_nacl_plt; break; + default: + abort (); } got_addr = 0; @@ -4347,7 +4310,7 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info) { struct elf_x86_init_table init_table; - switch (get_elf_x86_backend_data (info->output_bfd)->target_os) + switch (get_elf_backend_data (info->output_bfd)->target_os) { case is_normal: case is_solaris: @@ -4371,6 +4334,8 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info) init_table.lazy_ibt_plt = NULL; init_table.non_lazy_ibt_plt = NULL; break; + default: + abort (); } init_table.r_info = elf32_r_info; @@ -4423,6 +4388,8 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info) #define elf_backend_linux_prpsinfo32_ugid16 TRUE +#define elf32_bed elf32_i386_bed + #include "elf32-target.h" /* FreeBSD support. */ @@ -4438,10 +4405,11 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info) "FreeBSD" label in the ELF header. So we put this label on all executables and (for simplicity) also all other object files. */ -static void -elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info) +static bfd_boolean +elf_i386_fbsd_init_file_header (bfd *abfd, struct bfd_link_info *info) { - _bfd_elf_post_process_headers (abfd, info); + if (!_bfd_elf_init_file_header (abfd, info)) + return FALSE; #ifdef OLD_FREEBSD_ABI_LABEL { @@ -4450,10 +4418,11 @@ elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info) memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8); } #endif + return TRUE; } -#undef elf_backend_post_process_headers -#define elf_backend_post_process_headers elf_i386_fbsd_post_process_headers +#undef elf_backend_init_file_header +#define elf_backend_init_file_header elf_i386_fbsd_init_file_header #undef elf32_bed #define elf32_bed elf32_i386_fbsd_bed @@ -4461,6 +4430,8 @@ elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info) #include "elf32-target.h" +#undef elf_backend_init_file_header + /* Solaris 2. */ #undef TARGET_LITTLE_SYM @@ -4468,15 +4439,8 @@ elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info) #undef TARGET_LITTLE_NAME #define TARGET_LITTLE_NAME "elf32-i386-sol2" -static const struct elf_x86_backend_data elf_i386_solaris_arch_bed = - { - is_solaris /* os */ - }; - -#undef elf_backend_arch_data -#define elf_backend_arch_data &elf_i386_solaris_arch_bed - -#undef elf_backend_post_process_headers +#undef ELF_TARGET_OS +#define ELF_TARGET_OS is_solaris /* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE objects won't be recognized. */ @@ -4602,9 +4566,7 @@ elf32_iamcu_elf_object_p (bfd *abfd) #undef ELF_MACHINE_CODE #define ELF_MACHINE_CODE EM_IAMCU -#undef elf_backend_arch_data -#define elf_backend_arch_data &elf_i386_arch_bed - +#undef ELF_TARGET_OS #undef ELF_OSABI #undef elf32_bed @@ -4645,7 +4607,6 @@ elf32_iamcu_elf_object_p (bfd *abfd) #undef ELF_OSABI #undef elf_backend_want_plt_sym #define elf_backend_want_plt_sym 0 -#undef elf_backend_post_process_headers #undef elf_backend_static_tls_alignment /* NaCl uses substantially different PLT entries for the same effects. */ @@ -4732,7 +4693,7 @@ static const bfd_byte elf_i386_nacl_eh_frame_plt[] = || PLT_FDE_LENGTH != 36 \ || PLT_FDE_START_OFFSET != 4 + PLT_CIE_LENGTH + 8 \ || PLT_FDE_LEN_OFFSET != 4 + PLT_CIE_LENGTH + 12) -# error "Need elf_x86_backend_data parameters for eh_frame_plt offsets!" +# error "Need PLT_CIE_LENGTH parameters for eh_frame_plt offsets!" #endif PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */ 0, 0, 0, 0, /* CIE ID */ @@ -4771,6 +4732,12 @@ static const struct elf_x86_lazy_plt_layout elf_i386_nacl_plt = sizeof (elf_i386_nacl_plt0_entry), /* plt0_entry_size */ elf_i386_nacl_plt_entry, /* plt_entry */ NACL_PLT_ENTRY_SIZE, /* plt_entry_size */ + NULL, /* plt_tlsdesc_entry */ + 0, /* plt_tlsdesc_entry_size*/ + 0, /* plt_tlsdesc_got1_offset */ + 0, /* plt_tlsdesc_got2_offset */ + 0, /* plt_tlsdesc_got1_insn_end */ + 0, /* plt_tlsdesc_got2_insn_end */ 2, /* plt0_got1_offset */ 8, /* plt0_got2_offset */ 0, /* plt0_got2_insn_end */ @@ -4786,11 +4753,6 @@ static const struct elf_x86_lazy_plt_layout elf_i386_nacl_plt = sizeof (elf_i386_nacl_eh_frame_plt) /* eh_frame_plt_size */ }; -static const struct elf_x86_backend_data elf_i386_nacl_arch_bed = - { - is_nacl /* os */ - }; - static bfd_boolean elf32_i386_nacl_elf_object_p (bfd *abfd) { @@ -4799,15 +4761,15 @@ elf32_i386_nacl_elf_object_p (bfd *abfd) return TRUE; } -#undef elf_backend_arch_data -#define elf_backend_arch_data &elf_i386_nacl_arch_bed +#undef ELF_TARGET_OS +#define ELF_TARGET_OS is_nacl #undef elf_backend_object_p #define elf_backend_object_p elf32_i386_nacl_elf_object_p #undef elf_backend_modify_segment_map #define elf_backend_modify_segment_map nacl_modify_segment_map -#undef elf_backend_modify_program_headers -#define elf_backend_modify_program_headers nacl_modify_program_headers +#undef elf_backend_modify_headers +#define elf_backend_modify_headers nacl_modify_headers #undef elf_backend_final_write_processing #define elf_backend_final_write_processing nacl_final_write_processing @@ -4816,7 +4778,7 @@ elf32_i386_nacl_elf_object_p (bfd *abfd) /* Restore defaults. */ #undef elf_backend_object_p #undef elf_backend_modify_segment_map -#undef elf_backend_modify_program_headers +#undef elf_backend_modify_headers #undef elf_backend_final_write_processing /* VxWorks support. */ @@ -4831,13 +4793,8 @@ elf32_i386_nacl_elf_object_p (bfd *abfd) #undef elf_backend_plt_alignment #define elf_backend_plt_alignment 4 -static const struct elf_x86_backend_data elf_i386_vxworks_arch_bed = - { - is_vxworks /* os */ - }; - -#undef elf_backend_arch_data -#define elf_backend_arch_data &elf_i386_vxworks_arch_bed +#undef ELF_TARGET_OS +#define ELF_TARGET_OS is_vxworks #undef elf_backend_relocs_compatible #undef elf_backend_add_symbol_hook