Skip to content

Commit 5bc71c2

Browse files
committed
x86-64: Add R_X86_64_CODE_6_GOTTPOFF
For add %reg1, name@gottpoff(%rip), %reg2 and add name@gottpoff(%rip), %reg1, %reg2 add #define R_X86_64_CODE_6_GOTTPOFF 50 if the instruction starts at 6 bytes before the relocation offset. They are similar to R_X86_64_GOTTPOFF. Linker can covert GOTTPOFF to add $name@tpoff, %reg1, %reg2 Rewrite fx_tcbit, fx_tcbit2 and fx_tcbit3 usage to generate R_X86_64_GOTPCRELX, R_X86_64_REX_GOTPCRELX, R_X86_64_CODE_4_GOTPCRELX, R_X86_64_CODE_4_GOTTPOFF, R_X86_64_CODE_4_GOTPC32_TLSDESC and R_X86_64_CODE_6_GOTTPOFF. NB: There is no need to check BFD_RELOC_X86_64_CODE_4_GOTTPOFF in md_assemble since there is only BFD_RELOC_X86_64_GOTTPOFF at this stage, which will be converted to BFD_RELOC_X86_64_CODE_4_GOTTPOFF or BFD_RELOC_X86_64_CODE_6_GOTTPOFF in i386_validate_fix. 5 relocations: #define R_X86_64_CODE_5_GOTPCRELX 46 #define R_X86_64_CODE_5_GOTTPOFF 47 #define R_X86_64_CODE_5_GOTPC32_TLSDESC 48 #define R_X86_64_CODE_6_GOTPCRELX 49 #define R_X86_64_CODE_6_GOTPC32_TLSDESC 51 are added for completeness and they are unused. bfd/ * elf64-x86-64.c (x86_64_elf_howto_table): Add R_X86_64_CODE_5_GOTPCRELX, R_X86_64_CODE_5_GOTTPOFF, R_X86_64_CODE_5_GOTPC32_TLSDESC, R_X86_64_CODE_6_GOTPCRELX, R_X86_64_CODE_6_GOTTPOFF and R_X86_64_CODE_6_GOTPC32_TLSDESC. (R_X86_64_standard): Updated. (x86_64_reloc_map): Add R_X86_64_CODE_5_GOTPCRELX, R_X86_64_CODE_5_GOTTPOFF, R_X86_64_CODE_5_GOTPC32_TLSDESC, R_X86_64_CODE_6_GOTPCRELX, R_X86_64_CODE_6_GOTTPOFF and R_X86_64_CODE_6_GOTPC32_TLSDESC. (elf_x86_64_check_tls_transition): Handle R_X86_64_CODE_6_GOTTPOFF. (elf_x86_64_tls_transition): Likewise. (elf_x86_64_scan_relocs): Handle R_X86_64_CODE_6_GOTTPOFF. Issue an error for R_X86_64_CODE_5_GOTPCRELX, R_X86_64_CODE_5_GOTTPOFF, R_X86_64_CODE_5_GOTPC32_TLSDESC, R_X86_64_CODE_6_GOTPCRELX and R_X86_64_CODE_6_GOTPC32_TLSDESC. (elf_x86_64_relocate_section): Handle R_X86_64_CODE_6_GOTTPOFF. * reloc.c (bfd_reloc_code_real): Add 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 and BFD_RELOC_X86_64_CODE_6_GOTPC32_TLSDESC. * bfd-in2.h: Regenerated. * libbfd.h: Likewise. elfcpp/ * x86_64.h (R_X86_64_CODE_5_GOTPCRELX): New. (R_X86_64_CODE_5_GOTTPOFF): Likewise. (R_X86_64_CODE_5_GOTPC32_TLSDESC): Likewise. (R_X86_64_CODE_6_GOTPCRELX): Likewise. (R_X86_64_CODE_6_GOTTPOFF): Likewise. (R_X86_64_CODE_6_GOTPC32_TLSDESC): Likewise. gas/ * config/tc-i386.c (tc_i386_fix_adjustable): Handle BFD_RELOC_X86_64_CODE_6_GOTTPOFF. (md_assemble): Don't check BFD_RELOC_X86_64_CODE_4_GOTTPOFF. Allow "add %reg1, foo@gottpoff(%rip), %reg2". (output_disp): Handle BFD_RELOC_X86_64_CODE_6_GOTTPOFF. Rewrite setting fx_tcbitX bits for BFD_RELOC_X86_64_GOTTPOFF, BFD_RELOC_X86_64_GOTPC32_TLSDESC and BFD_RELOC_32_PCREL. (md_apply_fix): Handle BFD_RELOC_X86_64_CODE_6_GOTTPOFF. (i386_validate_fix): Rewrite fx_tcbitX bit checking for BFD_RELOC_X86_64_GOTTPOFF, BFD_RELOC_X86_64_GOTPC32_TLSDESC and BFD_RELOC_32_PCREL. (tc_gen_reloc): Handle BFD_RELOC_X86_64_CODE_6_GOTTPOFF. * testsuite/gas/i386/x86-64-gottpoff.d: Updated. * testsuite/gas/i386/x86-64-gottpoff.s: Add tests for "add %reg1, foo@gottpoff(%rip), %reg2" and "add foo@gottpoff(%rip), %reg, %reg2". gold/ * x86_64.cc (Target_x86_64::optimize_tls_reloc): Handle R_X86_64_CODE_6_GOTTPOFF. (Target_x86_64::Scan::get_reference_flags): Likewise. (Target_x86_64::Scan::local): Likewise. (Target_x86_64::Scan::global): Likewise. (Target_x86_64::Relocate::relocate): Likewise. (Target_x86_64::Relocate::relocate_tls): Likewise. (Target_x86_64::Relocate::tls_ie_to_le): Handle. R_X86_64_CODE_6_GOTTPOFF. * testsuite/x86_64_ie_to_le.s: Add tests for "add %reg1, foo@gottpoff(%rip), %reg2" and "add foo@gottpoff(%rip), %reg, %reg2". * testsuite/x86_64_ie_to_le.sh: Updated. include/ * elf/x86-64.h (elf_x86_64_reloc_type): Add R_X86_64_CODE_5_GOTPCRELX, R_X86_64_CODE_5_GOTTPOFF, R_X86_64_CODE_5_GOTPC32_TLSDESC, R_X86_64_CODE_6_GOTPCRELX, R_X86_64_CODE_6_GOTTPOFF and R_X86_64_CODE_6_GOTPC32_TLSDESC. ld/ * testsuite/ld-x86-64/tlsbindesc.s: Add R_X86_64_CODE_6_GOTTPOFF tests. * testsuite/ld-x86-64/tlsbindesc.d: Updated. * testsuite/ld-x86-64/tlsbindesc.rd: Likewise.
1 parent 3f8f974 commit 5bc71c2

