diff options
-rw-r--r-- | lib/MC/MCExpr.cpp | 2 | ||||
-rw-r--r-- | lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp | 17 | ||||
-rw-r--r-- | test/MC/COFF/secrel-variant.s | 19 |
3 files changed, 36 insertions, 2 deletions
diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp index d54c264183..6cde26cff1 100644 --- a/lib/MC/MCExpr.cpp +++ b/lib/MC/MCExpr.cpp @@ -288,6 +288,8 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) { .Case("tlvp", VK_TLVP) .Case("IMGREL", VK_COFF_IMGREL32) .Case("imgrel", VK_COFF_IMGREL32) + .Case("SECREL32", VK_SECREL) + .Case("secrel32", VK_SECREL) .Default(VK_Invalid); } diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index 182bec1e84..016af71501 100644 --- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -237,6 +237,14 @@ StartsWithGlobalOffsetTable(const MCExpr *Expr) { return GOT_Normal; } +static bool HasSecRelSymbolRef(const MCExpr *Expr) { + if (Expr->getKind() == MCExpr::SymbolRef) { + const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); + return Ref->getKind() == MCSymbolRefExpr::VK_SECREL; + } + return false; +} + void X86MCCodeEmitter:: EmitImmediate(const MCOperand &DispOp, SMLoc Loc, unsigned Size, MCFixupKind FixupKind, unsigned &CurByte, raw_ostream &OS, @@ -268,8 +276,13 @@ EmitImmediate(const MCOperand &DispOp, SMLoc Loc, unsigned Size, if (Kind == GOT_Normal) ImmOffset = CurByte; } else if (Expr->getKind() == MCExpr::SymbolRef) { - const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); - if (Ref->getKind() == MCSymbolRefExpr::VK_SECREL) { + if (HasSecRelSymbolRef(Expr)) { + FixupKind = MCFixupKind(FK_SecRel_4); + } + } else if (Expr->getKind() == MCExpr::Binary) { + const MCBinaryExpr *Bin = static_cast<const MCBinaryExpr*>(Expr); + if (HasSecRelSymbolRef(Bin->getLHS()) + || HasSecRelSymbolRef(Bin->getRHS())) { FixupKind = MCFixupKind(FK_SecRel_4); } } diff --git a/test/MC/COFF/secrel-variant.s b/test/MC/COFF/secrel-variant.s new file mode 100644 index 0000000000..1061bd404e --- /dev/null +++ b/test/MC/COFF/secrel-variant.s @@ -0,0 +1,19 @@ +// COFF section-relative relocations + +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-win32 %s | llvm-readobj -r | FileCheck %s + +.data +values: + .long 1 + .long 0 + +.text + movq values@SECREL32(%rax), %rcx + movq values@SECREL32+8(%rax), %rax + +// CHECK: Relocations [ +// CHECK-NEXT: Section (1) .text { +// CHECK-NEXT: 0x3 IMAGE_REL_AMD64_SECREL values +// CHECK-NEXT: 0xA IMAGE_REL_AMD64_SECREL values +// CHECK-NEXT: } +// CHECK-NEXT: ] |