[MC][X86] Make .reloc support arbitrary relocation types

Generalizes D62014 (R_386_NONE/R_X86_64_NONE).

Unlike ARM (D76746) and AArch64 (D76754), we cannot delete FK_NONE from
getFixupKindSize because FK_NONE is still used by R_386_TLS_DESC_CALL/R_X86_64_TLSDESC_CALL.
This commit is contained in:
Fangrui Song 2020-03-27 12:41:35 -07:00
parent 236ac68fa5
commit 152d14da64
4 changed files with 45 additions and 7 deletions

View File

@ -646,13 +646,23 @@ void X86AsmBackend::emitInstructionEnd(MCObjectStreamer &OS, const MCInst &Inst)
Optional<MCFixupKind> X86AsmBackend::getFixupKind(StringRef Name) const {
if (STI.getTargetTriple().isOSBinFormatELF()) {
unsigned Type;
if (STI.getTargetTriple().getArch() == Triple::x86_64) {
if (Name == "R_X86_64_NONE")
return FK_NONE;
Type = llvm::StringSwitch<unsigned>(Name)
#define ELF_RELOC(X, Y) .Case(#X, Y)
#include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
#undef ELF_RELOC
.Default(-1u);
} else {
if (Name == "R_386_NONE")
return FK_NONE;
Type = llvm::StringSwitch<unsigned>(Name)
#define ELF_RELOC(X, Y) .Case(#X, Y)
#include "llvm/BinaryFormat/ELFRelocs/i386.def"
#undef ELF_RELOC
.Default(-1u);
}
if (Type == -1u)
return None;
return static_cast<MCFixupKind>(FirstLiteralRelocationKind + Type);
}
return MCAsmBackend::getFixupKind(Name);
}
@ -670,6 +680,11 @@ const MCFixupKindInfo &X86AsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
{"reloc_branch_4byte_pcrel", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
};
// Fixup kinds from .reloc directive are like R_386_NONE/R_X86_64_NONE. They
// do not require any extra processing.
if (Kind >= FirstLiteralRelocationKind)
return MCAsmBackend::getFixupKindInfo(FK_NONE);
if (Kind < FirstTargetFixupKind)
return MCAsmBackend::getFixupKindInfo(Kind);
@ -682,7 +697,7 @@ const MCFixupKindInfo &X86AsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
bool X86AsmBackend::shouldForceRelocation(const MCAssembler &,
const MCFixup &Fixup,
const MCValue &) {
return Fixup.getKind() == FK_NONE;
return Fixup.getKind() >= FirstLiteralRelocationKind;
}
static unsigned getFixupKindSize(unsigned Kind) {
@ -724,7 +739,10 @@ void X86AsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
MutableArrayRef<char> Data,
uint64_t Value, bool IsResolved,
const MCSubtargetInfo *STI) const {
unsigned Size = getFixupKindSize(Fixup.getKind());
unsigned Kind = Fixup.getKind();
if (Kind >= FirstLiteralRelocationKind)
return;
unsigned Size = getFixupKindSize(Kind);
assert(Fixup.getOffset() + Size <= Data.size() && "Invalid fixup offset!");

View File

@ -317,8 +317,10 @@ static unsigned getRelocType32(MCContext &Ctx,
unsigned X86ELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
const MCFixup &Fixup,
bool IsPCRel) const {
MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
MCFixupKind Kind = Fixup.getKind();
if (Kind >= FirstLiteralRelocationKind)
return Kind - FirstLiteralRelocationKind;
MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
X86_64RelType Type = getType64(Kind, Modifier, IsPCRel);
if (getEMachine() == ELF::EM_X86_64)
return getRelocType64(Ctx, Fixup.getLoc(), Modifier, Type, IsPCRel, Kind);

View File

@ -7,12 +7,18 @@
# PRINT: .reloc 2, R_386_NONE, .data
# PRINT-NEXT: .reloc 1, R_386_NONE, foo+4
# PRINT-NEXT: .reloc 0, R_386_NONE, 8
# PRINT-NEXT: .reloc 0, R_386_32, .data+2
# PRINT-NEXT: .reloc 0, R_386_IRELATIVE, foo+3
# PRINT-NEXT: .reloc 0, R_386_GOT32X, 5
# X86 relocations use the Elf32_Rel format. Addends are neither stored in the
# relocation entries nor applied in the referenced locations.
# CHECK: 0x2 R_386_NONE .data 0x0
# CHECK-NEXT: 0x1 R_386_NONE foo 0x0
# CHECK-NEXT: 0x0 R_386_NONE - 0x0
# CHECK-NEXT: 0x0 R_386_32 .data 0x0
# CHECK-NEXT: 0x0 R_386_IRELATIVE foo 0x0
# CHECK-NEXT: 0x0 R_386_GOT32X - 0x0
# HEX: 0x00000000 00000000 00000000
@ -23,6 +29,9 @@
.reloc 2, R_386_NONE, .data
.reloc 1, R_386_NONE, foo+4
.reloc 0, R_386_NONE, 8
.reloc 0, R_386_32, .data+2
.reloc 0, R_386_IRELATIVE, foo+3
.reloc 0, R_386_GOT32X, 5
.data
.globl foo

View File

@ -6,10 +6,16 @@
# PRINT: .reloc 2, R_X86_64_NONE, .data
# PRINT-NEXT: .reloc 1, R_X86_64_NONE, foo+4
# PRINT-NEXT: .reloc 0, R_X86_64_NONE, 8
# 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
# CHECK: 0x2 R_X86_64_NONE .data 0x0
# CHECK-NEXT: 0x1 R_X86_64_NONE foo 0x4
# CHECK-NEXT: 0x0 R_X86_64_NONE - 0x8
# 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
.text
ret
@ -18,6 +24,9 @@
.reloc 2, R_X86_64_NONE, .data
.reloc 1, R_X86_64_NONE, foo+4
.reloc 0, R_X86_64_NONE, 8
.reloc 0, R_X86_64_64, .data+2
.reloc 0, R_X86_64_GOTPCRELX, foo+3
.reloc 0, R_X86_64_REX_GOTPCRELX, 5
.data
.globl foo