Compare commits
5 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86b0f88b28 | ||
|
|
75094e5df5 | ||
|
|
e1c965554e | ||
|
|
c76e72c911 | ||
|
|
580d2a5659 |
5 changed files with 786 additions and 2 deletions
662
binutils-Intel-APX-CODE_6_GOTTPOFF.patch
Normal file
662
binutils-Intel-APX-CODE_6_GOTTPOFF.patch
Normal file
|
|
@ -0,0 +1,662 @@
|
|||
diff -rup binutils.orig/bfd/bfd-in2.h binutils-2.41/bfd/bfd-in2.h
|
||||
--- binutils.orig/bfd/bfd-in2.h 2024-04-05 10:34:23.956241281 +0100
|
||||
+++ binutils-2.41/bfd/bfd-in2.h 2024-04-05 10:59:44.555106927 +0100
|
||||
@@ -3840,6 +3840,12 @@ instruction. */
|
||||
BFD_RELOC_X86_64_CODE_4_GOTPCRELX,
|
||||
BFD_RELOC_X86_64_CODE_4_GOTTPOFF,
|
||||
BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC,
|
||||
+ BFD_RELOC_X86_64_CODE_5_GOTPCRELX,
|
||||
+ BFD_RELOC_X86_64_CODE_5_GOTTPOFF,
|
||||
+ BFD_RELOC_X86_64_CODE_5_GOTPC32_TLSDESC,
|
||||
+ BFD_RELOC_X86_64_CODE_6_GOTPCRELX,
|
||||
+ BFD_RELOC_X86_64_CODE_6_GOTTPOFF,
|
||||
+ BFD_RELOC_X86_64_CODE_6_GOTPC32_TLSDESC,
|
||||
|
||||
/* ns32k relocations */
|
||||
BFD_RELOC_NS32K_IMM_8,
|
||||
diff -rup binutils.orig/bfd/elf64-x86-64.c binutils-2.41/bfd/elf64-x86-64.c
|
||||
--- binutils.orig/bfd/elf64-x86-64.c 2024-04-05 10:34:23.956241281 +0100
|
||||
+++ binutils-2.41/bfd/elf64-x86-64.c 2024-04-05 10:59:44.557106930 +0100
|
||||
@@ -179,12 +179,30 @@ static reloc_howto_type x86_64_elf_howto
|
||||
HOWTO(R_X86_64_CODE_4_GOTPC32_TLSDESC, 0, 4, 32, true, 0,
|
||||
complain_overflow_bitfield, bfd_elf_generic_reloc,
|
||||
"R_X86_64_CODE_4_GOTPC32_TLSDESC", false, 0, 0xffffffff, true),
|
||||
+ HOWTO(R_X86_64_CODE_5_GOTPCRELX, 0, 4, 32, true, 0,
|
||||
+ complain_overflow_signed, bfd_elf_generic_reloc,
|
||||
+ "R_X86_64_CODE_5_GOTPCRELX", false, 0, 0xffffffff, true),
|
||||
+ HOWTO(R_X86_64_CODE_5_GOTTPOFF, 0, 4, 32, true, 0,
|
||||
+ complain_overflow_signed, bfd_elf_generic_reloc,
|
||||
+ "R_X86_64_CODE_5_GOTTPOFF", false, 0, 0xffffffff, true),
|
||||
+ HOWTO(R_X86_64_CODE_5_GOTPC32_TLSDESC, 0, 4, 32, true, 0,
|
||||
+ complain_overflow_bitfield, bfd_elf_generic_reloc,
|
||||
+ "R_X86_64_CODE_5_GOTPC32_TLSDESC", false, 0, 0xffffffff, true),
|
||||
+ HOWTO(R_X86_64_CODE_6_GOTPCRELX, 0, 4, 32, true, 0,
|
||||
+ complain_overflow_signed, bfd_elf_generic_reloc,
|
||||
+ "R_X86_64_CODE_6_GOTPCRELX", false, 0, 0xffffffff, true),
|
||||
+ HOWTO(R_X86_64_CODE_6_GOTTPOFF, 0, 4, 32, true, 0,
|
||||
+ complain_overflow_signed, bfd_elf_generic_reloc,
|
||||
+ "R_X86_64_CODE_6_GOTTPOFF", false, 0, 0xffffffff, true),
|
||||
+ HOWTO(R_X86_64_CODE_6_GOTPC32_TLSDESC, 0, 4, 32, true, 0,
|
||||
+ complain_overflow_bitfield, bfd_elf_generic_reloc,
|
||||
+ "R_X86_64_CODE_6_GOTPC32_TLSDESC", false, 0, 0xffffffff, true),
|
||||
|
||||
/* We have a gap in the reloc numbers here.
|
||||
R_X86_64_standard counts the number up to this point, and
|
||||
R_X86_64_vt_offset is the value to subtract from a reloc type of
|
||||
R_X86_64_GNU_VT* to form an index into this table. */
|
||||
-#define R_X86_64_standard (R_X86_64_CODE_4_GOTPC32_TLSDESC + 1)
|
||||
+#define R_X86_64_standard (R_X86_64_CODE_6_GOTPC32_TLSDESC + 1)
|
||||
#define R_X86_64_vt_offset (R_X86_64_GNU_VTINHERIT - R_X86_64_standard)
|
||||
|
||||
/* GNU extension to record C++ vtable hierarchy. */
|
||||
@@ -256,6 +274,12 @@ static const struct elf_reloc_map x86_64
|
||||
{ BFD_RELOC_X86_64_CODE_4_GOTPCRELX, R_X86_64_CODE_4_GOTPCRELX, },
|
||||
{ BFD_RELOC_X86_64_CODE_4_GOTTPOFF, R_X86_64_CODE_4_GOTTPOFF, },
|
||||
{ BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC, R_X86_64_CODE_4_GOTPC32_TLSDESC, },
|
||||
+ { BFD_RELOC_X86_64_CODE_5_GOTPCRELX, R_X86_64_CODE_5_GOTPCRELX, },
|
||||
+ { BFD_RELOC_X86_64_CODE_5_GOTTPOFF, R_X86_64_CODE_5_GOTTPOFF, },
|
||||
+ { BFD_RELOC_X86_64_CODE_5_GOTPC32_TLSDESC, R_X86_64_CODE_5_GOTPC32_TLSDESC, },
|
||||
+ { BFD_RELOC_X86_64_CODE_6_GOTPCRELX, R_X86_64_CODE_6_GOTPCRELX, },
|
||||
+ { BFD_RELOC_X86_64_CODE_6_GOTTPOFF, R_X86_64_CODE_6_GOTTPOFF, },
|
||||
+ { BFD_RELOC_X86_64_CODE_6_GOTPC32_TLSDESC, R_X86_64_CODE_6_GOTPC32_TLSDESC, },
|
||||
{ BFD_RELOC_VTABLE_INHERIT, R_X86_64_GNU_VTINHERIT, },
|
||||
{ BFD_RELOC_VTABLE_ENTRY, R_X86_64_GNU_VTENTRY, },
|
||||
};
|
||||
@@ -1283,6 +1307,23 @@ elf_x86_64_check_tls_transition (bfd *ab
|
||||
|
||||
goto check_gottpoff;
|
||||
|
||||
+ case R_X86_64_CODE_6_GOTTPOFF:
|
||||
+ /* Check transition from IE access model:
|
||||
+ add %reg1, foo@gottpoff(%rip), %reg2
|
||||
+ where reg1/reg2 are one of r16 to r31. */
|
||||
+
|
||||
+ if (offset < 6
|
||||
+ || (offset + 4) > sec->size
|
||||
+ || contents[offset - 6] != 0x62)
|
||||
+ return false;
|
||||
+
|
||||
+ val = bfd_get_8 (abfd, contents + offset - 2);
|
||||
+ if (val != 0x01 && val != 0x03)
|
||||
+ return false;
|
||||
+
|
||||
+ val = bfd_get_8 (abfd, contents + offset - 1);
|
||||
+ return (val & 0xc7) == 5;
|
||||
+
|
||||
case R_X86_64_GOTTPOFF:
|
||||
/* Check transition from IE access model:
|
||||
mov foo@gottpoff(%rip), %reg
|
||||
@@ -1417,6 +1458,7 @@ elf_x86_64_tls_transition (struct bfd_li
|
||||
case R_X86_64_GOTTPOFF:
|
||||
case R_X86_64_CODE_4_GOTPC32_TLSDESC:
|
||||
case R_X86_64_CODE_4_GOTTPOFF:
|
||||
+ case R_X86_64_CODE_6_GOTTPOFF:
|
||||
if (bfd_link_executable (info))
|
||||
{
|
||||
if (h == NULL)
|
||||
@@ -1464,6 +1506,8 @@ elf_x86_64_tls_transition (struct bfd_li
|
||||
/* Return TRUE if there is no transition. */
|
||||
if (from_type == to_type
|
||||
|| (from_type == R_X86_64_CODE_4_GOTTPOFF
|
||||
+ && to_type == R_X86_64_GOTTPOFF)
|
||||
+ || (from_type == R_X86_64_CODE_6_GOTTPOFF
|
||||
&& to_type == R_X86_64_GOTTPOFF))
|
||||
return true;
|
||||
|
||||
@@ -2177,6 +2221,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struc
|
||||
|
||||
case R_X86_64_GOTTPOFF:
|
||||
case R_X86_64_CODE_4_GOTTPOFF:
|
||||
+ case R_X86_64_CODE_6_GOTTPOFF:
|
||||
if (!bfd_link_executable (info))
|
||||
info->flags |= DF_STATIC_TLS;
|
||||
/* Fall through */
|
||||
@@ -2214,6 +2259,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struc
|
||||
break;
|
||||
case R_X86_64_GOTTPOFF:
|
||||
case R_X86_64_CODE_4_GOTTPOFF:
|
||||
+ case R_X86_64_CODE_6_GOTTPOFF:
|
||||
tls_type = GOT_TLS_IE;
|
||||
break;
|
||||
case R_X86_64_GOTPC32_TLSDESC:
|
||||
@@ -2503,6 +2549,26 @@ elf_x86_64_scan_relocs (bfd *abfd, struc
|
||||
}
|
||||
break;
|
||||
|
||||
+ case R_X86_64_CODE_5_GOTPCRELX:
|
||||
+ case R_X86_64_CODE_5_GOTTPOFF:
|
||||
+ case R_X86_64_CODE_5_GOTPC32_TLSDESC:
|
||||
+ case R_X86_64_CODE_6_GOTPCRELX:
|
||||
+ case R_X86_64_CODE_6_GOTPC32_TLSDESC:
|
||||
+ {
|
||||
+ /* These relocations are added only for completeness and
|
||||
+ aren't be used. */
|
||||
+ if (h)
|
||||
+ name = h->root.root.string;
|
||||
+ else
|
||||
+ name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
|
||||
+ NULL);
|
||||
+ _bfd_error_handler
|
||||
+ /* xgettext:c-format */
|
||||
+ (_("%pB: unsupported relocation %s against symbol `%s'"),
|
||||
+ abfd, x86_64_elf_howto_table[r_type].name, name);
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
/* This relocation describes the C++ object vtable hierarchy.
|
||||
Reconstruct it for later use during GC. */
|
||||
case R_X86_64_GNU_VTINHERIT:
|
||||
@@ -3570,6 +3636,7 @@ elf_x86_64_relocate_section (bfd *output
|
||||
case R_X86_64_TLSDESC_CALL:
|
||||
case R_X86_64_GOTTPOFF:
|
||||
case R_X86_64_CODE_4_GOTTPOFF:
|
||||
+ case R_X86_64_CODE_6_GOTTPOFF:
|
||||
tls_type = GOT_UNKNOWN;
|
||||
if (h == NULL && local_got_offsets)
|
||||
tls_type = elf_x86_local_got_tls_type (input_bfd) [r_symndx];
|
||||
@@ -3915,6 +3982,50 @@ elf_x86_64_relocate_section (bfd *output
|
||||
contents + roff - 2);
|
||||
bfd_put_8 (output_bfd, 0xc0 | reg,
|
||||
contents + roff - 1);
|
||||
+ bfd_put_32 (output_bfd,
|
||||
+ elf_x86_64_tpoff (info, relocation),
|
||||
+ contents + roff);
|
||||
+ continue;
|
||||
+ }
|
||||
+ else if (r_type == R_X86_64_CODE_6_GOTTPOFF)
|
||||
+ {
|
||||
+ /* IE->LE transition:
|
||||
+ Originally it is
|
||||
+ add %reg1, foo@gottpoff(%rip), %reg2
|
||||
+ or
|
||||
+ add foo@gottpoff(%rip), %reg1, %reg2
|
||||
+ We change it into:
|
||||
+ add $foo@tpoff, %reg1, %reg2
|
||||
+ */
|
||||
+ unsigned int reg, byte1;
|
||||
+ unsigned int updated_byte1;
|
||||
+
|
||||
+ if (roff < 6)
|
||||
+ goto corrupt_input;
|
||||
+
|
||||
+ /* Move the R bits to the B bits in EVEX payload
|
||||
+ byte 1. */
|
||||
+ byte1 = bfd_get_8 (input_bfd, contents + roff - 5);
|
||||
+ updated_byte1 = byte1;
|
||||
+
|
||||
+ /* Set the R bits since they is inverted. */
|
||||
+ updated_byte1 |= 1 << 7 | 1 << 4;
|
||||
+
|
||||
+ /* Update the B bits from the R bits. */
|
||||
+ if ((byte1 & (1 << 7)) == 0)
|
||||
+ updated_byte1 &= ~(1 << 5);
|
||||
+ if ((byte1 & (1 << 4)) == 0)
|
||||
+ updated_byte1 |= 1 << 3;
|
||||
+
|
||||
+ reg = bfd_get_8 (input_bfd, contents + roff - 1);
|
||||
+ reg >>= 3;
|
||||
+
|
||||
+ bfd_put_8 (output_bfd, updated_byte1,
|
||||
+ contents + roff - 5);
|
||||
+ bfd_put_8 (output_bfd, 0x81,
|
||||
+ contents + roff - 2);
|
||||
+ bfd_put_8 (output_bfd, 0xc0 | reg,
|
||||
+ contents + roff - 1);
|
||||
bfd_put_32 (output_bfd,
|
||||
elf_x86_64_tpoff (info, relocation),
|
||||
contents + roff);
|
||||
diff -rup binutils.orig/bfd/libbfd.h binutils-2.41/bfd/libbfd.h
|
||||
--- binutils.orig/bfd/libbfd.h 2024-04-05 10:34:23.956241281 +0100
|
||||
+++ binutils-2.41/bfd/libbfd.h 2024-04-05 10:59:44.559106933 +0100
|
||||
@@ -1470,6 +1470,12 @@ static const char *const bfd_reloc_code_
|
||||
"BFD_RELOC_X86_64_CODE_4_GOTPCRELX",
|
||||
"BFD_RELOC_X86_64_CODE_4_GOTTPOFF",
|
||||
"BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC",
|
||||
+ "BFD_RELOC_X86_64_CODE_5_GOTPCRELX",
|
||||
+ "BFD_RELOC_X86_64_CODE_5_GOTTPOFF",
|
||||
+ "BFD_RELOC_X86_64_CODE_5_GOTPC32_TLSDESC",
|
||||
+ "BFD_RELOC_X86_64_CODE_6_GOTPCRELX",
|
||||
+ "BFD_RELOC_X86_64_CODE_6_GOTTPOFF",
|
||||
+ "BFD_RELOC_X86_64_CODE_6_GOTPC32_TLSDESC",
|
||||
"BFD_RELOC_NS32K_IMM_8",
|
||||
"BFD_RELOC_NS32K_IMM_16",
|
||||
"BFD_RELOC_NS32K_IMM_32",
|
||||
diff -rup binutils.orig/bfd/reloc.c binutils-2.41/bfd/reloc.c
|
||||
--- binutils.orig/bfd/reloc.c 2024-04-05 10:34:23.956241281 +0100
|
||||
+++ binutils-2.41/bfd/reloc.c 2024-04-05 10:59:44.561106936 +0100
|
||||
@@ -2487,6 +2487,18 @@ ENUMX
|
||||
BFD_RELOC_X86_64_CODE_4_GOTTPOFF
|
||||
ENUMX
|
||||
BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC
|
||||
+ENUMX
|
||||
+ BFD_RELOC_X86_64_CODE_5_GOTPCRELX
|
||||
+ENUMX
|
||||
+ BFD_RELOC_X86_64_CODE_5_GOTTPOFF
|
||||
+ENUMX
|
||||
+ BFD_RELOC_X86_64_CODE_5_GOTPC32_TLSDESC
|
||||
+ENUMX
|
||||
+ BFD_RELOC_X86_64_CODE_6_GOTPCRELX
|
||||
+ENUMX
|
||||
+ BFD_RELOC_X86_64_CODE_6_GOTTPOFF
|
||||
+ENUMX
|
||||
+ BFD_RELOC_X86_64_CODE_6_GOTPC32_TLSDESC
|
||||
ENUMDOC
|
||||
x86-64/elf relocations
|
||||
|
||||
diff -rup binutils.orig/elfcpp/x86_64.h binutils-2.41/elfcpp/x86_64.h
|
||||
--- binutils.orig/elfcpp/x86_64.h 2024-04-05 10:34:23.969241295 +0100
|
||||
+++ binutils-2.41/elfcpp/x86_64.h 2024-04-05 10:59:44.561106936 +0100
|
||||
@@ -110,6 +110,30 @@ enum
|
||||
// descriptor in GOT if the
|
||||
// instruction starts at 4 bytes
|
||||
// before the relocation offset.
|
||||
+ R_X86_64_CODE_5_GOTPCRELX = 46, // 32 bit signed PC relative offset to
|
||||
+ // GOT if the instruction starts at 5
|
||||
+ // bytes before the relocation offset,
|
||||
+ // relaxable.
|
||||
+ R_X86_64_CODE_5_GOTTPOFF = 47, // 32 bit signed PC relative offset to
|
||||
+ // GOT entry for IE symbol if the
|
||||
+ // instruction starts at 5 bytes before
|
||||
+ // the relocation offset.
|
||||
+ R_X86_64_CODE_5_GOTPC32_TLSDESC = 48, // 32-bit PC relative to TLS
|
||||
+ // descriptor in GOT if the
|
||||
+ // instruction starts at 5 bytes
|
||||
+ // before the relocation offset.
|
||||
+ R_X86_64_CODE_6_GOTPCRELX = 49, // 32 bit signed PC relative offset to
|
||||
+ // GOT if the instruction starts at 6
|
||||
+ // bytes before the relocation offset,
|
||||
+ // relaxable.
|
||||
+ R_X86_64_CODE_6_GOTTPOFF = 50, // 32 bit signed PC relative offset to
|
||||
+ // GOT entry for IE symbol if the
|
||||
+ // instruction starts at 6 bytes before
|
||||
+ // the relocation offset.
|
||||
+ R_X86_64_CODE_6_GOTPC32_TLSDESC = 51, // 32-bit PC relative to TLS
|
||||
+ // descriptor in GOT if the
|
||||
+ // instruction starts at 6 bytes
|
||||
+ // before the relocation offset.
|
||||
// GNU vtable garbage collection extensions.
|
||||
R_X86_64_GNU_VTINHERIT = 250,
|
||||
R_X86_64_GNU_VTENTRY = 251
|
||||
diff -rup binutils.orig/gas/config/tc-i386.c binutils-2.41/gas/config/tc-i386.c
|
||||
--- binutils.orig/gas/config/tc-i386.c 2024-04-05 10:34:23.973241300 +0100
|
||||
+++ binutils-2.41/gas/config/tc-i386.c 2024-04-05 10:59:44.561106936 +0100
|
||||
@@ -3640,6 +3640,7 @@ tc_i386_fix_adjustable (fixS *fixP)
|
||||
|| fixP->fx_r_type == BFD_RELOC_X86_64_DTPOFF64
|
||||
|| fixP->fx_r_type == BFD_RELOC_X86_64_GOTTPOFF
|
||||
|| fixP->fx_r_type == BFD_RELOC_X86_64_CODE_4_GOTTPOFF
|
||||
+ || fixP->fx_r_type == BFD_RELOC_X86_64_CODE_6_GOTTPOFF
|
||||
|| fixP->fx_r_type == BFD_RELOC_X86_64_TPOFF32
|
||||
|| fixP->fx_r_type == BFD_RELOC_X86_64_TPOFF64
|
||||
|| fixP->fx_r_type == BFD_RELOC_X86_64_GOTOFF64
|
||||
@@ -5671,10 +5672,19 @@ md_assemble (char *line)
|
||||
for (j = i.imm_operands; j < i.operands; ++j)
|
||||
switch (i.reloc[j])
|
||||
{
|
||||
+ case BFD_RELOC_X86_64_GOTTPOFF:
|
||||
+ if (i.tm.mnem_off == MN_add
|
||||
+ && i.tm.opcode_space == SPACE_EVEXMAP4
|
||||
+ && i.mem_operands == 1
|
||||
+ && i.base_reg
|
||||
+ && i.base_reg->reg_num == RegIP
|
||||
+ && i.tm.operand_types[0].bitfield.class == Reg
|
||||
+ && i.tm.operand_types[2].bitfield.class == Reg)
|
||||
+ /* Allow APX: add %reg1, foo@gottpoff(%rip), %reg2. */
|
||||
+ break;
|
||||
+ /* Fall through. */
|
||||
case BFD_RELOC_386_TLS_GOTIE:
|
||||
case BFD_RELOC_386_TLS_LE_32:
|
||||
- case BFD_RELOC_X86_64_GOTTPOFF:
|
||||
- case BFD_RELOC_X86_64_CODE_4_GOTTPOFF:
|
||||
case BFD_RELOC_X86_64_TLSLD:
|
||||
as_bad (_("TLS relocation cannot be used with `%s'"), insn_name (&i.tm));
|
||||
return;
|
||||
@@ -10889,6 +10899,7 @@ output_disp (fragS *insn_start_frag, off
|
||||
case BFD_RELOC_X86_64_TLSLD:
|
||||
case BFD_RELOC_X86_64_GOTTPOFF:
|
||||
case BFD_RELOC_X86_64_CODE_4_GOTTPOFF:
|
||||
+ case BFD_RELOC_X86_64_CODE_6_GOTTPOFF:
|
||||
case BFD_RELOC_X86_64_GOTPC32_TLSDESC:
|
||||
case BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC:
|
||||
case BFD_RELOC_X86_64_TLSDESC_CALL:
|
||||
@@ -10905,9 +10916,30 @@ output_disp (fragS *insn_start_frag, off
|
||||
&& !i.prefix[ADDR_PREFIX])
|
||||
fixP->fx_signed = 1;
|
||||
|
||||
- /* Set fx_tcbit3 for REX2 prefix. */
|
||||
- if (is_apx_rex2_encoding ())
|
||||
- fixP->fx_tcbit3 = 1;
|
||||
+ if (reloc_type == BFD_RELOC_X86_64_GOTTPOFF
|
||||
+ && i.tm.opcode_space == SPACE_EVEXMAP4)
|
||||
+ {
|
||||
+ /* Only "add %reg1, foo@gottpoff(%rip), %reg2" is
|
||||
+ allowed in md_assemble. Set fx_tcbit2 for EVEX
|
||||
+ prefix. */
|
||||
+ fixP->fx_tcbit2 = 1;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (i.base_reg && i.base_reg->reg_num == RegIP)
|
||||
+ {
|
||||
+ if (reloc_type == BFD_RELOC_X86_64_GOTPC32_TLSDESC)
|
||||
+ {
|
||||
+ /* Set fx_tcbit for REX2 prefix. */
|
||||
+ if (is_apx_rex2_encoding ())
|
||||
+ fixP->fx_tcbit = 1;
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+ /* In 64-bit, i386_validate_fix updates only (%rip)
|
||||
+ relocations. */
|
||||
+ else if (object_64bit)
|
||||
+ continue;
|
||||
|
||||
/* Check for "call/jmp *mem", "mov mem, %reg",
|
||||
"test %reg, mem" and "binop mem, %reg" where binop
|
||||
@@ -10932,10 +10964,22 @@ output_disp (fragS *insn_start_frag, off
|
||||
{
|
||||
if (object_64bit)
|
||||
{
|
||||
- fixP->fx_tcbit = i.rex != 0;
|
||||
- if (i.base_reg
|
||||
- && (i.base_reg->reg_num == RegIP))
|
||||
- fixP->fx_tcbit2 = 1;
|
||||
+ if (reloc_type == BFD_RELOC_X86_64_GOTTPOFF)
|
||||
+ {
|
||||
+ /* Set fx_tcbit for REX2 prefix. */
|
||||
+ if (is_apx_rex2_encoding ())
|
||||
+ fixP->fx_tcbit = 1;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /* Set fx_tcbit3 for REX2 prefix. */
|
||||
+ if (is_apx_rex2_encoding ())
|
||||
+ fixP->fx_tcbit3 = 1;
|
||||
+ else if (i.rex)
|
||||
+ fixP->fx_tcbit2 = 1;
|
||||
+ else
|
||||
+ fixP->fx_tcbit = 1;
|
||||
+ }
|
||||
}
|
||||
else
|
||||
fixP->fx_tcbit2 = 1;
|
||||
@@ -14405,6 +14449,7 @@ md_apply_fix (fixS *fixP, valueT *valP,
|
||||
case BFD_RELOC_X86_64_TLSLD:
|
||||
case BFD_RELOC_X86_64_GOTTPOFF:
|
||||
case BFD_RELOC_X86_64_CODE_4_GOTTPOFF:
|
||||
+ case BFD_RELOC_X86_64_CODE_6_GOTTPOFF:
|
||||
case BFD_RELOC_X86_64_GOTPC32_TLSDESC:
|
||||
case BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC:
|
||||
value = 0; /* Fully resolved at runtime. No addend. */
|
||||
@@ -15980,13 +16025,27 @@ i386_validate_fix (fixS *fixp)
|
||||
&& (!S_IS_DEFINED (fixp->fx_addsy)
|
||||
|| S_IS_EXTERNAL (fixp->fx_addsy));
|
||||
|
||||
- if (fixp->fx_tcbit3)
|
||||
+ /* BFD_RELOC_X86_64_GOTTPOFF:
|
||||
+ 1. fx_tcbit -> BFD_RELOC_X86_64_CODE_4_GOTTPOFF
|
||||
+ 2. fx_tcbit2 -> BFD_RELOC_X86_64_CODE_6_GOTTPOFF
|
||||
+ BFD_RELOC_X86_64_GOTPC32_TLSDESC:
|
||||
+ 1. fx_tcbit -> BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC
|
||||
+ BFD_RELOC_32_PCREL:
|
||||
+ 1. fx_tcbit -> BFD_RELOC_X86_64_GOTPCRELX
|
||||
+ 2. fx_tcbit2 -> BFD_RELOC_X86_64_REX_GOTPCRELX
|
||||
+ 3. fx_tcbit3 -> BFD_RELOC_X86_64_CODE_4_GOTPCRELX
|
||||
+ 4. else -> BFD_RELOC_X86_64_GOTPCREL
|
||||
+ */
|
||||
+ if (fixp->fx_r_type == BFD_RELOC_X86_64_GOTTPOFF)
|
||||
{
|
||||
- if (fixp->fx_r_type == BFD_RELOC_X86_64_GOTTPOFF)
|
||||
+ if (fixp->fx_tcbit)
|
||||
fixp->fx_r_type = BFD_RELOC_X86_64_CODE_4_GOTTPOFF;
|
||||
- else if (fixp->fx_r_type == BFD_RELOC_X86_64_GOTPC32_TLSDESC)
|
||||
- fixp->fx_r_type = BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC;
|
||||
+ else if (fixp->fx_tcbit2)
|
||||
+ fixp->fx_r_type = BFD_RELOC_X86_64_CODE_6_GOTTPOFF;
|
||||
}
|
||||
+ else if (fixp->fx_r_type == BFD_RELOC_X86_64_GOTPC32_TLSDESC
|
||||
+ && fixp->fx_tcbit)
|
||||
+ fixp->fx_r_type = BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC;
|
||||
#endif
|
||||
|
||||
if (fixp->fx_subsy)
|
||||
@@ -15998,15 +16057,12 @@ i386_validate_fix (fixS *fixp)
|
||||
if (!object_64bit)
|
||||
abort ();
|
||||
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
|
||||
- if (fixp->fx_tcbit2)
|
||||
- {
|
||||
- if (fixp->fx_tcbit3)
|
||||
- fixp->fx_r_type = BFD_RELOC_X86_64_CODE_4_GOTPCRELX;
|
||||
- else
|
||||
- fixp->fx_r_type = (fixp->fx_tcbit
|
||||
- ? BFD_RELOC_X86_64_REX_GOTPCRELX
|
||||
- : BFD_RELOC_X86_64_GOTPCRELX);
|
||||
- }
|
||||
+ if (fixp->fx_tcbit)
|
||||
+ fixp->fx_r_type = BFD_RELOC_X86_64_GOTPCRELX;
|
||||
+ else if (fixp->fx_tcbit2)
|
||||
+ fixp->fx_r_type = BFD_RELOC_X86_64_REX_GOTPCRELX;
|
||||
+ else if (fixp->fx_tcbit3)
|
||||
+ fixp->fx_r_type = BFD_RELOC_X86_64_CODE_4_GOTPCRELX;
|
||||
else
|
||||
#endif
|
||||
fixp->fx_r_type = BFD_RELOC_X86_64_GOTPCREL;
|
||||
@@ -16132,6 +16188,7 @@ tc_gen_reloc (asection *section ATTRIBUT
|
||||
case BFD_RELOC_X86_64_DTPOFF64:
|
||||
case BFD_RELOC_X86_64_GOTTPOFF:
|
||||
case BFD_RELOC_X86_64_CODE_4_GOTTPOFF:
|
||||
+ case BFD_RELOC_X86_64_CODE_6_GOTTPOFF:
|
||||
case BFD_RELOC_X86_64_TPOFF32:
|
||||
case BFD_RELOC_X86_64_TPOFF64:
|
||||
case BFD_RELOC_X86_64_GOTOFF64:
|
||||
@@ -16276,6 +16333,7 @@ tc_gen_reloc (asection *section ATTRIBUT
|
||||
case BFD_RELOC_X86_64_TLSLD:
|
||||
case BFD_RELOC_X86_64_GOTTPOFF:
|
||||
case BFD_RELOC_X86_64_CODE_4_GOTTPOFF:
|
||||
+ case BFD_RELOC_X86_64_CODE_6_GOTTPOFF:
|
||||
case BFD_RELOC_X86_64_GOTPC32_TLSDESC:
|
||||
case BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC:
|
||||
case BFD_RELOC_X86_64_TLSDESC_CALL:
|
||||
diff -rup binutils.orig/gas/testsuite/gas/i386/x86-64-gottpoff.d binutils-2.41/gas/testsuite/gas/i386/x86-64-gottpoff.d
|
||||
--- binutils.orig/gas/testsuite/gas/i386/x86-64-gottpoff.d 2024-04-05 10:34:24.078241418 +0100
|
||||
+++ binutils-2.41/gas/testsuite/gas/i386/x86-64-gottpoff.d 2024-04-05 10:59:44.561106936 +0100
|
||||
@@ -16,4 +16,8 @@ Disassembly of section .text:
|
||||
+[a-f0-9]+: 48 8b 05 00 00 00 00 mov 0x0\(%rip\),%rax # 2c <_start\+0x2c> 28: R_X86_64_GOTTPOFF foo-0x4
|
||||
+[a-f0-9]+: d5 48 03 05 00 00 00 00 add 0x0\(%rip\),%r16 # 34 <_start\+0x34> 30: R_X86_64_CODE_4_GOTTPOFF foo-0x4
|
||||
+[a-f0-9]+: d5 48 8b 25 00 00 00 00 mov 0x0\(%rip\),%r20 # 3c <_start\+0x3c> 38: R_X86_64_CODE_4_GOTTPOFF foo-0x4
|
||||
+ +[a-f0-9]+: 62 74 fc 10 01 05 00 00 00 00 add %r8,0x0\(%rip\),%r16 # 46 <_start\+0x46> 42: R_X86_64_CODE_6_GOTTPOFF foo-0x4
|
||||
+ +[a-f0-9]+: 62 f4 9c 18 03 05 00 00 00 00 add 0x0\(%rip\),%rax,%r12 # 50 <_start\+0x50> 4c: R_X86_64_CODE_6_GOTTPOFF foo-0x4
|
||||
+ +[a-f0-9]+: 62 74 fc 10 01 05 00 00 00 00 add %r8,0x0\(%rip\),%r16 # 5a <_start\+0x5a> 56: R_X86_64_CODE_6_GOTTPOFF foo-0x4
|
||||
+ +[a-f0-9]+: 62 f4 9c 18 03 05 00 00 00 00 add 0x0\(%rip\),%rax,%r12 # 64 <_start\+0x64> 60: R_X86_64_CODE_6_GOTTPOFF foo-0x4
|
||||
#pass
|
||||
diff -rup binutils.orig/gas/testsuite/gas/i386/x86-64-gottpoff.s binutils-2.41/gas/testsuite/gas/i386/x86-64-gottpoff.s
|
||||
--- binutils.orig/gas/testsuite/gas/i386/x86-64-gottpoff.s 2024-04-05 10:34:24.078241418 +0100
|
||||
+++ binutils-2.41/gas/testsuite/gas/i386/x86-64-gottpoff.s 2024-04-05 10:59:44.561106936 +0100
|
||||
@@ -13,3 +13,13 @@ _start:
|
||||
|
||||
addq r16, QWORD PTR [rip + foo@GOTTPOFF]
|
||||
movq r20, QWORD PTR [rip + foo@GOTTPOFF]
|
||||
+
|
||||
+ .att_syntax prefix
|
||||
+
|
||||
+ addq %r8, foo@GOTTPOFF(%rip), %r16
|
||||
+ addq foo@GOTTPOFF(%rip), %rax, %r12
|
||||
+
|
||||
+ .intel_syntax noprefix
|
||||
+
|
||||
+ addq r16, QWORD PTR [rip + foo@GOTTPOFF], r8
|
||||
+ addq r12, rax, QWORD PTR [rip + foo@GOTTPOFF]
|
||||
diff -rup binutils.orig/gold/x86_64.cc binutils-2.41/gold/x86_64.cc
|
||||
--- binutils.orig/gold/x86_64.cc 2024-04-05 10:34:24.166241517 +0100
|
||||
+++ binutils-2.41/gold/x86_64.cc 2024-04-05 10:59:44.563106939 +0100
|
||||
@@ -2920,6 +2920,11 @@ Target_x86_64<size>::optimize_tls_reloc(
|
||||
// Another Local-Dynamic reloc.
|
||||
return tls::TLSOPT_TO_LE;
|
||||
|
||||
+ case elfcpp::R_X86_64_CODE_6_GOTTPOFF:
|
||||
+ if (r_offset <= 6 || *(reloc_view - 6) != 0x62)
|
||||
+ return tls::TLSOPT_NONE;
|
||||
+ goto handle_gottpoff;
|
||||
+
|
||||
case elfcpp::R_X86_64_CODE_4_GOTTPOFF:
|
||||
if (r_offset <= 4 || *(reloc_view - 4) != 0xd5)
|
||||
return tls::TLSOPT_NONE;
|
||||
@@ -2929,6 +2934,7 @@ Target_x86_64<size>::optimize_tls_reloc(
|
||||
// from the GOT. If we know that we are linking against the
|
||||
// local symbol, we can switch to Local-Exec, which links the
|
||||
// thread offset into the instruction.
|
||||
+handle_gottpoff:
|
||||
if (is_final)
|
||||
return tls::TLSOPT_TO_LE;
|
||||
return tls::TLSOPT_NONE;
|
||||
@@ -2997,6 +3003,7 @@ Target_x86_64<size>::Scan::get_reference
|
||||
case elfcpp::R_X86_64_DTPOFF64:
|
||||
case elfcpp::R_X86_64_GOTTPOFF: // Initial-exec
|
||||
case elfcpp::R_X86_64_CODE_4_GOTTPOFF:
|
||||
+ case elfcpp::R_X86_64_CODE_6_GOTTPOFF:
|
||||
case elfcpp::R_X86_64_TPOFF32: // Local-exec
|
||||
return Symbol::TLS_REF;
|
||||
|
||||
@@ -3362,6 +3369,7 @@ need_got:
|
||||
// These are initial tls relocs, which are expected when linking
|
||||
case elfcpp::R_X86_64_CODE_4_GOTPC32_TLSDESC:
|
||||
case elfcpp::R_X86_64_CODE_4_GOTTPOFF:
|
||||
+ case elfcpp::R_X86_64_CODE_6_GOTTPOFF:
|
||||
{
|
||||
section_size_type stype;
|
||||
reloc_view = object->section_contents(data_shndx, &stype, true);
|
||||
@@ -3464,6 +3472,7 @@ need_got:
|
||||
|
||||
case elfcpp::R_X86_64_GOTTPOFF: // Initial-exec
|
||||
case elfcpp::R_X86_64_CODE_4_GOTTPOFF:
|
||||
+ case elfcpp::R_X86_64_CODE_6_GOTTPOFF:
|
||||
layout->set_has_static_tls();
|
||||
if (optimized_type == tls::TLSOPT_NONE)
|
||||
{
|
||||
@@ -3902,6 +3911,7 @@ Target_x86_64<size>::Scan::global(Symbol
|
||||
// These are initial tls relocs, which are expected for global()
|
||||
case elfcpp::R_X86_64_CODE_4_GOTPC32_TLSDESC:
|
||||
case elfcpp::R_X86_64_CODE_4_GOTTPOFF:
|
||||
+ case elfcpp::R_X86_64_CODE_6_GOTTPOFF:
|
||||
{
|
||||
section_size_type stype;
|
||||
reloc_view = object->section_contents(data_shndx, &stype, true);
|
||||
@@ -3920,7 +3930,8 @@ Target_x86_64<size>::Scan::global(Symbol
|
||||
// when building an executable.
|
||||
const bool is_final = (gsym->final_value_is_known() ||
|
||||
((r_type == elfcpp::R_X86_64_GOTTPOFF ||
|
||||
- r_type == elfcpp::R_X86_64_CODE_4_GOTTPOFF) &&
|
||||
+ r_type == elfcpp::R_X86_64_CODE_4_GOTTPOFF||
|
||||
+ r_type == elfcpp::R_X86_64_CODE_6_GOTTPOFF) &&
|
||||
gsym->is_undefined() &&
|
||||
parameters->options().output_is_executable()));
|
||||
size_t r_offset = reloc.get_r_offset();
|
||||
@@ -4006,6 +4017,7 @@ Target_x86_64<size>::Scan::global(Symbol
|
||||
|
||||
case elfcpp::R_X86_64_GOTTPOFF: // Initial-exec
|
||||
case elfcpp::R_X86_64_CODE_4_GOTTPOFF:
|
||||
+ case elfcpp::R_X86_64_CODE_6_GOTTPOFF:
|
||||
layout->set_has_static_tls();
|
||||
if (optimized_type == tls::TLSOPT_NONE)
|
||||
{
|
||||
@@ -4608,6 +4620,7 @@ Target_x86_64<size>::Relocate::relocate(
|
||||
case elfcpp::R_X86_64_DTPOFF64:
|
||||
case elfcpp::R_X86_64_GOTTPOFF: // Initial-exec
|
||||
case elfcpp::R_X86_64_CODE_4_GOTTPOFF:
|
||||
+ case elfcpp::R_X86_64_CODE_6_GOTTPOFF:
|
||||
case elfcpp::R_X86_64_TPOFF32: // Local-exec
|
||||
this->relocate_tls(relinfo, target, relnum, rela, r_type, gsym, psymval,
|
||||
view, address, view_size);
|
||||
@@ -4894,6 +4907,7 @@ Target_x86_64<size>::Relocate::relocate_
|
||||
|
||||
case elfcpp::R_X86_64_GOTTPOFF: // Initial-exec
|
||||
case elfcpp::R_X86_64_CODE_4_GOTTPOFF:
|
||||
+ case elfcpp::R_X86_64_CODE_6_GOTTPOFF:
|
||||
if (gsym != NULL
|
||||
&& gsym->is_undefined()
|
||||
&& parameters->options().output_is_executable())
|
||||
@@ -5308,11 +5322,19 @@ Target_x86_64<size>::Relocate::tls_ie_to
|
||||
|
||||
// movq foo@gottpoff(%rip),%reg ==> movq $YY,%reg
|
||||
// addq foo@gottpoff(%rip),%reg ==> addq $YY,%reg
|
||||
+ // addq %reg1,foo@gottpoff(%rip),%reg2 ==> addq $YY,%reg1,%reg2
|
||||
+ // addq foo@gottpoff(%rip),%reg1,%reg2 ==> addq $YY,%reg1,%reg2
|
||||
|
||||
- tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, -3);
|
||||
+ int off1;
|
||||
+ if (r_type == elfcpp::R_X86_64_CODE_6_GOTTPOFF)
|
||||
+ off1 = -5;
|
||||
+ else
|
||||
+ off1 = -3;
|
||||
+
|
||||
+ tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, off1);
|
||||
tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, 4);
|
||||
|
||||
- unsigned char op1 = view[-3];
|
||||
+ unsigned char op1 = view[off1];
|
||||
unsigned char op2 = view[-2];
|
||||
unsigned char op3 = view[-1];
|
||||
unsigned char reg = op3 >> 3;
|
||||
@@ -5350,7 +5372,7 @@ Target_x86_64<size>::Relocate::tls_ie_to
|
||||
view[-1] = 0x80 | reg | (reg << 3);
|
||||
}
|
||||
}
|
||||
- else
|
||||
+ else if (r_type == elfcpp::R_X86_64_CODE_4_GOTTPOFF)
|
||||
{
|
||||
if (op2 == 0x8b)
|
||||
op2 = 0xc7;
|
||||
@@ -5362,6 +5384,23 @@ Target_x86_64<size>::Relocate::tls_ie_to
|
||||
view[-2] = op2;
|
||||
view[-1] = 0xc0 | reg;
|
||||
}
|
||||
+ else
|
||||
+ {
|
||||
+ unsigned char updated_op1 = op1;
|
||||
+
|
||||
+ // Set the R bits since they is inverted.
|
||||
+ updated_op1 |= 1 << 7 | 1 << 4;
|
||||
+
|
||||
+ // Update the B bits from the R bits.
|
||||
+ if ((op1 & (1 << 7)) == 0)
|
||||
+ updated_op1 &= ~(1 << 5);
|
||||
+ if ((op1 & (1 << 4)) == 0)
|
||||
+ updated_op1 |= 1 << 3;
|
||||
+
|
||||
+ view[-5] = updated_op1;
|
||||
+ view[-2] = 0x81;
|
||||
+ view[-1] = 0xc0 | reg;
|
||||
+ }
|
||||
|
||||
if (tls_segment != NULL)
|
||||
value -= tls_segment->memsz();
|
||||
diff -rup binutils.orig/include/elf/x86-64.h binutils-2.41/include/elf/x86-64.h
|
||||
--- binutils.orig/include/elf/x86-64.h 2024-04-05 10:34:24.174241526 +0100
|
||||
+++ binutils-2.41/include/elf/x86-64.h 2024-04-05 10:59:44.563106939 +0100
|
||||
@@ -92,6 +92,26 @@ START_RELOC_NUMBERS (elf_x86_64_reloc_ty
|
||||
/* 32 bit signed pc relative offset to TLS descriptor in the GOT if
|
||||
instruction starts at 4 bytes before the relocation offset. */
|
||||
RELOC_NUMBER (R_X86_64_CODE_4_GOTPC32_TLSDESC, 45)
|
||||
+ /* Load from 32 bit signed pc relative offset to GOT entry if the
|
||||
+ instruction starts at 5 bytes before the relocation offset,
|
||||
+ relaxable. */
|
||||
+ RELOC_NUMBER (R_X86_64_CODE_5_GOTPCRELX, 46)
|
||||
+ /* 32 bit signed pc relative offset to TLS descriptor in the GOT if
|
||||
+ instruction starts at 5 bytes before the relocation offset. */
|
||||
+ RELOC_NUMBER (R_X86_64_CODE_5_GOTPC32_TLSDESC, 47)
|
||||
+ /* PC relative offset to IE GOT entry if the instruction starts at
|
||||
+ 5 bytes before the relocation offset. */
|
||||
+ RELOC_NUMBER (R_X86_64_CODE_5_GOTTPOFF, 48)
|
||||
+ /* Load from 32 bit signed pc relative offset to GOT entry if the
|
||||
+ instruction starts at 6 bytes before the relocation offset,
|
||||
+ relaxable. */
|
||||
+ RELOC_NUMBER (R_X86_64_CODE_6_GOTPCRELX, 49)
|
||||
+ /* PC relative offset to IE GOT entry if the instruction starts at
|
||||
+ 6 bytes before the relocation offset. */
|
||||
+ RELOC_NUMBER (R_X86_64_CODE_6_GOTTPOFF, 50)
|
||||
+ /* 32 bit signed pc relative offset to TLS descriptor in the GOT if
|
||||
+ instruction starts at 6 bytes before the relocation offset. */
|
||||
+ RELOC_NUMBER (R_X86_64_CODE_6_GOTPC32_TLSDESC, 51)
|
||||
RELOC_NUMBER (R_X86_64_GNU_VTINHERIT, 250) /* GNU C++ hack */
|
||||
RELOC_NUMBER (R_X86_64_GNU_VTENTRY, 251) /* GNU C++ hack */
|
||||
END_RELOC_NUMBERS (R_X86_64_max)
|
||||
37
binutils-archive-DT_SYMTAB.patch
Normal file
37
binutils-archive-DT_SYMTAB.patch
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
--- binutils.orig/bfd/elflink.c
|
||||
+++ binutils-2.41/bfd/elflink.c
|
||||
@@ -3571,12 +3571,6 @@ elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef)
|
||||
if (! bfd_check_format (abfd, bfd_object))
|
||||
return false;
|
||||
|
||||
- if (elf_use_dt_symtab_p (abfd))
|
||||
- {
|
||||
- bfd_set_error (bfd_error_wrong_format);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
/* Select the appropriate symbol table. If we don't know if the
|
||||
object file is an IR object, give linker LTO plugin a chance to
|
||||
get the correct symbol table. */
|
||||
@@ -3592,10 +3586,19 @@ elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef)
|
||||
abfd = abfd->plugin_dummy_bfd;
|
||||
hdr = &elf_tdata (abfd)->symtab_hdr;
|
||||
}
|
||||
- else if ((abfd->flags & DYNAMIC) == 0 || elf_dynsymtab (abfd) == 0)
|
||||
- hdr = &elf_tdata (abfd)->symtab_hdr;
|
||||
else
|
||||
- hdr = &elf_tdata (abfd)->dynsymtab_hdr;
|
||||
+ {
|
||||
+ if (elf_use_dt_symtab_p (abfd))
|
||||
+ {
|
||||
+ bfd_set_error (bfd_error_wrong_format);
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if ((abfd->flags & DYNAMIC) == 0 || elf_dynsymtab (abfd) == 0)
|
||||
+ hdr = &elf_tdata (abfd)->symtab_hdr;
|
||||
+ else
|
||||
+ hdr = &elf_tdata (abfd)->dynsymtab_hdr;
|
||||
+ }
|
||||
|
||||
symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
|
||||
45
binutils-ppc64-TLS-no_plt-optimization-bug.patch
Normal file
45
binutils-ppc64-TLS-no_plt-optimization-bug.patch
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
From 1686dc7079f1c03bdaffd2f779b92aa2b7ad97b5 Mon Sep 17 00:00:00 2001
|
||||
From: Alan Modra <amodra@gmail.com>
|
||||
Date: Tue, 26 Nov 2024 08:24:19 +1030
|
||||
Subject: [PATCH] PR32387 ppc64 TLS optimization bug with -fno-plt code
|
||||
|
||||
The inline plt code emitted by gcc is incompatible with the
|
||||
linker/ld.so --tls-get-addr-optimize scheme. This is the runtime
|
||||
optimisation where the first call to __tls_get_addr results in
|
||||
__tls_get_addr updating the tls_index pair, then the special linker
|
||||
stub using that to short-circuit second and subsequent calls for a
|
||||
given tls symbol. Enabled by default when the linker sees
|
||||
__tls_get_addr_opt is preseent, and enabled in ld.so when DT_PPC64_OPT
|
||||
has PPC64_OPT_TLS set. Note that this is distinct from link-time tls
|
||||
optimisation.
|
||||
|
||||
PR 32387
|
||||
* elf64-ppc.c (ppc64_elf_check_relocs): Disable tls_get_addr_opt
|
||||
on detecting inline plt calls to __tls_get_addr.
|
||||
---
|
||||
bfd/elf64-ppc.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
|
||||
index 9674fcdd6be..f7debc1edbc 100644
|
||||
--- a/bfd/elf64-ppc.c
|
||||
+++ b/bfd/elf64-ppc.c
|
||||
@@ -4915,6 +4915,15 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
tls_type = 0;
|
||||
switch (r_type)
|
||||
{
|
||||
+ case R_PPC64_PLTSEQ:
|
||||
+ case R_PPC64_PLTSEQ_NOTOC:
|
||||
+ /* Inline plt call code emitted by gcc doesn't support
|
||||
+ modifying the tls_index words to short-circuit
|
||||
+ __tls_get_addr calls. See PR32387. */
|
||||
+ if (h != NULL && (h == tga || h == dottga))
|
||||
+ htab->params->tls_get_addr_opt = 0;
|
||||
+ break;
|
||||
+
|
||||
case R_PPC64_TLSGD:
|
||||
case R_PPC64_TLSLD:
|
||||
/* These special tls relocs tie a call to __tls_get_addr with
|
||||
--
|
||||
2.43.5
|
||||
|
||||
|
|
@ -984,3 +984,18 @@ diff -rup binutils.orig/ld/testsuite/ld-powerpc/tls32no.g binutils-2.41/ld/tests
|
|||
- 1810154 (0+01 f+8020 f+9030 0+01|010+ 2080f+ 3090f+ 010+) .*
|
||||
- 1810164 0+ 0+ 0+ 0+0 .*
|
||||
+#pass
|
||||
--- binutils.orig/ld/testsuite/ld-plugin/lto.exp 2024-11-26 16:03:01.214914908 +0000
|
||||
+++ binutils-2.41/ld/testsuite/ld-plugin/lto.exp 2024-11-26 16:04:39.983307748 +0000
|
||||
@@ -638,12 +638,6 @@ set lto_run_tests [list \
|
||||
[list "Run pr20276" \
|
||||
"-O2 -flto tmpdir/pr20276a.o tmpdir/pr20276b.o" "" \
|
||||
{dummy.c} "pr20276" "pass.out" "-flto -O2" "c"] \
|
||||
- [list "Run pr20267a" \
|
||||
- "-O2 -flto -fcommon tmpdir/pr20267a.o tmpdir/libpr20267a.a" "" \
|
||||
- {dummy.c} "pr20267a" "pass.out" "-flto -O2 -fcommon" "c"] \
|
||||
- [list "Run pr20267b" \
|
||||
- "-O2 -flto -fcommon tmpdir/pr20267a.o tmpdir/libpr20267b.a" "" \
|
||||
- {dummy.c} "pr20267b" "pass.out" "-flto -O2 -fcommon" "c"] \
|
||||
[list "Run pr22502" \
|
||||
"-O2 -flto tmpdir/pr22502a.o tmpdir/pr22502b.o" "" \
|
||||
{dummy.c} "pr20267" "pass.out" "-flto -O2 -fcommon" "c"] \
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Summary: A GNU collection of binary utilities
|
||||
Name: binutils%{?_with_debug:-debug}
|
||||
Version: 2.41
|
||||
Release: 34%{?dist}
|
||||
Release: 38%{?dist}
|
||||
License: GPL-3.0-or-later AND (GPL-3.0-or-later WITH Bison-exception-2.2) AND (LGPL-2.0-or-later WITH GCC-exception-2.0) AND BSD-3-Clause AND GFDL-1.3-or-later AND GPL-2.0-or-later AND LGPL-2.1-or-later AND LGPL-2.0-or-later
|
||||
URL: https://sourceware.org/binutils
|
||||
|
||||
|
|
@ -331,6 +331,18 @@ Patch38: binutils-Intel-APX-part-1-fixes.patch
|
|||
# Lifetime: Fixed in 2.42
|
||||
Patch39: binutils-multilib.am.patch
|
||||
|
||||
# Purpose: Fix APX support for R_X86_64_CODE_6_GOTTPOFF
|
||||
# Lifetime: Fixed in 2.42
|
||||
Patch40: binutils-Intel-APX-CODE_6_GOTTPOFF.patch
|
||||
|
||||
# Purpose: Fix ld crash on LLVM-produced archive objects
|
||||
# Lifetime: Fixed in 2.42
|
||||
Patch41: binutils-archive-DT_SYMTAB.patch
|
||||
|
||||
# Purpose: Fix ppc64 TLS optimization bug with -fno-plt code.
|
||||
# Lifetime: Fixed in 2.44
|
||||
Patch42: binutils-ppc64-TLS-no_plt-optimization-bug.patch
|
||||
|
||||
# Purpose: Suppress the x86 linker's p_align-1 tests due to kernel bug on CentOS-10
|
||||
# Lifetime: TEMPORARY
|
||||
Patch99: binutils-suppress-ld-align-tests.patch
|
||||
|
|
@ -1270,7 +1282,8 @@ exit 0
|
|||
%{_bindir}/[!l]*
|
||||
# %%verify(symlink) does not work for some reason, so using "owner" instead.
|
||||
%verify(owner) %{_bindir}/ld
|
||||
%{_bindir}/ld.bfd
|
||||
# %%verify(mtime) does not work, probably because of the alternatives command in the %%post stage, so using "owner" instead. (#2277349)
|
||||
%verify(owner) %{_bindir}/ld.bfd
|
||||
|
||||
%if %{with gprofng}
|
||||
%exclude %{_bindir}/gp-*
|
||||
|
|
@ -1370,6 +1383,18 @@ exit 0
|
|||
|
||||
#----------------------------------------------------------------------------
|
||||
%changelog
|
||||
* Tue Nov 26 2024 Björn Esser <besser82@fedoraproject.org> - 2.41-38
|
||||
- Fix ppc64 TLS optimization bug with -fno-plt code. (#2324491)
|
||||
|
||||
* Fri May 03 2024 Benjamin Gilbert <bgilbert@backtick.net> - 2.41-37
|
||||
- Backport commit bac5753ca24 to fix ld crash on LLVM-produced archives (#2278106)
|
||||
|
||||
* Mon Apr 29 2024 Nick Clifton <nickc@redhat.com> - 2.41-36
|
||||
- Spec File: Stop %%verify(mtime) for ld.bfd. (#2277349)
|
||||
|
||||
* Fri Apr 05 2024 Nick Clifton <nickc@redhat.com> - 2.41-35
|
||||
- Backport commit 5bc71c2a6b8 to fix APX support for R_X86_64_CODE_6_GOTTPOFF (#2273298)
|
||||
|
||||
* Mon Feb 12 2024 Nick Clifton <nickc@redhat.com> - 2.41-34
|
||||
- Backport commits 5a635f1f59ad and 41e115853eef to fix some APX issues.
|
||||
- Add top-level multilib.am file.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue