[PATCH] WinCOFF: Transform IR expressions featuring __ImageBase into image relative relocations

David Majnemer david.majnemer at gmail.com
Wed Jan 8 17:24:56 PST 2014


Hi nicholas, rafael, grosbach, rnk,

MSVC on x64 requires that we create image relative symbol
references to refer to RTTI data.  Seeing as how there is no way to
explicitly make reference to a given relocation type in LLVM IR, pattern
match expressions of the form &foo - &__ImageBase.

http://llvm-reviews.chandlerc.com/D2523

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
@@ -30,6 +30,7 @@
   class MCSymbolRefExpr;
   class MCStreamer;
   class GlobalValue;
+  class ConstantExpr;
   class TargetMachine;
   
 class TargetLoweringObjectFile : public MCObjectFileInfo {
@@ -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->isTargetWin64())
+    return new X86_64WindowsTargetObjectFile();
   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
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "X86TargetObjectFile.h"
+#include "llvm/IR/Operator.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCSectionELF.h"
@@ -53,3 +54,26 @@
     const MCSymbol *Sym) const {
   return MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_DTPOFF, getContext());
 }
+
+const MCExpr *X86_64WindowsTargetObjectFile::getExecutableRelativeSymbol(
+    const ConstantExpr *CE, Mangler *Mang) const {
+  if (const SubOperator *Sub = dyn_cast<SubOperator>(CE))
+    if (const PtrToIntOperator *SubLHS =
+            dyn_cast<PtrToIntOperator>(Sub->getOperand(0)))
+      if (const PtrToIntOperator *SubRHS =
+              dyn_cast<PtrToIntOperator>(Sub->getOperand(1)))
+        if (SubLHS->getPointerAddressSpace() == 0 &&
+            SubRHS->getPointerAddressSpace() == 0)
+          if (const GlobalVariable *GVLHS =
+                  dyn_cast<GlobalVariable>(SubLHS->getPointerOperand()))
+            if (const GlobalVariable *GVRHS =
+                    dyn_cast<GlobalVariable>(SubRHS->getPointerOperand()))
+              if (!GVLHS->isThreadLocal() && !GVRHS->isThreadLocal() &&
+                  !GVRHS->hasSection() && GVRHS->hasExternalLinkage() &&
+                  GVRHS->hasName() && GVRHS->getName() == "__ImageBase") {
+                return MCSymbolRefExpr::Create(
+                    getSymbol(*Mang, GVLHS), MCSymbolRefExpr::VK_COFF_IMGREL32,
+                    getContext());
+              }
+  return 0;
+}
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-64.
+  class X86_64WindowsTargetObjectFile : 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.1.patch
Type: text/x-patch
Size: 5774 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140108/a1fb2659/attachment.bin>


More information about the llvm-commits mailing list