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 /gold | |
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 'gold')
-rw-r--r-- | gold/testsuite/x86_64_ie_to_le.s | 2 | ||||
-rwxr-xr-x | gold/testsuite/x86_64_ie_to_le.sh | 2 | ||||
-rw-r--r-- | gold/x86_64.cc | 47 |
3 files changed, 47 insertions, 4 deletions
diff --git a/gold/testsuite/x86_64_ie_to_le.s b/gold/testsuite/x86_64_ie_to_le.s index c575206..bd0643d 100644 --- a/gold/testsuite/x86_64_ie_to_le.s +++ b/gold/testsuite/x86_64_ie_to_le.s @@ -7,6 +7,8 @@ _start: movq foo@gottpoff(%rip), %rax addq foo@gottpoff(%rip), %r16 movq foo@gottpoff(%rip), %r20 + addq %r30, foo@gottpoff(%rip), %r8 + addq foo@gottpoff(%rip), %rax, %r20 .size _start, .-_start .section .tdata,"awT",@progbits .align 4 diff --git a/gold/testsuite/x86_64_ie_to_le.sh b/gold/testsuite/x86_64_ie_to_le.sh index 9d2e082..5308712 100755 --- a/gold/testsuite/x86_64_ie_to_le.sh +++ b/gold/testsuite/x86_64_ie_to_le.sh @@ -27,3 +27,5 @@ grep -q "add[ \t]\+\$0x[a-f0-9]\+,%r12" x86_64_ie_to_le.stdout grep -q "mov[ \t]\+\$0x[a-f0-9]\+,%rax" x86_64_ie_to_le.stdout grep -q "add[ \t]\+\$0x[a-f0-9]\+,%r16" x86_64_ie_to_le.stdout grep -q "mov[ \t]\+\$0x[a-f0-9]\+,%r20" x86_64_ie_to_le.stdout +grep -q "add[ \t]\+\$0x[a-f0-9]\+,%r30,%r8" x86_64_ie_to_le.stdout +grep -q "add[ \t]\+\$0x[a-f0-9]\+,%rax,%r20" x86_64_ie_to_le.stdout diff --git a/gold/x86_64.cc b/gold/x86_64.cc index 58e191a..f77430b 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -2920,6 +2920,11 @@ Target_x86_64<size>::optimize_tls_reloc(bool is_final, int r_type, // 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(bool is_final, int r_type, // 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_flags(unsigned int r_type) 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_table* symtab, // 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_table* symtab, // 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_table* symtab, 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_tls( 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_le( // 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_le( 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_le( 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(); |