Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/test/Driver/relax.s
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@
// RUN: llvm-readobj -r %t | FileCheck --check-prefix=REL %s

// REL: R_X86_64_REX_GOTPCRELX foo
// REL: R_X86_64_REX2_GOTPCRELX foo

movq foo@GOTPCREL(%rip), %rax
movq foo@GOTPCREL(%rip), %r16
1 change: 1 addition & 0 deletions llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ ELF_RELOC(R_X86_64_TLSDESC, 36)
ELF_RELOC(R_X86_64_IRELATIVE, 37)
ELF_RELOC(R_X86_64_GOTPCRELX, 41)
ELF_RELOC(R_X86_64_REX_GOTPCRELX, 42)
ELF_RELOC(R_X86_64_REX2_GOTPCRELX, 43)
4 changes: 2 additions & 2 deletions llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ llvm::mc::RegisterMCTargetOptionsFlags::RegisterMCTargetOptionsFlags() {

static cl::opt<bool> X86RelaxRelocations(
"x86-relax-relocations",
cl::desc(
"Emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL on x86-64 ELF"),
cl::desc("Emit GOTPCRELX/REX_GOTPCRELX/REX2_GOTPCRELX instead of "
"GOTPCREL on x86-64 ELF"),
cl::init(true));
MCBINDOPT(X86RelaxRelocations);

Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -629,15 +629,19 @@ std::optional<MCFixupKind> X86AsmBackend::getFixupKind(StringRef Name) const {

const MCFixupKindInfo &X86AsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
const static MCFixupKindInfo Infos[X86::NumTargetFixupKinds] = {
// clang-format off
{"reloc_riprel_4byte", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
{"reloc_riprel_4byte_movq_load", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
{"reloc_riprel_4byte_movq_load_rex2", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
{"reloc_riprel_4byte_relax", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
{"reloc_riprel_4byte_relax_rex", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
{"reloc_riprel_4byte_relax_rex2", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
{"reloc_signed_4byte", 0, 32, 0},
{"reloc_signed_4byte_relax", 0, 32, 0},
{"reloc_global_offset_table", 0, 32, 0},
{"reloc_global_offset_table8", 0, 64, 0},
{"reloc_branch_4byte_pcrel", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
// clang-format on
};

// Fixup kinds from .reloc directive are like R_386_NONE/R_X86_64_NONE. They
Expand Down Expand Up @@ -678,7 +682,9 @@ static unsigned getFixupKindSize(unsigned Kind) {
case X86::reloc_riprel_4byte:
case X86::reloc_riprel_4byte_relax:
case X86::reloc_riprel_4byte_relax_rex:
case X86::reloc_riprel_4byte_relax_rex2:
case X86::reloc_riprel_4byte_movq_load:
case X86::reloc_riprel_4byte_movq_load_rex2:
case X86::reloc_signed_4byte:
case X86::reloc_signed_4byte_relax:
case X86::reloc_global_offset_table:
Expand Down
7 changes: 6 additions & 1 deletion llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ static X86_64RelType getType64(MCFixupKind Kind,
case X86::reloc_riprel_4byte:
case X86::reloc_riprel_4byte_relax:
case X86::reloc_riprel_4byte_relax_rex:
case X86::reloc_riprel_4byte_relax_rex2:
case X86::reloc_riprel_4byte_movq_load:
case X86::reloc_riprel_4byte_movq_load_rex2:
return RT64_32;
case X86::reloc_branch_4byte_pcrel:
Modifier = MCSymbolRefExpr::VK_PLT;
Expand Down Expand Up @@ -205,7 +207,7 @@ static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc,
case MCSymbolRefExpr::VK_GOTPCREL:
checkIs32(Ctx, Loc, Type);
// Older versions of ld.bfd/ld.gold/lld
// do not support GOTPCRELX/REX_GOTPCRELX,
// do not support GOTPCRELX/REX_GOTPCRELX/REX2_GOTPCRELX,
// and we want to keep back-compatibility.
if (!Ctx.getTargetOptions()->X86RelaxRelocations)
return ELF::R_X86_64_GOTPCREL;
Expand All @@ -217,6 +219,9 @@ static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc,
case X86::reloc_riprel_4byte_relax_rex:
case X86::reloc_riprel_4byte_movq_load:
return ELF::R_X86_64_REX_GOTPCRELX;
case X86::reloc_riprel_4byte_relax_rex2:
case X86::reloc_riprel_4byte_movq_load_rex2:
return ELF::R_X86_64_REX2_GOTPCRELX;
}
llvm_unreachable("unexpected relocation type!");
case MCSymbolRefExpr::VK_GOTPCREL_NORELAX:
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ namespace X86 {
enum Fixups {
reloc_riprel_4byte = FirstTargetFixupKind, // 32-bit rip-relative
reloc_riprel_4byte_movq_load, // 32-bit rip-relative in movq
reloc_riprel_4byte_movq_load_rex2, // 32-bit rip-relative in movq
// with rex2 prefix
reloc_riprel_4byte_relax, // 32-bit rip-relative in relaxable
// instruction
reloc_riprel_4byte_relax_rex, // 32-bit rip-relative in relaxable
// instruction with rex prefix
reloc_riprel_4byte_relax_rex2, // 32-bit rip-relative in relaxable
// instruction with rex2 prefix
reloc_signed_4byte, // 32-bit signed. Unlike FK_Data_4
// this will be sign extended at
// runtime.
Expand Down
19 changes: 9 additions & 10 deletions llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,8 +568,10 @@ void X86MCCodeEmitter::emitImmediate(const MCOperand &DispOp, SMLoc Loc,
if (FixupKind == FK_PCRel_4 ||
FixupKind == MCFixupKind(X86::reloc_riprel_4byte) ||
FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load) ||
FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load_rex2) ||
FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax) ||
FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_rex) ||
FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_rex2) ||
FixupKind == MCFixupKind(X86::reloc_branch_4byte_pcrel)) {
ImmOffset -= 4;
// If this is a pc-relative load off _GLOBAL_OFFSET_TABLE_:
Expand Down Expand Up @@ -637,12 +639,11 @@ void X86MCCodeEmitter::emitMemModRMByte(
default:
return X86::reloc_riprel_4byte;
case X86::MOV64rm:
// movq loads is a subset of reloc_riprel_4byte_relax_rex. It is a
// movq loads is a subset of reloc_riprel_4byte_relax_rex/rex2. It is a
// special case because COFF and Mach-O don't support ELF's more
// flexible R_X86_64_REX_GOTPCRELX relaxation.
// TODO: Support new relocation for REX2.
assert(Kind == REX || Kind == REX2);
return X86::reloc_riprel_4byte_movq_load;
// flexible R_X86_64_REX_GOTPCRELX/R_X86_64_REX2_GOTPCRELX relaxation.
return Kind == REX2 ? X86::reloc_riprel_4byte_movq_load_rex2
: X86::reloc_riprel_4byte_movq_load;
case X86::ADC32rm:
case X86::ADD32rm:
case X86::AND32rm:
Expand All @@ -665,11 +666,9 @@ void X86MCCodeEmitter::emitMemModRMByte(
case X86::SBB64rm:
case X86::SUB64rm:
case X86::XOR64rm:
// We haven't support relocation for REX2 prefix, so temporarily use REX
// relocation.
// TODO: Support new relocation for REX2.
return (Kind == REX || Kind == REX2) ? X86::reloc_riprel_4byte_relax_rex
: X86::reloc_riprel_4byte_relax;
return Kind == REX2 ? X86::reloc_riprel_4byte_relax_rex2
: Kind == REX ? X86::reloc_riprel_4byte_relax_rex
: X86::reloc_riprel_4byte_relax;
}
}();

Expand Down
6 changes: 5 additions & 1 deletion llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,10 @@ class X86MachObjectWriter : public MCMachObjectTargetWriter {
static bool isFixupKindRIPRel(unsigned Kind) {
return Kind == X86::reloc_riprel_4byte ||
Kind == X86::reloc_riprel_4byte_movq_load ||
Kind == X86::reloc_riprel_4byte_movq_load_rex2 ||
Kind == X86::reloc_riprel_4byte_relax ||
Kind == X86::reloc_riprel_4byte_relax_rex;
Kind == X86::reloc_riprel_4byte_relax_rex ||
Kind == X86::reloc_riprel_4byte_relax_rex2;
}

static unsigned getFixupKindLog2Size(unsigned Kind) {
Expand All @@ -83,7 +85,9 @@ static unsigned getFixupKindLog2Size(unsigned Kind) {
case X86::reloc_riprel_4byte:
case X86::reloc_riprel_4byte_relax:
case X86::reloc_riprel_4byte_relax_rex:
case X86::reloc_riprel_4byte_relax_rex2:
case X86::reloc_riprel_4byte_movq_load:
case X86::reloc_riprel_4byte_movq_load_rex2:
case X86::reloc_signed_4byte:
case X86::reloc_signed_4byte_relax:
case X86::reloc_branch_4byte_pcrel:
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,10 @@ unsigned X86WinCOFFObjectWriter::getRelocType(MCContext &Ctx,
case FK_PCRel_4:
case X86::reloc_riprel_4byte:
case X86::reloc_riprel_4byte_movq_load:
case X86::reloc_riprel_4byte_movq_load_rex2:
case X86::reloc_riprel_4byte_relax:
case X86::reloc_riprel_4byte_relax_rex:
case X86::reloc_riprel_4byte_relax_rex2:
case X86::reloc_branch_4byte_pcrel:
return COFF::IMAGE_REL_AMD64_REL32;
case FK_Data_4:
Expand Down
3 changes: 3 additions & 0 deletions llvm/test/MC/ELF/relocation-alias.s
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ movabsq $memcpy+2, %rax

# CHECK: movq (%rip), %rax
# CHECK-NEXT: R_X86_64_REX_GOTPCRELX abs-0x4
# CHECK: movq (%rip), %r16
# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX abs-0x4
movq abs@GOTPCREL(%rip), %rax
movq abs@GOTPCREL(%rip), %r16
abs = 42

# CHECK: movabsq $0, %rbx
Expand Down
34 changes: 34 additions & 0 deletions llvm/test/MC/X86/gotpcrelx.s
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@
# CHECK-NEXT: R_X86_64_REX_GOTPCRELX sbb
# CHECK-NEXT: R_X86_64_REX_GOTPCRELX sub
# CHECK-NEXT: R_X86_64_REX_GOTPCRELX xor
# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX mov
# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX test
# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX adc
# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX add
# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX and
# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX cmp
# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX or
# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX sbb
# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX sub
# CHECK-NEXT: R_X86_64_REX2_GOTPCRELX xor
# CHECK-NEXT: }

# NORELAX-NEXT: R_X86_64_GOTPCREL mov
Expand Down Expand Up @@ -71,6 +81,16 @@
# NORELAX-NEXT: R_X86_64_GOTPCREL sbb
# NORELAX-NEXT: R_X86_64_GOTPCREL sub
# NORELAX-NEXT: R_X86_64_GOTPCREL xor
# NORELAX-NEXT: R_X86_64_GOTPCREL mov
# NORELAX-NEXT: R_X86_64_GOTPCREL test
# NORELAX-NEXT: R_X86_64_GOTPCREL adc
# NORELAX-NEXT: R_X86_64_GOTPCREL add
# NORELAX-NEXT: R_X86_64_GOTPCREL and
# NORELAX-NEXT: R_X86_64_GOTPCREL cmp
# NORELAX-NEXT: R_X86_64_GOTPCREL or
# NORELAX-NEXT: R_X86_64_GOTPCREL sbb
# NORELAX-NEXT: R_X86_64_GOTPCREL sub
# NORELAX-NEXT: R_X86_64_GOTPCREL xor
# NORELAX-NEXT: }

movl mov@GOTPCREL(%rip), %eax
Expand Down Expand Up @@ -108,10 +128,22 @@ sbb sbb@GOTPCREL(%rip), %rax
sub sub@GOTPCREL(%rip), %rax
xor xor@GOTPCREL(%rip), %rax

movq mov@GOTPCREL(%rip), %r16
test %r16, test@GOTPCREL(%rip)
adc adc@GOTPCREL(%rip), %r16
add add@GOTPCREL(%rip), %r16
and and@GOTPCREL(%rip), %r16
cmp cmp@GOTPCREL(%rip), %r16
or or@GOTPCREL(%rip), %r16
sbb sbb@GOTPCREL(%rip), %r16
sub sub@GOTPCREL(%rip), %r16
xor xor@GOTPCREL(%rip), %r16

# COMMON-NEXT: Section ({{.*}}) .rela.norelax {
# COMMON-NEXT: R_X86_64_GOTPCREL mov 0x0
# COMMON-NEXT: R_X86_64_GOTPCREL mov 0xFFFFFFFFFFFFFFFD
# COMMON-NEXT: R_X86_64_GOTPCREL mov 0xFFFFFFFFFFFFFFFC
# COMMON-NEXT: R_X86_64_GOTPCREL mov 0xFFFFFFFFFFFFFFFD
# COMMON-NEXT: }
# COMMON-NEXT: ]

Expand All @@ -123,3 +155,5 @@ movl mov@GOTPCREL+4(%rip), %eax
movq mov@GOTPCREL+1(%rip), %rax
## We could emit R_X86_64_GOTPCRELX, but it is probably unnecessary.
movl mov@GOTPCREL+0(%rip), %eax
## Don't emit R_X86_64_GOTPCRELX.
movq mov@GOTPCREL+1(%rip), %r16
3 changes: 3 additions & 0 deletions llvm/test/MC/X86/reloc-directive-elf-64.s
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
# PRINT-NEXT: .reloc 0, R_X86_64_64, .data+2
# PRINT-NEXT: .reloc 0, R_X86_64_GOTPCRELX, foo+3
# PRINT-NEXT: .reloc 0, R_X86_64_REX_GOTPCRELX, 5
# PRINT-NEXT: .reloc 0, R_X86_64_REX2_GOTPCRELX, 7
# PRINT: .reloc 0, BFD_RELOC_NONE, 9
# PRINT-NEXT: .reloc 0, BFD_RELOC_8, 9
# PRINT-NEXT: .reloc 0, BFD_RELOC_16, 9
Expand All @@ -21,6 +22,7 @@
# CHECK-NEXT: 0x0 R_X86_64_64 .data 0x2
# CHECK-NEXT: 0x0 R_X86_64_GOTPCRELX foo 0x3
# CHECK-NEXT: 0x0 R_X86_64_REX_GOTPCRELX - 0x5
# CHECK-NEXT: 0x0 R_X86_64_REX2_GOTPCRELX - 0x7
# CHECK-NEXT: 0x0 R_X86_64_NONE - 0x9
# CHECK-NEXT: 0x0 R_X86_64_8 - 0x9
# CHECK-NEXT: 0x0 R_X86_64_16 - 0x9
Expand All @@ -37,6 +39,7 @@
.reloc 0, R_X86_64_64, .data+2
.reloc 0, R_X86_64_GOTPCRELX, foo+3
.reloc 0, R_X86_64_REX_GOTPCRELX, 5
.reloc 0, R_X86_64_REX2_GOTPCRELX, 7

.reloc 0, BFD_RELOC_NONE, 9
.reloc 0, BFD_RELOC_8, 9
Expand Down