[PATCH] WinCOFF: Transform IR expressions featuring __ImageBase into image relative relocations
David Majnemer
david.majnemer at gmail.com
Mon Jan 13 23:39:39 PST 2014
- Fix the sort order of forward declarations.
Hi nlewycky, nicholas, rafael, grosbach, rnk,
http://llvm-reviews.chandlerc.com/D2523
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D2523?vs=6442&id=6443#toc
BRANCH
IMAGEREL
ARCANIST PROJECT
llvm
Files:
include/llvm/IR/Operator.h
include/llvm/Target/TargetLoweringObjectFile.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86TargetObjectFile.cpp
lib/Target/X86/X86TargetObjectFile.h
test/MC/COFF/ir-to-imgrel.ll
Index: include/llvm/IR/Operator.h
===================================================================
--- include/llvm/IR/Operator.h
+++ include/llvm/IR/Operator.h
@@ -473,6 +473,36 @@
};
+class PtrToIntOperator
+ : public ConcreteOperator<Operator, Instruction::PtrToInt> {
+ friend class PtrToInt;
+ friend class ConstantExpr;
+
+public:
+ Value *getPointerOperand() {
+ return getOperand(0);
+ }
+ const Value *getPointerOperand() const {
+ return getOperand(0);
+ }
+ static unsigned getPointerOperandIndex() {
+ return 0U; // get index for modifying correct operand
+ }
+
+ /// getPointerOperandType - Method to return the pointer operand as a
+ /// PointerType.
+ Type *getPointerOperandType() const {
+ return getPointerOperand()->getType();
+ }
+
+ /// getPointerAddressSpace - Method to return the address space of the
+ /// pointer operand.
+ unsigned getPointerAddressSpace() const {
+ return cast<PointerType>(getPointerOperandType())->getAddressSpace();
+ }
+};
+
+
} // End llvm namespace
#endif
Index: include/llvm/Target/TargetLoweringObjectFile.h
===================================================================
--- include/llvm/Target/TargetLoweringObjectFile.h
+++ include/llvm/Target/TargetLoweringObjectFile.h
@@ -29,6 +29,7 @@
class MCSymbol;
class MCSymbolRefExpr;
class MCStreamer;
+ class ConstantExpr;
class GlobalValue;
class TargetMachine;
@@ -152,6 +153,11 @@
/// emitting the address in debug info.
virtual const MCExpr *getDebugThreadLocalSymbol(const MCSymbol *Sym) const;
+ virtual const MCExpr *
+ getExecutableRelativeSymbol(const ConstantExpr *CE, Mangler *Mang) const {
+ return 0;
+ }
+
protected:
virtual const MCSection *
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp
===================================================================
--- lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1514,6 +1514,10 @@
llvm_unreachable("Unknown constant value to lower!");
}
+ if (const MCExpr *RelocExpr =
+ AP.getObjFileLowering().getExecutableRelativeSymbol(CE, AP.Mang))
+ return RelocExpr;
+
switch (CE->getOpcode()) {
default:
// If the code isn't optimized, there may be outstanding folding
Index: lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- lib/Target/X86/X86ISelLowering.cpp
+++ lib/Target/X86/X86ISelLowering.cpp
@@ -189,6 +189,8 @@
return new X86LinuxTargetObjectFile();
if (Subtarget->isTargetELF())
return new TargetLoweringObjectFileELF();
+ if (Subtarget->isTargetWindows())
+ return new X86WindowsTargetObjectFile();
if (Subtarget->isTargetCOFF())
return new TargetLoweringObjectFileCOFF();
llvm_unreachable("unknown subtarget type");
Index: lib/Target/X86/X86TargetObjectFile.cpp
===================================================================
--- lib/Target/X86/X86TargetObjectFile.cpp
+++ lib/Target/X86/X86TargetObjectFile.cpp
@@ -9,6 +9,7 @@
#include "X86TargetObjectFile.h"
#include "llvm/IR/Mangler.h"
+#include "llvm/IR/Operator.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSectionELF.h"
@@ -53,3 +54,54 @@
const MCSymbol *Sym) const {
return MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_DTPOFF, getContext());
}
+
+const MCExpr *
+X86WindowsTargetObjectFile::getExecutableRelativeSymbol(const ConstantExpr *CE,
+ Mangler *Mang) const {
+ // We are looking for the difference of two symbols, need a subtraction
+ // operation.
+ const SubOperator *Sub = dyn_cast<SubOperator>(CE);
+ if (!Sub)
+ return 0;
+
+ // Symbols must first be numbers before we can subtract them, we need to see a
+ // ptrtoint on both subtraction operands.
+ const PtrToIntOperator *SubLHS =
+ dyn_cast<PtrToIntOperator>(Sub->getOperand(0));
+ const PtrToIntOperator *SubRHS =
+ dyn_cast<PtrToIntOperator>(Sub->getOperand(1));
+ if (!SubLHS || !SubRHS)
+ return 0;
+
+ // Our symbols should exist in address space zero, cowardly no-op if
+ // otherwise.
+ if (SubLHS->getPointerAddressSpace() != 0 ||
+ SubRHS->getPointerAddressSpace() != 0)
+ return 0;
+
+ // Both ptrtoint instructions must wrap global variables:
+ // - Only global variables are eligible for image relative relocations.
+ // - The subtrahend refers to the special symbol __ImageBase, a global.
+ const GlobalVariable *GVLHS =
+ dyn_cast<GlobalVariable>(SubLHS->getPointerOperand());
+ const GlobalVariable *GVRHS =
+ dyn_cast<GlobalVariable>(SubRHS->getPointerOperand());
+ if (!GVLHS || !GVRHS)
+ return 0;
+
+ // We expect __ImageBase to be a global variable without a section, externally
+ // defined.
+ //
+ // It should look something like this: @__ImageBase = external constant i8
+ if (GVRHS->isThreadLocal() || GVRHS->getName() != "__ImageBase" ||
+ !GVRHS->hasExternalLinkage() || GVRHS->hasInitializer() ||
+ GVRHS->hasSection())
+ return 0;
+
+ // An image-relative, thread-local, symbol makes no sense.
+ if (GVLHS->isThreadLocal())
+ return 0;
+
+ return MCSymbolRefExpr::Create(
+ getSymbol(*Mang, GVLHS), MCSymbolRefExpr::VK_COFF_IMGREL32, getContext());
+}
Index: lib/Target/X86/X86TargetObjectFile.h
===================================================================
--- lib/Target/X86/X86TargetObjectFile.h
+++ lib/Target/X86/X86TargetObjectFile.h
@@ -41,6 +41,12 @@
virtual const MCExpr *getDebugThreadLocalSymbol(const MCSymbol *Sym) const;
};
+ /// \brief This implementation is used for Windows targets on x86 and x86-64.
+ class X86WindowsTargetObjectFile : public TargetLoweringObjectFileCOFF {
+ virtual const MCExpr *getExecutableRelativeSymbol(const ConstantExpr *CE,
+ Mangler *Mang) const;
+ };
+
} // end namespace llvm
#endif
Index: test/MC/COFF/ir-to-imgrel.ll
===================================================================
--- /dev/null
+++ test/MC/COFF/ir-to-imgrel.ll
@@ -0,0 +1,6 @@
+; RUN: llc -mtriple=x86_64-pc-win32 %s -o - | FileCheck %s --check-prefix=X64
+
+ at __ImageBase = external global i8
+
+; X64: .quad "?x@@3HA"@IMGREL32
+@"\01?x@@3HA" = global i64 sub nsw (i64 ptrtoint (i64* @"\01?x@@3HA" to i64), i64 ptrtoint (i8* @__ImageBase to i64)), align 8
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2523.3.patch
Type: text/x-patch
Size: 6508 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140113/3f03bebe/attachment.bin>
More information about the llvm-commits
mailing list