File tree

15 files changed

+371
-45
lines changed

15 files changed

+371
-45
lines changed

bfd/bfd-in2.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3894,6 +3894,12 @@ enum bfd_reloc_code_real
38943894
BFD_RELOC_X86_64_CODE_4_GOTPCRELX,
38953895
BFD_RELOC_X86_64_CODE_4_GOTTPOFF,
38963896
BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC,
3897+
BFD_RELOC_X86_64_CODE_5_GOTPCRELX,
3898+
BFD_RELOC_X86_64_CODE_5_GOTTPOFF,
3899+
BFD_RELOC_X86_64_CODE_5_GOTPC32_TLSDESC,
3900+
BFD_RELOC_X86_64_CODE_6_GOTPCRELX,
3901+
BFD_RELOC_X86_64_CODE_6_GOTTPOFF,
3902+
BFD_RELOC_X86_64_CODE_6_GOTPC32_TLSDESC,
38973903

38983904
/* ns32k relocations. */
38993905
BFD_RELOC_NS32K_IMM_8,

bfd/elf64-x86-64.c

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,30 @@ static reloc_howto_type x86_64_elf_howto_table[] =
179179
HOWTO(R_X86_64_CODE_4_GOTPC32_TLSDESC, 0, 4, 32, true, 0,
180180
complain_overflow_bitfield, bfd_elf_generic_reloc,
181181
"R_X86_64_CODE_4_GOTPC32_TLSDESC", false, 0, 0xffffffff, true),
182+
HOWTO(R_X86_64_CODE_5_GOTPCRELX, 0, 4, 32, true, 0,
183+
complain_overflow_signed, bfd_elf_generic_reloc,
184+
"R_X86_64_CODE_5_GOTPCRELX", false, 0, 0xffffffff, true),
185+
HOWTO(R_X86_64_CODE_5_GOTTPOFF, 0, 4, 32, true, 0,
186+
complain_overflow_signed, bfd_elf_generic_reloc,
187+
"R_X86_64_CODE_5_GOTTPOFF", false, 0, 0xffffffff, true),
188+
HOWTO(R_X86_64_CODE_5_GOTPC32_TLSDESC, 0, 4, 32, true, 0,
189+
complain_overflow_bitfield, bfd_elf_generic_reloc,
190+
"R_X86_64_CODE_5_GOTPC32_TLSDESC", false, 0, 0xffffffff, true),
191+
HOWTO(R_X86_64_CODE_6_GOTPCRELX, 0, 4, 32, true, 0,
192+
complain_overflow_signed, bfd_elf_generic_reloc,
193+
"R_X86_64_CODE_6_GOTPCRELX", false, 0, 0xffffffff, true),
194+
HOWTO(R_X86_64_CODE_6_GOTTPOFF, 0, 4, 32, true, 0,
195+
complain_overflow_signed, bfd_elf_generic_reloc,
196+
"R_X86_64_CODE_6_GOTTPOFF", false, 0, 0xffffffff, true),
197+
HOWTO(R_X86_64_CODE_6_GOTPC32_TLSDESC, 0, 4, 32, true, 0,
198+
complain_overflow_bitfield, bfd_elf_generic_reloc,
199+
"R_X86_64_CODE_6_GOTPC32_TLSDESC", false, 0, 0xffffffff, true),
182200

