[X86][LLD] Handle R_X86_64_CODE_6_GOTTPOFF relocation type (#117675)
For add %reg1, name@GOTTPOFF(%rip), %reg2 add name@GOTTPOFF(%rip), %reg1, %reg2 {nf} add %reg1, name@GOTTPOFF(%rip), %reg2 {nf} add name@GOTTPOFF(%rip), %reg1, %reg2 {nf} add name@GOTTPOFF(%rip), %reg add R_X86_64_CODE_6_GOTTPOFF = 50 in #117277. Linker can treat R_X86_64_CODE_6_GOTTPOFF as R_X86_64_GOTTPOFF or convert the instructions above to add $name@tpoff, %reg1, %reg2 add $name@tpoff, %reg1, %reg2 {nf} add $name@tpoff, %reg1, %reg2 {nf} add $name@tpoff, %reg1, %reg2 {nf} add $name@tpoff, %reg if the first byte of the instruction at the relocation offset - 6 is 0x62 (namely, encoded w/EVEX prefix) when possible. Binutils patch: bminor/binutils-gdb@5bc71c2 Binutils mailthread: https://sourceware.org/pipermail/binutils/2024-February/132351.html ABI discussion: https://groups.google.com/g/x86-64-abi/c/FhEZjCtDLFw/m/VHDjN4orAgAJ Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation
This commit is contained in:
parent
a9a4a83b61
commit
636beb6a28
@ -401,6 +401,7 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s,
|
|||||||
case R_X86_64_CODE_4_GOTPCRELX:
|
case R_X86_64_CODE_4_GOTPCRELX:
|
||||||
case R_X86_64_GOTTPOFF:
|
case R_X86_64_GOTTPOFF:
|
||||||
case R_X86_64_CODE_4_GOTTPOFF:
|
case R_X86_64_CODE_4_GOTTPOFF:
|
||||||
|
case R_X86_64_CODE_6_GOTTPOFF:
|
||||||
return R_GOT_PC;
|
return R_GOT_PC;
|
||||||
case R_X86_64_GOTOFF64:
|
case R_X86_64_GOTOFF64:
|
||||||
return R_GOTPLTREL;
|
return R_GOTPLTREL;
|
||||||
@ -562,8 +563,9 @@ void X86_64::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// In some conditions, R_X86_64_GOTTPOFF/R_X86_64_CODE_4_GOTTPOFF relocation can
|
// In some conditions,
|
||||||
// be optimized to R_X86_64_TPOFF32 so that it does not use GOT.
|
// R_X86_64_GOTTPOFF/R_X86_64_CODE_4_GOTTPOFF/R_X86_64_CODE_6_GOTTPOFF
|
||||||
|
// relocation can be optimized to R_X86_64_TPOFF32 so that it does not use GOT.
|
||||||
void X86_64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
|
void X86_64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
|
||||||
uint64_t val) const {
|
uint64_t val) const {
|
||||||
uint8_t *inst = loc - 3;
|
uint8_t *inst = loc - 3;
|
||||||
@ -605,7 +607,7 @@ void X86_64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
|
|||||||
} else if (rel.type == R_X86_64_CODE_4_GOTTPOFF) {
|
} else if (rel.type == R_X86_64_CODE_4_GOTTPOFF) {
|
||||||
if (loc[-4] != 0xd5) {
|
if (loc[-4] != 0xd5) {
|
||||||
Err(ctx) << getErrorLoc(ctx, loc - 4)
|
Err(ctx) << getErrorLoc(ctx, loc - 4)
|
||||||
<< "Invalid prefix with R_X86_64_CODE_4_GOTTPOFF!";
|
<< "invalid prefix with R_X86_64_CODE_4_GOTTPOFF!";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const uint8_t rex = loc[-3];
|
const uint8_t rex = loc[-3];
|
||||||
@ -623,6 +625,41 @@ void X86_64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel,
|
|||||||
<< "R_X86_64_CODE_4_GOTTPOFF must be used in MOVQ or ADDQ "
|
<< "R_X86_64_CODE_4_GOTTPOFF must be used in MOVQ or ADDQ "
|
||||||
"instructions only";
|
"instructions only";
|
||||||
}
|
}
|
||||||
|
} else if (rel.type == R_X86_64_CODE_6_GOTTPOFF) {
|
||||||
|
if (loc[-6] != 0x62) {
|
||||||
|
Err(ctx) << getErrorLoc(ctx, loc - 6)
|
||||||
|
<< "invalid prefix with R_X86_64_CODE_6_GOTTPOFF!";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Check bits are satisfied:
|
||||||
|
// loc[-5]: X==1 (inverted polarity), (loc[-5] & 0x7) == 0x4
|
||||||
|
// loc[-4]: W==1, X2==1 (inverted polarity), pp==0b00(NP)
|
||||||
|
// loc[-3]: NF==1 or ND==1
|
||||||
|
// loc[-2]: opcode==0x1 or opcode==0x3
|
||||||
|
// loc[-1]: Mod==0b00, RM==0b101
|
||||||
|
if (((loc[-5] & 0x47) == 0x44) && ((loc[-4] & 0x87) == 0x84) &&
|
||||||
|
((loc[-3] & 0x14) != 0) && (loc[-2] == 0x1 || loc[-2] == 0x3) &&
|
||||||
|
((loc[-1] & 0xc7) == 0x5)) {
|
||||||
|
// "addq %reg1, foo@GOTTPOFF(%rip), %reg2" -> "addq $foo, %reg1, %reg2"
|
||||||
|
// "addq foo@GOTTPOFF(%rip), %reg1, %reg2" -> "addq $foo, %reg1, %reg2"
|
||||||
|
// "{nf} addq %reg1, foo@GOTTPOFF(%rip), %reg2"
|
||||||
|
// -> "{nf} addq $foo, %reg1, %reg2"
|
||||||
|
// "{nf} addq name@GOTTPOFF(%rip), %reg1, %reg2"
|
||||||
|
// -> "{nf} addq $foo, %reg1, %reg2"
|
||||||
|
// "{nf} addq name@GOTTPOFF(%rip), %reg" -> "{nf} addq $foo, %reg"
|
||||||
|
loc[-2] = 0x81;
|
||||||
|
// Move R bits to B bits in EVEX payloads and ModRM byte.
|
||||||
|
const uint8_t evexPayload0 = loc[-5];
|
||||||
|
if ((evexPayload0 & (1 << 7)) == 0)
|
||||||
|
loc[-5] = (evexPayload0 | (1 << 7)) & ~(1 << 5);
|
||||||
|
if ((evexPayload0 & (1 << 4)) == 0)
|
||||||
|
loc[-5] = evexPayload0 | (1 << 4) | (1 << 3);
|
||||||
|
*regSlot = 0xc0 | reg;
|
||||||
|
} else {
|
||||||
|
Err(ctx) << getErrorLoc(ctx, loc - 6)
|
||||||
|
<< "R_X86_64_CODE_6_GOTTPOFF must be used in ADDQ instructions "
|
||||||
|
"with NDD/NF/NDD+NF only";
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
llvm_unreachable("Unsupported relocation type!");
|
llvm_unreachable("Unsupported relocation type!");
|
||||||
}
|
}
|
||||||
@ -782,6 +819,7 @@ int64_t X86_64::getImplicitAddend(const uint8_t *buf, RelType type) const {
|
|||||||
case R_X86_64_PC32:
|
case R_X86_64_PC32:
|
||||||
case R_X86_64_GOTTPOFF:
|
case R_X86_64_GOTTPOFF:
|
||||||
case R_X86_64_CODE_4_GOTTPOFF:
|
case R_X86_64_CODE_4_GOTTPOFF:
|
||||||
|
case R_X86_64_CODE_6_GOTTPOFF:
|
||||||
case R_X86_64_PLT32:
|
case R_X86_64_PLT32:
|
||||||
case R_X86_64_TLSGD:
|
case R_X86_64_TLSGD:
|
||||||
case R_X86_64_TLSLD:
|
case R_X86_64_TLSLD:
|
||||||
@ -893,6 +931,7 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
|
|||||||
break;
|
break;
|
||||||
case R_X86_64_GOTTPOFF:
|
case R_X86_64_GOTTPOFF:
|
||||||
case R_X86_64_CODE_4_GOTTPOFF:
|
case R_X86_64_CODE_4_GOTTPOFF:
|
||||||
|
case R_X86_64_CODE_6_GOTTPOFF:
|
||||||
if (rel.expr == R_RELAX_TLS_IE_TO_LE) {
|
if (rel.expr == R_RELAX_TLS_IE_TO_LE) {
|
||||||
relaxTlsIeToLe(loc, rel, val);
|
relaxTlsIeToLe(loc, rel, val);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
# REQUIRES: x86
|
# REQUIRES: x86
|
||||||
|
|
||||||
# RUN: yaml2obj %s -o %t.o
|
# RUN: yaml2obj --docnum=1 %s -o %t1.o
|
||||||
# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck --check-prefix=ERR %s
|
# RUN: not ld.lld %t1.o -o /dev/null 2>&1 | FileCheck --check-prefix=ERR %s
|
||||||
# ERR: R_X86_64_GOTTPOFF must be used in MOVQ or ADDQ instructions only
|
# ERR: error: {{.*}}: R_X86_64_GOTTPOFF must be used in MOVQ or ADDQ instructions only
|
||||||
# ERR: R_X86_64_GOTTPOFF must be used in MOVQ or ADDQ instructions only
|
# ERR: error: {{.*}}: R_X86_64_GOTTPOFF must be used in MOVQ or ADDQ instructions only
|
||||||
|
|
||||||
## YAML below contains 2 relocations of type R_X86_64_GOTTPOFF, and a .text
|
## YAML below contains 2 relocations of type R_X86_64_GOTTPOFF, and a .text
|
||||||
## with fake content filled by 0xFF. That means instructions for relaxation are
|
## with fake content filled by 0xFF. That means instructions for relaxation are
|
||||||
## "broken", so they does not match any known valid relaxations. We also generate
|
## "broken", so they does not match any known valid relaxations. We also generate
|
||||||
## .tls section because we need it for correct processing of STT_TLS symbol.
|
## .tls section because we need it for correct processing of STT_TLS symbol.
|
||||||
!ELF
|
--- !ELF
|
||||||
FileHeader:
|
FileHeader:
|
||||||
Class: ELFCLASS64
|
Class: ELFCLASS64
|
||||||
Data: ELFDATA2LSB
|
Data: ELFDATA2LSB
|
||||||
@ -44,4 +44,131 @@ Symbols:
|
|||||||
Value: 0x12345
|
Value: 0x12345
|
||||||
Size: 4
|
Size: 4
|
||||||
Binding: STB_GLOBAL
|
Binding: STB_GLOBAL
|
||||||
|
|
||||||
|
|
||||||
|
# RUN: yaml2obj --docnum=2 %s -o %t2.o
|
||||||
|
# RUN: not ld.lld %t2.o -o /dev/null 2>&1 | FileCheck --check-prefix=ERR2 %s
|
||||||
|
# ERR2: error: {{.*}}: invalid prefix with R_X86_64_CODE_4_GOTTPOFF!
|
||||||
|
# ERR2: error: {{.*}}: invalid prefix with R_X86_64_CODE_6_GOTTPOFF!
|
||||||
|
|
||||||
|
## YAML below contains 2 relocations of
|
||||||
|
## R_X86_64_CODE_4_GOTTPOFF/R_X86_64_CODE_6_GOTTPOFF type, and a .text with
|
||||||
|
## fake content filled by 0xFF. It's expected to get "invalid prefix" error
|
||||||
|
## message as above.
|
||||||
|
--- !ELF
|
||||||
|
FileHeader:
|
||||||
|
Class: ELFCLASS64
|
||||||
|
Data: ELFDATA2LSB
|
||||||
|
OSABI: ELFOSABI_FREEBSD
|
||||||
|
Type: ET_REL
|
||||||
|
Machine: EM_X86_64
|
||||||
|
Sections:
|
||||||
|
- Type: SHT_PROGBITS
|
||||||
|
Name: .text
|
||||||
|
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||||
|
AddressAlign: 0x04
|
||||||
|
Content: "FFFFFFFFFFFFFFFFFFFF"
|
||||||
|
- Type: SHT_PROGBITS
|
||||||
|
Name: .tls
|
||||||
|
Flags: [ SHF_ALLOC, SHF_TLS ]
|
||||||
|
- Type: SHT_REL
|
||||||
|
Name: .rel.text
|
||||||
|
Link: .symtab
|
||||||
|
Info: .text
|
||||||
|
AddressAlign: 0x04
|
||||||
|
Relocations:
|
||||||
|
- Offset: 4
|
||||||
|
Symbol: foo
|
||||||
|
Type: R_X86_64_CODE_4_GOTTPOFF
|
||||||
|
- Offset: 6
|
||||||
|
Symbol: foo
|
||||||
|
Type: R_X86_64_CODE_6_GOTTPOFF
|
||||||
|
Symbols:
|
||||||
|
- Name: foo
|
||||||
|
Type: STT_TLS
|
||||||
|
Section: .text
|
||||||
|
Value: 0x12345
|
||||||
|
Size: 4
|
||||||
|
Binding: STB_GLOBAL
|
||||||
|
|
||||||
|
|
||||||
|
# RUN: yaml2obj --docnum=3 %s -o %t3.o
|
||||||
|
# RUN: not ld.lld %t3.o -o /dev/null 2>&1 | FileCheck --check-prefix=ERR3 %s
|
||||||
|
# ERR3: error: {{.*}}: R_X86_64_CODE_4_GOTTPOFF must be used in MOVQ or ADDQ instructions only
|
||||||
|
|
||||||
|
## YAML below contains R_X86_64_CODE_4_GOTTPOFF relocation type, and a .text
|
||||||
|
## with fake content filled by 0xd5, 0xFF, ... and 0xFF. It's expected to get
|
||||||
|
## the error message as above.
|
||||||
|
--- !ELF
|
||||||
|
FileHeader:
|
||||||
|
Class: ELFCLASS64
|
||||||
|
Data: ELFDATA2LSB
|
||||||
|
OSABI: ELFOSABI_FREEBSD
|
||||||
|
Type: ET_REL
|
||||||
|
Machine: EM_X86_64
|
||||||
|
Sections:
|
||||||
|
- Type: SHT_PROGBITS
|
||||||
|
Name: .text
|
||||||
|
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||||
|
AddressAlign: 0x04
|
||||||
|
Content: "d5FFFFFFFFFFFFFFFFFF"
|
||||||
|
- Type: SHT_PROGBITS
|
||||||
|
Name: .tls
|
||||||
|
Flags: [ SHF_ALLOC, SHF_TLS ]
|
||||||
|
- Type: SHT_REL
|
||||||
|
Name: .rel.text
|
||||||
|
Link: .symtab
|
||||||
|
Info: .text
|
||||||
|
AddressAlign: 0x04
|
||||||
|
Relocations:
|
||||||
|
- Offset: 4
|
||||||
|
Symbol: foo
|
||||||
|
Type: R_X86_64_CODE_4_GOTTPOFF
|
||||||
|
Symbols:
|
||||||
|
- Name: foo
|
||||||
|
Type: STT_TLS
|
||||||
|
Section: .text
|
||||||
|
Value: 0x12345
|
||||||
|
Size: 4
|
||||||
|
Binding: STB_GLOBAL
|
||||||
|
|
||||||
|
|
||||||
|
# RUN: yaml2obj --docnum=4 %s -o %t4.o
|
||||||
|
# RUN: not ld.lld %t4.o -o /dev/null 2>&1 | FileCheck --check-prefix=ERR4 %s
|
||||||
|
# ERR4: error: {{.*}}: R_X86_64_CODE_6_GOTTPOFF must be used in ADDQ instructions with NDD/NF/NDD+NF only
|
||||||
|
|
||||||
|
## YAML below contains R_X86_64_CODE_6_GOTTPOFF relocation type, and a .text
|
||||||
|
## with fake content filled by 0x62, 0xFF, ... and 0xFF. It's expected to get
|
||||||
|
## the error message as above.
|
||||||
|
--- !ELF
|
||||||
|
FileHeader:
|
||||||
|
Class: ELFCLASS64
|
||||||
|
Data: ELFDATA2LSB
|
||||||
|
OSABI: ELFOSABI_FREEBSD
|
||||||
|
Type: ET_REL
|
||||||
|
Machine: EM_X86_64
|
||||||
|
Sections:
|
||||||
|
- Type: SHT_PROGBITS
|
||||||
|
Name: .text
|
||||||
|
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||||
|
AddressAlign: 0x04
|
||||||
|
Content: "62FFFFFFFFFFFFFFFFFF"
|
||||||
|
- Type: SHT_PROGBITS
|
||||||
|
Name: .tls
|
||||||
|
Flags: [ SHF_ALLOC, SHF_TLS ]
|
||||||
|
- Type: SHT_REL
|
||||||
|
Name: .rel.text
|
||||||
|
Link: .symtab
|
||||||
|
Info: .text
|
||||||
|
AddressAlign: 0x04
|
||||||
|
Relocations:
|
||||||
|
- Offset: 6
|
||||||
|
Symbol: foo
|
||||||
|
Type: R_X86_64_CODE_6_GOTTPOFF
|
||||||
|
Symbols:
|
||||||
|
- Name: foo
|
||||||
|
Type: STT_TLS
|
||||||
|
Section: .text
|
||||||
|
Value: 0x12345
|
||||||
|
Size: 4
|
||||||
|
Binding: STB_GLOBAL
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
foo:
|
foo:
|
||||||
movq tlsvar@GOTTPOFF(%rip), %rcx
|
movq tlsvar@GOTTPOFF(%rip), %rcx
|
||||||
movq tlsvar2@GOTTPOFF(%rip), %r31
|
movq tlsvar2@GOTTPOFF(%rip), %r31
|
||||||
|
addq tlsvar3@GOTTPOFF(%rip), %rcx, %r16
|
||||||
|
|
||||||
|
|
||||||
.section .tdata,"awT",@progbits
|
.section .tdata,"awT",@progbits
|
||||||
@ -21,7 +22,11 @@ tlsvar:
|
|||||||
.word 42
|
.word 42
|
||||||
tlsvar2:
|
tlsvar2:
|
||||||
.word 42
|
.word 42
|
||||||
|
tlsvar3:
|
||||||
|
.word 42
|
||||||
|
|
||||||
// CHECK: Section ({{.+}}) .rela.dyn {
|
// CHECK: Section ({{.+}}) .rela.dyn {
|
||||||
// CHECK-NEXT: R_X86_64_TPOFF64 - 0x1234
|
// CHECK-NEXT: R_X86_64_TPOFF64 - 0x1234
|
||||||
// CHECK-NEXT: R_X86_64_TPOFF64 - 0x1236
|
// CHECK-NEXT: R_X86_64_TPOFF64 - 0x1236
|
||||||
|
// CHECK-NEXT: R_X86_64_TPOFF64 - 0x1238
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
|
@ -20,12 +20,25 @@
|
|||||||
// DISASM-NEXT: leaq -4(%r15), %r15
|
// DISASM-NEXT: leaq -4(%r15), %r15
|
||||||
// DISASM-NEXT: addq $-4, %rsp
|
// DISASM-NEXT: addq $-4, %rsp
|
||||||
// DISASM-NEXT: addq $-4, %r12
|
// DISASM-NEXT: addq $-4, %r12
|
||||||
|
# EGPR
|
||||||
// DISASM-NEXT: movq $-8, %r16
|
// DISASM-NEXT: movq $-8, %r16
|
||||||
// DISASM-NEXT: movq $-8, %r20
|
// DISASM-NEXT: movq $-8, %r20
|
||||||
// DISASM-NEXT: movq $-4, %r16
|
// DISASM-NEXT: movq $-4, %r16
|
||||||
// DISASM-NEXT: addq $-8, %r16
|
// DISASM-NEXT: addq $-8, %r16
|
||||||
// DISASM-NEXT: addq $-8, %r28
|
// DISASM-NEXT: addq $-8, %r28
|
||||||
// DISASM-NEXT: addq $-4, %r16
|
// DISASM-NEXT: addq $-4, %r16
|
||||||
|
# NDD
|
||||||
|
// DISASM-NEXT: addq $-10, %r16, %r16
|
||||||
|
// DISASM-NEXT: addq $-10, %r16, %r20
|
||||||
|
// DISASM-NEXT: addq $-10, %r16, %rax
|
||||||
|
// DISASM-NEXT: addq $-10, %rax, %r16
|
||||||
|
// DISASM-NEXT: addq $-10, %r8, %r16
|
||||||
|
// DISASM-NEXT: addq $-10, %rax, %r12
|
||||||
|
# NDD + NF
|
||||||
|
// DISASM-NEXT: {nf} addq $-10, %r8, %r16
|
||||||
|
// DISASM-NEXT: {nf} addq $-10, %rax, %r12
|
||||||
|
# NF
|
||||||
|
// DISASM-NEXT: {nf} addq $-10, %r12
|
||||||
|
|
||||||
// LD to LE:
|
// LD to LE:
|
||||||
// DISASM-NEXT: movq %fs:0, %rax
|
// DISASM-NEXT: movq %fs:0, %rax
|
||||||
@ -82,6 +95,18 @@ _start:
|
|||||||
addq tls0@GOTTPOFF(%rip), %r16
|
addq tls0@GOTTPOFF(%rip), %r16
|
||||||
addq tls0@GOTTPOFF(%rip), %r28
|
addq tls0@GOTTPOFF(%rip), %r28
|
||||||
addq tls1@GOTTPOFF(%rip), %r16
|
addq tls1@GOTTPOFF(%rip), %r16
|
||||||
|
# NDD
|
||||||
|
addq tls0@GOTTPOFF(%rip), %r16, %r16
|
||||||
|
addq tls0@GOTTPOFF(%rip), %r16, %r20
|
||||||
|
addq tls0@GOTTPOFF(%rip), %r16, %rax
|
||||||
|
addq tls0@GOTTPOFF(%rip), %rax, %r16
|
||||||
|
addq %r8, tls0@GOTTPOFF(%rip), %r16
|
||||||
|
addq tls0@GOTTPOFF(%rip), %rax, %r12
|
||||||
|
# NDD + NF
|
||||||
|
{nf} addq %r8, tls0@GOTTPOFF(%rip), %r16
|
||||||
|
{nf} addq tls0@GOTTPOFF(%rip), %rax, %r12
|
||||||
|
# NF
|
||||||
|
{nf} addq tls0@GOTTPOFF(%rip), %r12
|
||||||
|
|
||||||
// LD to LE
|
// LD to LE
|
||||||
leaq tls0@tlsld(%rip), %rdi
|
leaq tls0@tlsld(%rip), %rdi
|
||||||
|
35
lld/test/ELF/x86-64-tls-ie-err.s
Normal file
35
lld/test/ELF/x86-64-tls-ie-err.s
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# REQUIRES: x86
|
||||||
|
# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
|
||||||
|
# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck -DFILE=%t.o %s
|
||||||
|
|
||||||
|
# CHECK: error: [[FILE]]:(.text+0x2): invalid prefix with R_X86_64_CODE_4_GOTTPOFF!
|
||||||
|
# CHECK-NEXT: error: [[FILE]]:(.text+0x8): invalid prefix with R_X86_64_CODE_6_GOTTPOFF!
|
||||||
|
# CHECK-NEXT: error: [[FILE]]:(.text+0x12): R_X86_64_CODE_4_GOTTPOFF must be used in MOVQ or ADDQ instructions only
|
||||||
|
# CHECK-NEXT: error: [[FILE]]:(.text+0x1a): R_X86_64_CODE_6_GOTTPOFF must be used in ADDQ instructions with NDD/NF/NDD+NF only
|
||||||
|
|
||||||
|
## These negative tests are to check if the invalid prefix and unsupported
|
||||||
|
## instructions for TLS relocation types with APX instructions are handled as
|
||||||
|
## errors.
|
||||||
|
|
||||||
|
.type tls0,@object
|
||||||
|
.section .tbss,"awT",@nobits
|
||||||
|
.globl tls0
|
||||||
|
.align 4
|
||||||
|
tls0:
|
||||||
|
.long 0
|
||||||
|
.size tls0, 4
|
||||||
|
|
||||||
|
.text
|
||||||
|
.globl _start
|
||||||
|
_start:
|
||||||
|
addq 0(%rip), %rax, %r16
|
||||||
|
.reloc .-4, R_X86_64_CODE_4_GOTTPOFF, tls0-4
|
||||||
|
|
||||||
|
movq 0(%rip), %r16
|
||||||
|
.reloc .-4, R_X86_64_CODE_6_GOTTPOFF, tls0-4
|
||||||
|
|
||||||
|
andq 0(%rip), %r16
|
||||||
|
.reloc .-4, R_X86_64_CODE_4_GOTTPOFF, tls0-4
|
||||||
|
|
||||||
|
andq 0(%rip), %rax, %r16
|
||||||
|
.reloc .-4, R_X86_64_CODE_6_GOTTPOFF, tls0-4
|
@ -5,29 +5,47 @@
|
|||||||
# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=REL %s
|
# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=REL %s
|
||||||
# RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %t.so | FileCheck %s
|
# RUN: llvm-objdump --no-print-imm-hex -d --no-show-raw-insn %t.so | FileCheck %s
|
||||||
|
|
||||||
# SEC: .got PROGBITS 0000000000002348 000348 000010 00 WA 0 0 8
|
# SEC: .got PROGBITS 0000000000002378 000378 000010 00 WA 0 0 8
|
||||||
|
|
||||||
## Dynamic relocations for non-preemptable symbols in a shared object have section index 0.
|
## Dynamic relocations for non-preemptable symbols in a shared object have section index 0.
|
||||||
# REL: .rela.dyn {
|
# REL: .rela.dyn {
|
||||||
# REL-NEXT: 0x2348 R_X86_64_TPOFF64 - 0x0
|
# REL-NEXT: 0x2378 R_X86_64_TPOFF64 - 0x0
|
||||||
# REL-NEXT: 0x2350 R_X86_64_TPOFF64 - 0x4
|
# REL-NEXT: 0x2380 R_X86_64_TPOFF64 - 0x4
|
||||||
# REL-NEXT: }
|
# REL-NEXT: }
|
||||||
|
|
||||||
## &.got[0] - 0x127f = 0x2348 - 0x127f = 4297
|
## &.got[0] - 0x127f = 0x2378 - 0x127f = 4345
|
||||||
## &.got[1] - 0x1286 = 0x2350 - 0x1286 = 4298
|
## &.got[1] - 0x1286 = 0x2380 - 0x1286 = 4346
|
||||||
## &.got[2] - 0x128e = 0x2348 - 0x128e = 4282
|
## &.got[2] - 0x128e = 0x2378 - 0x128e = 4330
|
||||||
## &.got[3] - 0x1296 = 0x2350 - 0x1296 = 4282
|
## &.got[3] - 0x1296 = 0x2380 - 0x1296 = 4330
|
||||||
|
## &.got[0] - 0x12a0 = 0x2376 - 0x12a0 = 4310
|
||||||
|
## &.got[1] - 0x12aa = 0x237e - 0x12aa = 4308
|
||||||
|
## &.got[0] - 0x12b4 = 0x2376 - 0x12b4 = 4290
|
||||||
|
## &.got[1] - 0x12be = 0x237e - 0x12be = 4288
|
||||||
|
## &.got[0] - 0x12c8 = 0x2376 - 0x12c8 = 4270
|
||||||
|
|
||||||
# CHECK: 1278: addq 4297(%rip), %rax
|
# CHECK: 1278: addq 4345(%rip), %rax
|
||||||
# CHECK-NEXT: 127f: addq 4298(%rip), %rax
|
# CHECK-NEXT: 127f: addq 4346(%rip), %rax
|
||||||
# CHECK-NEXT: 1286: addq 4282(%rip), %r16
|
# CHECK-NEXT: 1286: addq 4330(%rip), %r16
|
||||||
# CHECK-NEXT: 128e: addq 4282(%rip), %r16
|
# CHECK-NEXT: 128e: addq 4330(%rip), %r16
|
||||||
|
# CHECK-NEXT: 1296: addq %r8, 4310(%rip), %r16
|
||||||
|
# CHECK-NEXT: 12a0: addq 4308(%rip), %rax, %r12
|
||||||
|
# CHECK-NEXT: 12aa: {nf} addq %r8, 4290(%rip), %r16
|
||||||
|
# CHECK-NEXT: 12b4: {nf} addq 4288(%rip), %rax, %r12
|
||||||
|
# CHECK-NEXT: 12be: {nf} addq 4270(%rip), %r12
|
||||||
|
|
||||||
addq foo@GOTTPOFF(%rip), %rax
|
addq foo@GOTTPOFF(%rip), %rax
|
||||||
addq bar@GOTTPOFF(%rip), %rax
|
addq bar@GOTTPOFF(%rip), %rax
|
||||||
|
# EGPR
|
||||||
addq foo@GOTTPOFF(%rip), %r16
|
addq foo@GOTTPOFF(%rip), %r16
|
||||||
addq bar@GOTTPOFF(%rip), %r16
|
addq bar@GOTTPOFF(%rip), %r16
|
||||||
|
# NDD
|
||||||
|
addq %r8, foo@GOTTPOFF(%rip), %r16
|
||||||
|
addq bar@GOTTPOFF(%rip), %rax, %r12
|
||||||
|
# NDD + NF
|
||||||
|
{nf} addq %r8, foo@GOTTPOFF(%rip), %r16
|
||||||
|
{nf} addq bar@GOTTPOFF(%rip), %rax, %r12
|
||||||
|
# NF
|
||||||
|
{nf} addq foo@GOTTPOFF(%rip), %r12
|
||||||
|
|
||||||
.section .tbss,"awT",@nobits
|
.section .tbss,"awT",@nobits
|
||||||
foo:
|
foo:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user