aboutsummaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2024-02-03 14:32:17 -0800
committerH.J. Lu <hjl.tools@gmail.com>2024-02-08 03:45:43 -0800
commit5bc71c2a6b8efb27089baa1fecded82be4f550a7 (patch)
tree10dfffcc5c12eaddca36a98b8e55e049592b6283 /gold
parent3f8f9745c75b333515f399fc2908ede2ed8014e9 (diff)
downloadgdb-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.s2
-rwxr-xr-xgold/testsuite/x86_64_ie_to_le.sh2
-rw-r--r--gold/x86_64.cc47
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();