183201
/* We have a gap in the reloc numbers here.
184202
R_X86_64_standard counts the number up to this point, and
185203
R_X86_64_vt_offset is the value to subtract from a reloc type of
186204
R_X86_64_GNU_VT* to form an index into this table. */
187-
#define R_X86_64_standard (R_X86_64_CODE_4_GOTPC32_TLSDESC + 1)
205+
#define R_X86_64_standard (R_X86_64_CODE_6_GOTPC32_TLSDESC + 1)
188206
#define R_X86_64_vt_offset (R_X86_64_GNU_VTINHERIT - R_X86_64_standard)
189207

190208
/* GNU extension to record C++ vtable hierarchy. */
@@ -256,6 +274,12 @@ static const struct elf_reloc_map x86_64_reloc_map[] =
256274
{ BFD_RELOC_X86_64_CODE_4_GOTPCRELX, R_X86_64_CODE_4_GOTPCRELX, },
257275
{ BFD_RELOC_X86_64_CODE_4_GOTTPOFF, R_X86_64_CODE_4_GOTTPOFF, },
258276
{ BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC, R_X86_64_CODE_4_GOTPC32_TLSDESC, },
277+
{ BFD_RELOC_X86_64_CODE_5_GOTPCRELX, R_X86_64_CODE_5_GOTPCRELX, },
278+
{ BFD_RELOC_X86_64_CODE_5_GOTTPOFF, R_X86_64_CODE_5_GOTTPOFF, },
279+
{ BFD_RELOC_X86_64_CODE_5_GOTPC32_TLSDESC, R_X86_64_CODE_5_GOTPC32_TLSDESC, },
280+
{ BFD_RELOC_X86_64_CODE_6_GOTPCRELX, R_X86_64_CODE_6_GOTPCRELX, },
281+
{ BFD_RELOC_X86_64_CODE_6_GOTTPOFF, R_X86_64_CODE_6_GOTTPOFF, },
282+
{ BFD_RELOC_X86_64_CODE_6_GOTPC32_TLSDESC, R_X86_64_CODE_6_GOTPC32_TLSDESC, },
259283
{ BFD_RELOC_VTABLE_INHERIT, R_X86_64_GNU_VTINHERIT, },
260284
{ BFD_RELOC_VTABLE_ENTRY, R_X86_64_GNU_VTENTRY, },
261285
};
@@ -1283,6 +1307,23 @@ elf_x86_64_check_tls_transition (bfd *abfd,
12831307

12841308
goto check_gottpoff;
12851309

1310+
case R_X86_64_CODE_6_GOTTPOFF:
1311+
/* Check transition from IE access model:
1312+
add %reg1, foo@gottpoff(%rip), %reg2
1313+
where reg1/reg2 are one of r16 to r31. */
1314+
1315+
if (offset < 6
1316+
|| (offset + 4) > sec->size
1317+
|| contents[offset - 6] != 0x62)
1318+
return false;
1319+
1320+
val = bfd_get_8 (abfd, contents + offset - 2);
1321+
if (val != 0x01 && val != 0x03)
1322+
return false;
1323+
1324+
val = bfd_get_8 (abfd, contents + offset - 1);
1325+
return (val & 0xc7) == 5;
1326+
12861327
case R_X86_64_GOTTPOFF:
12871328
/* Check transition from IE access model:
12881329
mov foo@gottpoff(%rip), %reg
@@ -1417,6 +1458,7 @@ elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
14171458
case R_X86_64_TLSDESC_CALL:
14181459
case R_X86_64_GOTTPOFF:
14191460
case R_X86_64_CODE_4_GOTTPOFF:
1461+
case R_X86_64_CODE_6_GOTTPOFF:
14201462
if (bfd_link_executable (info))
14211463
{
14221464
if (h == NULL)
@@ -1464,6 +1506,8 @@ elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
14641506
/* Return TRUE if there is no transition. */
14651507
if (from_type == to_type
14661508
|| (from_type == R_X86_64_CODE_4_GOTTPOFF
1509+
&& to_type == R_X86_64_GOTTPOFF)
1510+
|| (from_type == R_X86_64_CODE_6_GOTTPOFF
14671511
&& to_type == R_X86_64_GOTTPOFF))
14681512
return true;
14691513

@@ -2177,6 +2221,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
21772221

21782222
case R_X86_64_GOTTPOFF:
21792223
case R_X86_64_CODE_4_GOTTPOFF:
2224+
case R_X86_64_CODE_6_GOTTPOFF:
21802225
if (!bfd_link_executable (info))
21812226
info->flags |= DF_STATIC_TLS;
21822227
/* Fall through */
@@ -2214,6 +2259,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
22142259
break;
22152260
case R_X86_64_GOTTPOFF:
22162261
case R_X86_64_CODE_4_GOTTPOFF:
2262+
case R_X86_64_CODE_6_GOTTPOFF:
22172263
tls_type = GOT_TLS_IE;
22182264
break;
22192265
case R_X86_64_GOTPC32_TLSDESC:
@@ -2503,6 +2549,26 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
25032549
}
25042550
break;
25052551

