diff options
Diffstat (limited to 'bfd/elf64-x86-64.c')
-rw-r--r-- | bfd/elf64-x86-64.c | 70 |
1 files changed, 40 insertions, 30 deletions
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 1e08f2e..b6f97b5 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -868,13 +868,6 @@ static const bfd_byte elf_x86_64_eh_frame_non_lazy_plt[] = DW_CFA_nop, DW_CFA_nop, DW_CFA_nop }; -static const sframe_frame_row_entry elf_x86_64_sframe_null_fre = -{ - 0, - {16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */ - SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */ -}; - /* .sframe FRE covering the .plt section entry. */ static const sframe_frame_row_entry elf_x86_64_sframe_plt0_fre1 = { @@ -923,6 +916,14 @@ static const sframe_frame_row_entry elf_x86_64_sframe_sec_pltn_fre1 = SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */ }; +/* .sframe FRE covering the .plt.got section entry. */ +static const sframe_frame_row_entry elf_x86_64_sframe_pltgot_fre1 = +{ + 0, /* SFrame FRE start address. */ + {16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */ + SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */ +}; + /* SFrame helper object for non-lazy PLT. */ static const struct elf_x86_sframe_plt elf_x86_64_sframe_non_lazy_plt = { @@ -933,14 +934,14 @@ static const struct elf_x86_sframe_plt elf_x86_64_sframe_non_lazy_plt = LAZY_PLT_ENTRY_SIZE, 1, /* Number of FREs for PLTn. */ /* Array of SFrame FREs for plt. */ - { &elf_x86_64_sframe_sec_pltn_fre1, &elf_x86_64_sframe_null_fre }, + { &elf_x86_64_sframe_sec_pltn_fre1 }, 0, 0, /* There is no second PLT necessary. */ - { &elf_x86_64_sframe_null_fre }, + { }, NON_LAZY_PLT_ENTRY_SIZE, 1, /* Number of FREs for PLT GOT. */ /* Array of SFrame FREs for PLT GOT. */ - { &elf_x86_64_sframe_null_fre }, + { &elf_x86_64_sframe_pltgot_fre1 }, }; /* SFrame helper object for non-lazy IBT enabled PLT. */ @@ -953,14 +954,14 @@ static const struct elf_x86_sframe_plt elf_x86_64_sframe_non_lazy_ibt_plt = LAZY_PLT_ENTRY_SIZE, 1, /* Number of FREs for PLTn. */ /* Array of SFrame FREs for plt. */ - { &elf_x86_64_sframe_sec_pltn_fre1, &elf_x86_64_sframe_null_fre }, + { &elf_x86_64_sframe_sec_pltn_fre1 }, 0, 0, /* There is no second PLT necessary. */ - { &elf_x86_64_sframe_null_fre }, + { }, LAZY_PLT_ENTRY_SIZE, 1, /* Number of FREs for PLT GOT. */ /* Array of SFrame FREs for PLT GOT. */ - { &elf_x86_64_sframe_null_fre }, + { &elf_x86_64_sframe_pltgot_fre1 }, }; /* SFrame helper object for lazy PLT. */ @@ -981,7 +982,7 @@ static const struct elf_x86_sframe_plt elf_x86_64_sframe_plt = NON_LAZY_PLT_ENTRY_SIZE, 1, /* Number of FREs for PLT GOT. */ /* Array of SFrame FREs for PLT GOT. */ - { &elf_x86_64_sframe_null_fre }, + { &elf_x86_64_sframe_pltgot_fre1 }, }; /* SFrame helper object for lazy PLT with IBT. */ @@ -1002,7 +1003,7 @@ static const struct elf_x86_sframe_plt elf_x86_64_sframe_ibt_plt = LAZY_PLT_ENTRY_SIZE, 1, /* Number of FREs for PLT GOT. */ /* Array of SFrame FREs for PLT GOT. */ - { &elf_x86_64_sframe_null_fre }, + { &elf_x86_64_sframe_pltgot_fre1 }, }; /* These are the standard parameters. */ @@ -2552,7 +2553,13 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info, } howto = elf_x86_64_rtype_to_howto (abfd, r_type); - if (rel->r_offset + bfd_get_reloc_size (howto) > sec->size) + if (howto == NULL) + { + _bfd_error_handler (_("%pB: unsupported relocation type %#x"), + abfd, r_type); + goto error_return; + } + if (!bfd_reloc_offset_in_range (howto, abfd, sec, rel->r_offset)) { /* xgettext:c-format */ _bfd_error_handler @@ -3261,10 +3268,14 @@ elf_x86_64_relocate_section (bfd *output_bfd, wrel->r_addend = 0; /* For ld -r, remove relocations in debug sections against - sections defined in discarded sections. Not done for - eh_frame editing code expects to be present. */ + sections defined in discarded sections, including sframe + sections. Not done for eh_frame editing code expects to + be present. NB: Since sframe code keeps R_X86_64_NONE + reloc as is, its r_offset is wrong, we must not generate + R_X86_64_NONE reloc in sframe section. */ if (bfd_link_relocatable (info) - && (input_section->flags & SEC_DEBUGGING)) + && ((input_section->flags & SEC_DEBUGGING) != 0 + || elf_section_type (input_section) == SHT_GNU_SFRAME)) wrel--; continue; @@ -5088,14 +5099,6 @@ elf_x86_64_relocate_section (bfd *output_bfd, rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section); rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted; - if (rel_hdr->sh_size == 0) - { - /* It is too late to remove an empty reloc section. Leave - one NONE reloc. - ??? What is wrong with an empty section??? */ - rel_hdr->sh_size = rel_hdr->sh_entsize; - deleted -= 1; - } rel_hdr = _bfd_elf_single_rel_hdr (input_section); rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted; input_section->reloc_count -= deleted; @@ -5241,6 +5244,9 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, + got_offset); if (PLT_LOCAL_IFUNC_P (info, h)) { + if (h->root.u.def.section == NULL) + return false; + info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"), h->root.root.string, h->root.u.def.section->owner); @@ -5409,6 +5415,9 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, } if (SYMBOL_REFERENCES_LOCAL_P (info, h)) { + if (h->root.u.def.section == NULL) + return false; + info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"), h->root.root.string, h->root.u.def.section->owner); @@ -6123,13 +6132,14 @@ elf_x86_64_fake_sections (bfd *abfd ATTRIBUTE_UNUSED, static bool elf_x86_64_copy_private_section_data (bfd *ibfd, asection *isec, - bfd *obfd, asection *osec) + bfd *obfd, asection *osec, + struct bfd_link_info *link_info) { - if (!_bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec)) + if (!_bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec, link_info)) return false; /* objcopy --set-section-flags without "large" drops SHF_X86_64_LARGE. */ - if (ibfd != obfd) + if (link_info == NULL && ibfd != obfd) elf_section_flags (osec) &= ~SHF_X86_64_LARGE; return true; |