/* X86-64 specific support for ELF
- Copyright (C) 2000-2022 Free Software Foundation, Inc.
+ Copyright (C) 2000-2023 Free Software Foundation, Inc.
Contributed by Jan Hubicka <jh@suse.cz>.
This file is part of BFD, the Binary File Descriptor library.
#include "elfxx-x86.h"
#include "dwarf2.h"
#include "libiberty.h"
+#include "sframe.h"
#include "opcode/i386.h"
special_function, name, partial_inplace, src_mask, dst_mask, pcrel_offset. */
static reloc_howto_type x86_64_elf_howto_table[] =
{
- HOWTO(R_X86_64_NONE, 0, 3, 0, false, 0, complain_overflow_dont,
+ HOWTO(R_X86_64_NONE, 0, 0, 0, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_X86_64_NONE", false, 0, 0x00000000,
false),
- HOWTO(R_X86_64_64, 0, 4, 64, false, 0, complain_overflow_dont,
+ HOWTO(R_X86_64_64, 0, 8, 64, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_X86_64_64", false, 0, MINUS_ONE,
false),
- HOWTO(R_X86_64_PC32, 0, 2, 32, true, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_PC32, 0, 4, 32, true, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_PC32", false, 0, 0xffffffff,
true),
- HOWTO(R_X86_64_GOT32, 0, 2, 32, false, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_GOT32, 0, 4, 32, false, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_GOT32", false, 0, 0xffffffff,
false),
- HOWTO(R_X86_64_PLT32, 0, 2, 32, true, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_PLT32, 0, 4, 32, true, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_PLT32", false, 0, 0xffffffff,
true),
- HOWTO(R_X86_64_COPY, 0, 2, 32, false, 0, complain_overflow_bitfield,
+ HOWTO(R_X86_64_COPY, 0, 4, 32, false, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_X86_64_COPY", false, 0, 0xffffffff,
false),
- HOWTO(R_X86_64_GLOB_DAT, 0, 4, 64, false, 0, complain_overflow_dont,
+ HOWTO(R_X86_64_GLOB_DAT, 0, 8, 64, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_X86_64_GLOB_DAT", false, 0, MINUS_ONE,
false),
- HOWTO(R_X86_64_JUMP_SLOT, 0, 4, 64, false, 0, complain_overflow_dont,
+ HOWTO(R_X86_64_JUMP_SLOT, 0, 8, 64, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_X86_64_JUMP_SLOT", false, 0, MINUS_ONE,
false),
- HOWTO(R_X86_64_RELATIVE, 0, 4, 64, false, 0, complain_overflow_dont,
+ HOWTO(R_X86_64_RELATIVE, 0, 8, 64, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_X86_64_RELATIVE", false, 0, MINUS_ONE,
false),
- HOWTO(R_X86_64_GOTPCREL, 0, 2, 32, true, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_GOTPCREL, 0, 4, 32, true, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_GOTPCREL", false, 0, 0xffffffff,
true),
- HOWTO(R_X86_64_32, 0, 2, 32, false, 0, complain_overflow_unsigned,
+ HOWTO(R_X86_64_32, 0, 4, 32, false, 0, complain_overflow_unsigned,
bfd_elf_generic_reloc, "R_X86_64_32", false, 0, 0xffffffff,
false),
- HOWTO(R_X86_64_32S, 0, 2, 32, false, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_32S, 0, 4, 32, false, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_32S", false, 0, 0xffffffff,
false),
- HOWTO(R_X86_64_16, 0, 1, 16, false, 0, complain_overflow_bitfield,
+ HOWTO(R_X86_64_16, 0, 2, 16, false, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_X86_64_16", false, 0, 0xffff, false),
- HOWTO(R_X86_64_PC16, 0, 1, 16, true, 0, complain_overflow_bitfield,
+ HOWTO(R_X86_64_PC16, 0, 2, 16, true, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_X86_64_PC16", false, 0, 0xffff, true),
- HOWTO(R_X86_64_8, 0, 0, 8, false, 0, complain_overflow_bitfield,
+ HOWTO(R_X86_64_8, 0, 1, 8, false, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_X86_64_8", false, 0, 0xff, false),
- HOWTO(R_X86_64_PC8, 0, 0, 8, true, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_PC8, 0, 1, 8, true, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_PC8", false, 0, 0xff, true),
- HOWTO(R_X86_64_DTPMOD64, 0, 4, 64, false, 0, complain_overflow_dont,
+ HOWTO(R_X86_64_DTPMOD64, 0, 8, 64, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_X86_64_DTPMOD64", false, 0, MINUS_ONE,
false),
- HOWTO(R_X86_64_DTPOFF64, 0, 4, 64, false, 0, complain_overflow_dont,
+ HOWTO(R_X86_64_DTPOFF64, 0, 8, 64, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_X86_64_DTPOFF64", false, 0, MINUS_ONE,
false),
- HOWTO(R_X86_64_TPOFF64, 0, 4, 64, false, 0, complain_overflow_dont,
+ HOWTO(R_X86_64_TPOFF64, 0, 8, 64, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_X86_64_TPOFF64", false, 0, MINUS_ONE,
false),
- HOWTO(R_X86_64_TLSGD, 0, 2, 32, true, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_TLSGD, 0, 4, 32, true, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_TLSGD", false, 0, 0xffffffff,
true),
- HOWTO(R_X86_64_TLSLD, 0, 2, 32, true, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_TLSLD, 0, 4, 32, true, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_TLSLD", false, 0, 0xffffffff,
true),
- HOWTO(R_X86_64_DTPOFF32, 0, 2, 32, false, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_DTPOFF32, 0, 4, 32, false, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_DTPOFF32", false, 0, 0xffffffff,
false),
- HOWTO(R_X86_64_GOTTPOFF, 0, 2, 32, true, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_GOTTPOFF, 0, 4, 32, true, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_GOTTPOFF", false, 0, 0xffffffff,
true),
- HOWTO(R_X86_64_TPOFF32, 0, 2, 32, false, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_TPOFF32, 0, 4, 32, false, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_TPOFF32", false, 0, 0xffffffff,
false),
- HOWTO(R_X86_64_PC64, 0, 4, 64, true, 0, complain_overflow_dont,
+ HOWTO(R_X86_64_PC64, 0, 8, 64, true, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_X86_64_PC64", false, 0, MINUS_ONE,
true),
- HOWTO(R_X86_64_GOTOFF64, 0, 4, 64, false, 0, complain_overflow_dont,
+ HOWTO(R_X86_64_GOTOFF64, 0, 8, 64, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_X86_64_GOTOFF64", false, 0, MINUS_ONE,
false),
- HOWTO(R_X86_64_GOTPC32, 0, 2, 32, true, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_GOTPC32, 0, 4, 32, true, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_GOTPC32", false, 0, 0xffffffff,
true),
- HOWTO(R_X86_64_GOT64, 0, 4, 64, false, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_GOT64, 0, 8, 64, false, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_GOT64", false, 0, MINUS_ONE,
false),
- HOWTO(R_X86_64_GOTPCREL64, 0, 4, 64, true, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_GOTPCREL64, 0, 8, 64, true, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_GOTPCREL64", false, 0, MINUS_ONE,
true),
- HOWTO(R_X86_64_GOTPC64, 0, 4, 64, true, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_GOTPC64, 0, 8, 64, true, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_GOTPC64", false, 0, MINUS_ONE,
true),
- HOWTO(R_X86_64_GOTPLT64, 0, 4, 64, false, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_GOTPLT64, 0, 8, 64, false, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_GOTPLT64", false, 0, MINUS_ONE,
false),
- HOWTO(R_X86_64_PLTOFF64, 0, 4, 64, false, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_PLTOFF64, 0, 8, 64, false, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_PLTOFF64", false, 0, MINUS_ONE,
false),
- HOWTO(R_X86_64_SIZE32, 0, 2, 32, false, 0, complain_overflow_unsigned,
+ HOWTO(R_X86_64_SIZE32, 0, 4, 32, false, 0, complain_overflow_unsigned,
bfd_elf_generic_reloc, "R_X86_64_SIZE32", false, 0, 0xffffffff,
false),
- HOWTO(R_X86_64_SIZE64, 0, 4, 64, false, 0, complain_overflow_dont,
+ HOWTO(R_X86_64_SIZE64, 0, 8, 64, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_X86_64_SIZE64", false, 0, MINUS_ONE,
false),
- HOWTO(R_X86_64_GOTPC32_TLSDESC, 0, 2, 32, true, 0,
+ HOWTO(R_X86_64_GOTPC32_TLSDESC, 0, 4, 32, true, 0,
complain_overflow_bitfield, bfd_elf_generic_reloc,
"R_X86_64_GOTPC32_TLSDESC", false, 0, 0xffffffff, true),
- HOWTO(R_X86_64_TLSDESC_CALL, 0, 3, 0, false, 0,
+ HOWTO(R_X86_64_TLSDESC_CALL, 0, 0, 0, false, 0,
complain_overflow_dont, bfd_elf_generic_reloc,
"R_X86_64_TLSDESC_CALL",
false, 0, 0, false),
- HOWTO(R_X86_64_TLSDESC, 0, 4, 64, false, 0,
+ HOWTO(R_X86_64_TLSDESC, 0, 8, 64, false, 0,
complain_overflow_dont, bfd_elf_generic_reloc,
"R_X86_64_TLSDESC", false, 0, MINUS_ONE, false),
- HOWTO(R_X86_64_IRELATIVE, 0, 4, 64, false, 0, complain_overflow_dont,
+ HOWTO(R_X86_64_IRELATIVE, 0, 8, 64, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_X86_64_IRELATIVE", false, 0, MINUS_ONE,
false),
- HOWTO(R_X86_64_RELATIVE64, 0, 4, 64, false, 0, complain_overflow_dont,
+ HOWTO(R_X86_64_RELATIVE64, 0, 8, 64, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_X86_64_RELATIVE64", false, 0, MINUS_ONE,
false),
- HOWTO(R_X86_64_PC32_BND, 0, 2, 32, true, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_PC32_BND, 0, 4, 32, true, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_PC32_BND", false, 0, 0xffffffff,
true),
- HOWTO(R_X86_64_PLT32_BND, 0, 2, 32, true, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_PLT32_BND, 0, 4, 32, true, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_PLT32_BND", false, 0, 0xffffffff,
true),
- HOWTO(R_X86_64_GOTPCRELX, 0, 2, 32, true, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_GOTPCRELX, 0, 4, 32, true, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_GOTPCRELX", false, 0, 0xffffffff,
true),
- HOWTO(R_X86_64_REX_GOTPCRELX, 0, 2, 32, true, 0, complain_overflow_signed,
+ HOWTO(R_X86_64_REX_GOTPCRELX, 0, 4, 32, true, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_X86_64_REX_GOTPCRELX", false, 0, 0xffffffff,
true),
#define R_X86_64_vt_offset (R_X86_64_GNU_VTINHERIT - R_X86_64_standard)
/* GNU extension to record C++ vtable hierarchy. */
- HOWTO (R_X86_64_GNU_VTINHERIT, 0, 4, 0, false, 0, complain_overflow_dont,
+ HOWTO (R_X86_64_GNU_VTINHERIT, 0, 8, 0, false, 0, complain_overflow_dont,
NULL, "R_X86_64_GNU_VTINHERIT", false, 0, 0, false),
/* GNU extension to record C++ vtable member usage. */
- HOWTO (R_X86_64_GNU_VTENTRY, 0, 4, 0, false, 0, complain_overflow_dont,
+ HOWTO (R_X86_64_GNU_VTENTRY, 0, 8, 0, false, 0, complain_overflow_dont,
_bfd_elf_rel_vtable_reloc_fn, "R_X86_64_GNU_VTENTRY", false, 0, 0,
false),
/* Use complain_overflow_bitfield on R_X86_64_32 for x32. */
- HOWTO(R_X86_64_32, 0, 2, 32, false, 0, complain_overflow_bitfield,
+ HOWTO(R_X86_64_32, 0, 4, 32, false, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_X86_64_32", false, 0, 0xffffffff,
false)
};
default:
return false;
- case 124: /* sizeof(struct elf_prpsinfo) on Linux/x32 */
+ case 124:
+ /* sizeof (struct elf_external_linux_prpsinfo32_ugid16). */
elf_tdata (abfd)->core->pid
= bfd_get_32 (abfd, note->descdata + 12);
elf_tdata (abfd)->core->program
= _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
break;
- case 136: /* sizeof(struct elf_prpsinfo) on Linux/x86_64 */
+ case 128:
+ /* sizeof (struct elf_external_linux_prpsinfo32_ugid32). */
+ elf_tdata (abfd)->core->pid
+ = bfd_get_32 (abfd, note->descdata + 12);
+ elf_tdata (abfd)->core->program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
+ elf_tdata (abfd)->core->command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
+ break;
+
+ case 136:
+ /* sizeof (struct elf_prpsinfo) on Linux/x86_64. */
elf_tdata (abfd)->core->pid
= bfd_get_32 (abfd, note->descdata + 24);
elf_tdata (abfd)->core->program
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 =
+{
+ 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 FRE covering the .plt section entry. */
+static const sframe_frame_row_entry elf_x86_64_sframe_plt0_fre2 =
+{
+ 6, /* SFrame FRE start address. */
+ {24, 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_pltn_fre1 =
+{
+ 0, /* SFrame FRE start address. */
+ {8, 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_pltn_fre2 =
+{
+ 11, /* 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 FRE covering the second .plt section entry. */
+static const sframe_frame_row_entry elf_x86_64_sframe_sec_pltn_fre1 =
+{
+ 0, /* SFrame FRE start address. */
+ {8, 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. Also used for IBT enabled PLT. */
+static const struct elf_x86_sframe_plt elf_x86_64_sframe_non_lazy_plt =
+{
+ LAZY_PLT_ENTRY_SIZE,
+ 2, /* Number of FREs for PLT0. */
+ /* Array of SFrame FREs for plt0. */
+ { &elf_x86_64_sframe_plt0_fre1, &elf_x86_64_sframe_plt0_fre2 },
+ 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 },
+ 0,
+ 0, /* There is no second PLT necessary. */
+ { &elf_x86_64_sframe_null_fre }
+};
+
+/* SFrame helper object for lazy PLT. Also used for IBT enabled PLT. */
+static const struct elf_x86_sframe_plt elf_x86_64_sframe_plt =
+{
+ LAZY_PLT_ENTRY_SIZE,
+ 2, /* Number of FREs for PLT0. */
+ /* Array of SFrame FREs for plt0. */
+ { &elf_x86_64_sframe_plt0_fre1, &elf_x86_64_sframe_plt0_fre2 },
+ LAZY_PLT_ENTRY_SIZE,
+ 2, /* Number of FREs for PLTn. */
+ /* Array of SFrame FREs for plt. */
+ { &elf_x86_64_sframe_pltn_fre1, &elf_x86_64_sframe_pltn_fre2 },
+ NON_LAZY_PLT_ENTRY_SIZE,
+ 1, /* Number of FREs for PLTn for second PLT. */
+ /* FREs for second plt (stack trace info for .plt.got is
+ identical). Used when IBT or non-lazy PLT is in effect. */
+ { &elf_x86_64_sframe_sec_pltn_fre1 }
+};
+
/* These are the standard parameters. */
static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_plt =
{
sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
};
-
static bool
elf64_x86_64_elf_object_p (bfd *abfd)
{
if (largepic)
return r_type == R_X86_64_PLTOFF64;
else if (indirect_call)
- return r_type == R_X86_64_GOTPCRELX;
+ return (r_type == R_X86_64_GOTPCRELX || r_type == R_X86_64_GOTPCREL);
else
return (r_type == R_X86_64_PC32 || r_type == R_X86_64_PLT32);
}
break;
case R_X86_64_PLT32:
- case R_X86_64_PLT32_BND:
/* This symbol requires a procedure linkage table entry. We
actually build the entry in adjust_dynamic_symbol,
because this might be a case of linking PIC code which is
case R_X86_64_PC8:
case R_X86_64_PC16:
case R_X86_64_PC32:
- case R_X86_64_PC32_BND:
case R_X86_64_PC64:
case R_X86_64_64:
pointer:
}
}
}
- else if (r_type != R_X86_64_PC32_BND
- && r_type != R_X86_64_PC64)
+ else if (r_type != R_X86_64_PC64)
{
/* At run-time, R_X86_64_64 can be resolved for both
x86-64 and x32. But R_X86_64_32 and R_X86_64_32S
&& (r_type == R_X86_64_32
|| r_type == R_X86_64_32S))))
func_pointer_ref = true;
- else
+
+ /* IFUNC symbol needs pointer equality in PDE so that
+ function pointer reference will be resolved to its
+ PLT entry directly. */
+ if (!func_pointer_ref
+ || (bfd_link_pde (info)
+ && h->type == STT_GNU_IFUNC))
h->pointer_equality_needed = 1;
}
|| (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
h->plt.refcount = 1;
- if (h->pointer_equality_needed
+ if (htab->elf.target_os != is_solaris
+ && h->pointer_equality_needed
&& h->type == STT_FUNC
&& eh->def_protected
- && elf_has_indirect_extern_access (h->root.u.def.section->owner))
+ && !SYMBOL_DEFINED_NON_SHARED_P (h)
+ && h->def_dynamic)
{
/* Disallow non-canonical reference to canonical
protected function. */
}
/* FALLTHROUGH */
case R_X86_64_PC32:
- case R_X86_64_PC32_BND:
case R_X86_64_PC64:
case R_X86_64_PLT32:
- case R_X86_64_PLT32_BND:
goto do_relocation;
}
}
break;
case R_X86_64_PLT32:
- case R_X86_64_PLT32_BND:
/* Relocation is to the entry for this symbol in the
procedure linkage table. */
case R_X86_64_PC8:
case R_X86_64_PC16:
case R_X86_64_PC32:
- case R_X86_64_PC32_BND:
/* Don't complain about -fPIC if the symbol is undefined when
building executable unless it is unresolved weak symbol,
references a dynamic definition in PIE or -z nocopyreloc
|| (h != NULL
&& !h->root.linker_def
&& !h->root.ldscript_def
- && eh->def_protected
- && elf_has_no_copy_on_protected (h->root.u.def.section->owner)));
+ && eh->def_protected));
if ((input_section->flags & SEC_ALLOC) != 0
&& (input_section->flags & SEC_READONLY) != 0
{
case R_X86_64_32S:
sec = h->root.u.def.section;
- if ((info->nocopyreloc
- || (eh->def_protected
- && elf_has_no_copy_on_protected (h->root.u.def.section->owner)))
+ if ((info->nocopyreloc || eh->def_protected)
&& !(h->root.u.def.section->flags & SEC_CODE))
return elf_x86_64_need_pic (info, input_bfd, input_section,
h, NULL, NULL, howto);
const struct elf_x86_non_lazy_plt_layout *non_lazy_bnd_plt;
const struct elf_x86_lazy_plt_layout *lazy_ibt_plt;
const struct elf_x86_non_lazy_plt_layout *non_lazy_ibt_plt;
+ const struct elf_x86_lazy_plt_layout *x32_lazy_ibt_plt;
+ const struct elf_x86_non_lazy_plt_layout *x32_non_lazy_ibt_plt;
asection *plt;
enum elf_x86_plt_type plt_type;
struct elf_x86_plt plts[] =
{
lazy_ibt_plt = &elf_x86_64_lazy_ibt_plt;
non_lazy_ibt_plt = &elf_x86_64_non_lazy_ibt_plt;
+ x32_lazy_ibt_plt = &elf_x32_lazy_ibt_plt;
+ x32_non_lazy_ibt_plt = &elf_x32_non_lazy_ibt_plt;
}
else
{
lazy_ibt_plt = &elf_x32_lazy_ibt_plt;
non_lazy_ibt_plt = &elf_x32_non_lazy_ibt_plt;
+ x32_lazy_ibt_plt = NULL;
+ x32_non_lazy_ibt_plt = NULL;
}
count = 0;
for (j = 0; plts[j].name != NULL; j++)
{
plt = bfd_get_section_by_name (abfd, plts[j].name);
- if (plt == NULL || plt->size == 0)
+ if (plt == NULL
+ || plt->size == 0
+ || (plt->flags & SEC_HAS_CONTENTS) == 0)
continue;
/* Get the PLT section contents. */
lazy_plt->plt0_got1_offset) == 0)
&& (memcmp (plt_contents + 6, lazy_plt->plt0_entry + 6,
2) == 0))
- plt_type = plt_lazy;
+ {
+ if (x32_lazy_ibt_plt != NULL
+ && (memcmp (plt_contents
+ + x32_lazy_ibt_plt->plt_entry_size,
+ x32_lazy_ibt_plt->plt_entry,
+ x32_lazy_ibt_plt->plt_got_offset) == 0))
+ {
+ /* The fist entry in the x32 lazy IBT PLT is the same
+ as the lazy PLT. */
+ plt_type = plt_lazy | plt_second;
+ lazy_plt = x32_lazy_ibt_plt;
+ }
+ else
+ plt_type = plt_lazy;
+ }
else if (lazy_bnd_plt != NULL
&& (memcmp (plt_contents, lazy_bnd_plt->plt0_entry,
lazy_bnd_plt->plt0_got1_offset) == 0)
plt_type = plt_second;
non_lazy_plt = non_lazy_ibt_plt;
}
+ else if (x32_non_lazy_ibt_plt != NULL
+ && plt->size >= x32_non_lazy_ibt_plt->plt_entry_size
+ && (memcmp (plt_contents,
+ x32_non_lazy_ibt_plt->plt_entry,
+ x32_non_lazy_ibt_plt->plt_got_offset) == 0))
+ {
+ /* Match x32 IBT PLT. */
+ plt_type = plt_second;
+ non_lazy_plt = x32_non_lazy_ibt_plt;
+ }
}
if (plt_type == plt_unknown)
htab = elf_x86_hash_table (info, bed->target_id);
if (!htab)
abort ();
- if (htab->params->bndplt)
- {
- init_table.lazy_plt = &elf_x86_64_lazy_bnd_plt;
- init_table.non_lazy_plt = &elf_x86_64_non_lazy_bnd_plt;
- }
- else
- {
- init_table.lazy_plt = &elf_x86_64_lazy_plt;
- init_table.non_lazy_plt = &elf_x86_64_non_lazy_plt;
- }
+
+ init_table.lazy_plt = &elf_x86_64_lazy_plt;
+ init_table.non_lazy_plt = &elf_x86_64_non_lazy_plt;
+
+ init_table.lazy_ibt_plt = &elf_x32_lazy_ibt_plt;
+ init_table.non_lazy_ibt_plt = &elf_x32_non_lazy_ibt_plt;
if (ABI_64_P (info->output_bfd))
{
- init_table.lazy_ibt_plt = &elf_x86_64_lazy_ibt_plt;
- init_table.non_lazy_ibt_plt = &elf_x86_64_non_lazy_ibt_plt;
+ init_table.sframe_lazy_plt = &elf_x86_64_sframe_plt;
+ init_table.sframe_non_lazy_plt = &elf_x86_64_sframe_non_lazy_plt;
+ init_table.sframe_lazy_ibt_plt = &elf_x86_64_sframe_plt;
+ init_table.sframe_non_lazy_ibt_plt = &elf_x86_64_sframe_non_lazy_plt;
}
else
{
- init_table.lazy_ibt_plt = &elf_x32_lazy_ibt_plt;
- init_table.non_lazy_ibt_plt = &elf_x32_non_lazy_ibt_plt;
+ /* SFrame is not supported for non AMD64. */
+ init_table.sframe_lazy_plt = NULL;
+ init_table.sframe_non_lazy_plt = NULL;
}
if (ABI_64_P (info->output_bfd))
#define ELF_ARCH bfd_arch_i386
#define ELF_TARGET_ID X86_64_ELF_DATA
#define ELF_MACHINE_CODE EM_X86_64
-#if DEFAULT_LD_Z_SEPARATE_CODE
-# define ELF_MAXPAGESIZE 0x1000
-#else
-# define ELF_MAXPAGESIZE 0x200000
-#endif
+#define ELF_MAXPAGESIZE 0x1000
#define ELF_COMMONPAGESIZE 0x1000
#define elf_backend_can_gc_sections 1
#define elf_backend_got_header_size (GOT_ENTRY_SIZE*3)
#define elf_backend_rela_normal 1
#define elf_backend_plt_alignment 4
-#define elf_backend_extern_protected_data 1
#define elf_backend_caches_rawsize 1
#define elf_backend_dtrel_excludes_plt 1
#define elf_backend_want_dynrelro 1