2552+
case R_X86_64_CODE_5_GOTPCRELX:
2553+
case R_X86_64_CODE_5_GOTTPOFF:
2554+
case R_X86_64_CODE_5_GOTPC32_TLSDESC:
2555+
case R_X86_64_CODE_6_GOTPCRELX:
2556+
case R_X86_64_CODE_6_GOTPC32_TLSDESC:
2557+
{
2558+
/* These relocations are added only for completeness and
2559+
aren't be used. */
2560+
if (h)
2561+
name = h->root.root.string;
2562+
else
2563+
name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
2564+
NULL);
2565+
_bfd_error_handler
2566+
/* xgettext:c-format */
2567+
(_("%pB: unsupported relocation %s against symbol `%s'"),
2568+
abfd, x86_64_elf_howto_table[r_type].name, name);
2569+
}
2570+
break;
2571+
25062572
/* This relocation describes the C++ object vtable hierarchy.
25072573
Reconstruct it for later use during GC. */
25082574
case R_X86_64_GNU_VTINHERIT:
@@ -3570,6 +3636,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
35703636
case R_X86_64_TLSDESC_CALL:
35713637
case R_X86_64_GOTTPOFF:
35723638
case R_X86_64_CODE_4_GOTTPOFF:
3639+
case R_X86_64_CODE_6_GOTTPOFF:
35733640
tls_type = GOT_UNKNOWN;
35743641
if (h == NULL && local_got_offsets)
35753642
tls_type = elf_x86_local_got_tls_type (input_bfd) [r_symndx];
@@ -3920,6 +3987,50 @@ elf_x86_64_relocate_section (bfd *output_bfd,
39203987
contents + roff);
39213988
continue;
39223989
}
3990+
else if (r_type == R_X86_64_CODE_6_GOTTPOFF)
3991+
{
3992+
/* IE->LE transition:
3993+
Originally it is
3994+
add %reg1, foo@gottpoff(%rip), %reg2
3995+
or
3996+
add foo@gottpoff(%rip), %reg1, %reg2
3997+
We change it into:
3998+
add $foo@tpoff, %reg1, %reg2
3999+
*/
4000+
unsigned int reg, byte1;
4001+
unsigned int updated_byte1;
4002+
4003+
if (roff < 6)
4004+
goto corrupt_input;
4005+
4006+
/* Move the R bits to the B bits in EVEX payload
4007+
byte 1. */
4008+
byte1 = bfd_get_8 (input_bfd, contents + roff - 5);
4009+
updated_byte1 = byte1;
4010+
4011+
/* Set the R bits since they is inverted. */
4012+
updated_byte1 |= 1 << 7 | 1 << 4;
4013+
4014+
/* Update the B bits from the R bits. */
4015+
if ((byte1 & (1 << 7)) == 0)
4016+
updated_byte1 &= ~(1 << 5);
4017+
if ((byte1 & (1 << 4)) == 0)
4018+
updated_byte1 |= 1 << 3;
4019+
4020+
reg = bfd_get_8 (input_bfd, contents + roff - 1);
4021+
reg >>= 3;
4022+
4023+
bfd_put_8 (output_bfd, updated_byte1,
4024+
contents + roff - 5);
4025+
bfd_put_8 (output_bfd, 0x81,
4026+
contents + roff - 2);
4027+
bfd_put_8 (output_bfd, 0xc0 | reg,
4028+
contents + roff - 1);
4029+
bfd_put_32 (output_bfd,
4030+
elf_x86_64_tpoff (info, relocation),
4031+
contents + roff);
4032+
continue;
4033+
}
39234034
else
39244035
BFD_ASSERT (false);
39254036
}

