diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2024-02-03 14:32:17 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2024-02-08 03:45:43 -0800 |
commit | 5bc71c2a6b8efb27089baa1fecded82be4f550a7 (patch) | |
tree | 10dfffcc5c12eaddca36a98b8e55e049592b6283 /gas | |
parent | 3f8f9745c75b333515f399fc2908ede2ed8014e9 (diff) | |
download | gdb-5bc71c2a6b8efb27089baa1fecded82be4f550a7.zip gdb-5bc71c2a6b8efb27089baa1fecded82be4f550a7.tar.gz gdb-5bc71c2a6b8efb27089baa1fecded82be4f550a7.tar.bz2 |
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.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/config/tc-i386.c | 102 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-gottpoff.d | 4 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-gottpoff.s | 10 |
3 files changed, 94 insertions, 22 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 50d890c..9e7bb1d 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -3648,6 +3648,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 @@ -6795,10 +6796,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; @@ -12040,6 +12050,7 @@ output_disp (fragS *insn_start_frag, offsetT insn_start_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: @@ -12056,9 +12067,30 @@ output_disp (fragS *insn_start_frag, offsetT insn_start_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 @@ -12083,10 +12115,22 @@ output_disp (fragS *insn_start_frag, offsetT insn_start_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; @@ -15563,6 +15607,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) 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. */ @@ -17144,13 +17189,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) @@ -17162,15 +17221,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; @@ -17296,6 +17352,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) 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: @@ -17440,6 +17497,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) 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 --git a/gas/testsuite/gas/i386/x86-64-gottpoff.d b/gas/testsuite/gas/i386/x86-64-gottpoff.d index d42abcc..f2c039a 100644 --- a/gas/testsuite/gas/i386/x86-64-gottpoff.d +++ b/gas/testsuite/gas/i386/x86-64-gottpoff.d @@ -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 --git a/gas/testsuite/gas/i386/x86-64-gottpoff.s b/gas/testsuite/gas/i386/x86-64-gottpoff.s index 6f8f9d1..0335ec5 100644 --- a/gas/testsuite/gas/i386/x86-64-gottpoff.s +++ b/gas/testsuite/gas/i386/x86-64-gottpoff.s @@ -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] |