From e426e8360c88faadf4d7efd56d9a367deb6234eb Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 25 Apr 2013 19:27:05 +0000 Subject: [PATCH] Fix section relocation for SECTIONREL32 with immediate offset. Patch by Kai Nacke. This matches the gnu as output. llvm-svn: 180568 --- lib/MC/MCExpr.cpp | 2 ++ .../X86/MCTargetDesc/X86MCCodeEmitter.cpp | 17 +++++++++++++++-- test/MC/COFF/secrel-variant.s | 19 +++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 test/MC/COFF/secrel-variant.s diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp index d54c2641834..6cde26cff17 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 182bec1e841..016af71501a 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(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(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(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 00000000000..1061bd404ea --- /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: ]