aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf64-x86-64.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/elf64-x86-64.c')
-rw-r--r--bfd/elf64-x86-64.c70
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;