bfd/libbfd.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,6 +1463,12 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
14631463
"BFD_RELOC_X86_64_CODE_4_GOTPCRELX",
14641464
"BFD_RELOC_X86_64_CODE_4_GOTTPOFF",
14651465
"BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC",
1466+
"BFD_RELOC_X86_64_CODE_5_GOTPCRELX",
1467+
"BFD_RELOC_X86_64_CODE_5_GOTTPOFF",
1468+
"BFD_RELOC_X86_64_CODE_5_GOTPC32_TLSDESC",
1469+
"BFD_RELOC_X86_64_CODE_6_GOTPCRELX",
1470+
"BFD_RELOC_X86_64_CODE_6_GOTTPOFF",
1471+
"BFD_RELOC_X86_64_CODE_6_GOTPC32_TLSDESC",
14661472
"BFD_RELOC_NS32K_IMM_8",
14671473
"BFD_RELOC_NS32K_IMM_16",
14681474
"BFD_RELOC_NS32K_IMM_32",

bfd/reloc.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2481,6 +2481,18 @@ ENUMX
24812481
BFD_RELOC_X86_64_CODE_4_GOTTPOFF
24822482
ENUMX
24832483
BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC
2484+
ENUMX
2485+
BFD_RELOC_X86_64_CODE_5_GOTPCRELX
2486+
ENUMX
2487+
BFD_RELOC_X86_64_CODE_5_GOTTPOFF
2488+
ENUMX
2489+
BFD_RELOC_X86_64_CODE_5_GOTPC32_TLSDESC
2490+
ENUMX
2491+
BFD_RELOC_X86_64_CODE_6_GOTPCRELX
2492+
ENUMX
2493+
BFD_RELOC_X86_64_CODE_6_GOTTPOFF
2494+
ENUMX
2495+
BFD_RELOC_X86_64_CODE_6_GOTPC32_TLSDESC
24842496
ENUMDOC
24852497
x86-64/elf relocations.
24862498

elfcpp/x86_64.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,30 @@ enum
110110
// descriptor in GOT if the
111111
// instruction starts at 4 bytes
112112
// before the relocation offset.
113+
R_X86_64_CODE_5_GOTPCRELX = 46, // 32 bit signed PC relative offset to
114+
// GOT if the instruction starts at 5
115+
// bytes before the relocation offset,
116+
// relaxable.
117+
R_X86_64_CODE_5_GOTTPOFF = 47, // 32 bit signed PC relative offset to
118+
// GOT entry for IE symbol if the
119+
// instruction starts at 5 bytes before
120+
// the relocation offset.
121+
R_X86_64_CODE_5_GOTPC32_TLSDESC = 48, // 32-bit PC relative to TLS
122+
// descriptor in GOT if the
123+
// instruction starts at 5 bytes
124+
// before the relocation offset.
125+
R_X86_64_CODE_6_GOTPCRELX = 49, // 32 bit signed PC relative offset to
126+
// GOT if the instruction starts at 6
127+
// bytes before the relocation offset,
128+
// relaxable.
129+
R_X86_64_CODE_6_GOTTPOFF = 50, // 32 bit signed PC relative offset to
130+
// GOT entry for IE symbol if the
131+
// instruction starts at 6 bytes before
132+
// the relocation offset.
133+
R_X86_64_CODE_6_GOTPC32_TLSDESC = 51, // 32-bit PC relative to TLS
134+
// descriptor in GOT if the
135+
// instruction starts at 6 bytes
136+
// before the relocation offset.
113137
// GNU vtable garbage collection extensions.
114138
R_X86_64_GNU_VTINHERIT = 250,
115139
R_X86_64_GNU_VTENTRY = 251

0 commit comments

Comments
 (0)