[llvm] r219280 - llvm-dwarfdump: Add support for some COFF relocations

David Majnemer david.majnemer at gmail.com
Tue Oct 7 23:38:50 PDT 2014


Author: majnemer
Date: Wed Oct  8 01:38:50 2014
New Revision: 219280

URL: http://llvm.org/viewvc/llvm-project?rev=219280&view=rev
Log:
llvm-dwarfdump: Add support for some COFF relocations

DWARF in COFF utilizes several relocations.  Implement support for them
in RelocVisitor to support llvm-dwarfdump.

Modified:
    llvm/trunk/include/llvm/Object/ELFObjectFile.h
    llvm/trunk/include/llvm/Object/RelocVisitor.h
    llvm/trunk/lib/DebugInfo/DWARFContext.cpp
    llvm/trunk/test/DebugInfo/X86/processes-relocations.ll

Modified: llvm/trunk/include/llvm/Object/ELFObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ELFObjectFile.h?rev=219280&r1=219279&r2=219280&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELFObjectFile.h (original)
+++ llvm/trunk/include/llvm/Object/ELFObjectFile.h Wed Oct  8 01:38:50 2014
@@ -47,6 +47,8 @@ public:
 
   virtual std::error_code getSymbolVersion(SymbolRef Symb, StringRef &Version,
                                            bool &IsDefault) const = 0;
+
+  static inline bool classof(const Binary *v) { return v->isELF(); }
 };
 
 template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {

Modified: llvm/trunk/include/llvm/Object/RelocVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/RelocVisitor.h?rev=219280&r1=219279&r2=219280&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/RelocVisitor.h (original)
+++ llvm/trunk/include/llvm/Object/RelocVisitor.h Wed Oct  8 01:38:50 2014
@@ -17,6 +17,7 @@
 #define LLVM_OBJECT_RELOCVISITOR_H
 
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Object/COFF.h"
 #include "llvm/Object/ELFObjectFile.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/Debug.h"
@@ -46,8 +47,23 @@ public:
   // TODO: Should handle multiple applied relocations via either passing in the
   // previously computed value or just count paired relocations as a single
   // visit.
-  RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t SecAddr = 0,
-                     uint64_t Value = 0) {
+  RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t Value = 0) {
+    if (isa<ELFObjectFileBase>(ObjToVisit))
+      return visitELF(RelocType, R, Value);
+    if (isa<COFFObjectFile>(ObjToVisit))
+      return visitCOFF(RelocType, R, Value);
+
+    HasError = true;
+    return RelocToApply();
+  }
+
+  bool error() { return HasError; }
+
+private:
+  ObjectFile &ObjToVisit;
+  bool HasError;
+
+  RelocToApply visitELF(uint32_t RelocType, RelocationRef R, uint64_t Value) {
     if (ObjToVisit.getBytesInAddress() == 8) { // 64-bit object file
       switch (ObjToVisit.getArch()) {
       case Triple::x86_64:
@@ -57,7 +73,7 @@ public:
         case llvm::ELF::R_X86_64_64:
           return visitELF_X86_64_64(R, Value);
         case llvm::ELF::R_X86_64_PC32:
-          return visitELF_X86_64_PC32(R, Value, SecAddr);
+          return visitELF_X86_64_PC32(R, Value);
         case llvm::ELF::R_X86_64_32:
           return visitELF_X86_64_32(R, Value);
         case llvm::ELF::R_X86_64_32S:
@@ -133,7 +149,7 @@ public:
         case llvm::ELF::R_386_32:
           return visitELF_386_32(R, Value);
         case llvm::ELF::R_386_PC32:
-          return visitELF_386_PC32(R, Value, SecAddr);
+          return visitELF_386_PC32(R, Value);
         default:
           HasError = true;
           return RelocToApply();
@@ -182,13 +198,30 @@ public:
     }
   }
 
-  bool error() { return HasError; }
-
-private:
-  ObjectFile &ObjToVisit;
-  bool HasError;
+  RelocToApply visitCOFF(uint32_t RelocType, RelocationRef R, uint64_t Value) {
+    switch (ObjToVisit.getArch()) {
+    case Triple::x86:
+      switch (RelocType) {
+      case COFF::IMAGE_REL_I386_SECREL:
+        return visitCOFF_I386_SECREL(R, Value);
+      case COFF::IMAGE_REL_I386_DIR32:
+        return visitCOFF_I386_DIR32(R, Value);
+      }
+      break;
+    case Triple::x86_64:
+      switch (RelocType) {
+      case COFF::IMAGE_REL_AMD64_SECREL:
+        return visitCOFF_AMD64_SECREL(R, Value);
+      case COFF::IMAGE_REL_AMD64_ADDR64:
+        return visitCOFF_AMD64_ADDR64(R, Value);
+      }
+      break;
+    }
+    HasError = true;
+    return RelocToApply();
+  }
 
-  int64_t getAddend32LE(RelocationRef R) {
+  int64_t getELFAddend32LE(RelocationRef R) {
     const ELF32LEObjectFile *Obj = cast<ELF32LEObjectFile>(R.getObjectFile());
     DataRefImpl DRI = R.getRawDataRefImpl();
     int64_t Addend;
@@ -196,7 +229,7 @@ private:
     return Addend;
   }
 
-  int64_t getAddend64LE(RelocationRef R) {
+  int64_t getELFAddend64LE(RelocationRef R) {
     const ELF64LEObjectFile *Obj = cast<ELF64LEObjectFile>(R.getObjectFile());
     DataRefImpl DRI = R.getRawDataRefImpl();
     int64_t Addend;
@@ -204,7 +237,7 @@ private:
     return Addend;
   }
 
-  int64_t getAddend32BE(RelocationRef R) {
+  int64_t getELFAddend32BE(RelocationRef R) {
     const ELF32BEObjectFile *Obj = cast<ELF32BEObjectFile>(R.getObjectFile());
     DataRefImpl DRI = R.getRawDataRefImpl();
     int64_t Addend;
@@ -212,7 +245,7 @@ private:
     return Addend;
   }
 
-  int64_t getAddend64BE(RelocationRef R) {
+  int64_t getELFAddend64BE(RelocationRef R) {
     const ELF64BEObjectFile *Obj = cast<ELF64BEObjectFile>(R.getObjectFile());
     DataRefImpl DRI = R.getRawDataRefImpl();
     int64_t Addend;
@@ -229,13 +262,12 @@ private:
   // Ideally the Addend here will be the addend in the data for
   // the relocation. It's not actually the case for Rel relocations.
   RelocToApply visitELF_386_32(RelocationRef R, uint64_t Value) {
-    int64_t Addend = getAddend32LE(R);
+    int64_t Addend = getELFAddend32LE(R);
     return RelocToApply(Value + Addend, 4);
   }
 
-  RelocToApply visitELF_386_PC32(RelocationRef R, uint64_t Value,
-                                 uint64_t SecAddr) {
-    int64_t Addend = getAddend32LE(R);
+  RelocToApply visitELF_386_PC32(RelocationRef R, uint64_t Value) {
+    int64_t Addend = getELFAddend32LE(R);
     uint64_t Address;
     R.getOffset(Address);
     return RelocToApply(Value + Addend - Address, 4);
@@ -246,23 +278,22 @@ private:
     return RelocToApply(0, 0);
   }
   RelocToApply visitELF_X86_64_64(RelocationRef R, uint64_t Value) {
-    int64_t Addend = getAddend64LE(R);
+    int64_t Addend = getELFAddend64LE(R);
     return RelocToApply(Value + Addend, 8);
   }
-  RelocToApply visitELF_X86_64_PC32(RelocationRef R, uint64_t Value,
-                                    uint64_t SecAddr) {
-    int64_t Addend = getAddend64LE(R);
+  RelocToApply visitELF_X86_64_PC32(RelocationRef R, uint64_t Value) {
+    int64_t Addend = getELFAddend64LE(R);
     uint64_t Address;
     R.getOffset(Address);
     return RelocToApply(Value + Addend - Address, 4);
   }
   RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) {
-    int64_t Addend = getAddend64LE(R);
+    int64_t Addend = getELFAddend64LE(R);
     uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
     return RelocToApply(Res, 4);
   }
   RelocToApply visitELF_X86_64_32S(RelocationRef R, uint64_t Value) {
-    int64_t Addend = getAddend64LE(R);
+    int64_t Addend = getELFAddend64LE(R);
     int32_t Res = (Value + Addend) & 0xFFFFFFFF;
     return RelocToApply(Res, 4);
   }
@@ -282,7 +313,7 @@ private:
 
   /// PPC32 ELF
   RelocToApply visitELF_PPC_ADDR32(RelocationRef R, uint64_t Value) {
-    int64_t Addend = getAddend32BE(R);
+    int64_t Addend = getELFAddend32BE(R);
     uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
     return RelocToApply(Res, 4);
   }
@@ -323,7 +354,7 @@ private:
 
   // SystemZ ELF
   RelocToApply visitELF_390_32(RelocationRef R, uint64_t Value) {
-    int64_t Addend = getAddend64BE(R);
+    int64_t Addend = getELFAddend64BE(R);
     int64_t Res = Value + Addend;
 
     // Overflow check allows for both signed and unsigned interpretation.
@@ -334,22 +365,22 @@ private:
   }
 
   RelocToApply visitELF_390_64(RelocationRef R, uint64_t Value) {
-    int64_t Addend = getAddend64BE(R);
+    int64_t Addend = getELFAddend64BE(R);
     return RelocToApply(Value + Addend, 8);
   }
 
   RelocToApply visitELF_SPARC_32(RelocationRef R, uint32_t Value) {
-    int32_t Addend = getAddend32BE(R);
+    int32_t Addend = getELFAddend32BE(R);
     return RelocToApply(Value + Addend, 4);
   }
 
   RelocToApply visitELF_SPARCV9_32(RelocationRef R, uint64_t Value) {
-    int32_t Addend = getAddend64BE(R);
+    int32_t Addend = getELFAddend64BE(R);
     return RelocToApply(Value + Addend, 4);
   }
 
   RelocToApply visitELF_SPARCV9_64(RelocationRef R, uint64_t Value) {
-    int64_t Addend = getAddend64BE(R);
+    int64_t Addend = getELFAddend64BE(R);
     return RelocToApply(Value + Addend, 8);
   }
 
@@ -365,6 +396,23 @@ private:
     return RelocToApply(static_cast<uint32_t>(Res), 4);
   }
 
+  /// I386 COFF
+  RelocToApply visitCOFF_I386_SECREL(RelocationRef R, uint64_t Value) {
+    return RelocToApply(static_cast<uint32_t>(Value), /*Width=*/4);
+  }
+
+  RelocToApply visitCOFF_I386_DIR32(RelocationRef R, uint64_t Value) {
+    return RelocToApply(static_cast<uint32_t>(Value), /*Width=*/4);
+  }
+
+  /// AMD64 COFF
+  RelocToApply visitCOFF_AMD64_SECREL(RelocationRef R, uint64_t Value) {
+    return RelocToApply(static_cast<uint32_t>(Value), /*Width=*/4);
+  }
+
+  RelocToApply visitCOFF_AMD64_ADDR64(RelocationRef R, uint64_t Value) {
+    return RelocToApply(Value, /*Width=*/8);
+  }
 };
 
 }

Modified: llvm/trunk/lib/DebugInfo/DWARFContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARFContext.cpp?rev=219280&r1=219279&r2=219280&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARFContext.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARFContext.cpp Wed Oct  8 01:38:50 2014
@@ -620,15 +620,12 @@ DWARFContextInMemory::DWARFContextInMemo
         uint64_t Type;
         Reloc.getType(Type);
         uint64_t SymAddr = 0;
-        // ELF relocations may need the symbol address
-        if (Obj.isELF()) {
-          object::symbol_iterator Sym = Reloc.getSymbol();
+        object::symbol_iterator Sym = Reloc.getSymbol();
+        if (Sym != Obj.symbol_end())
           Sym->getAddress(SymAddr);
-        }
 
         object::RelocVisitor V(Obj);
-        // The section address is always 0 for debug sections.
-        object::RelocToApply R(V.visit(Type, Reloc, 0, SymAddr));
+        object::RelocToApply R(V.visit(Type, Reloc, SymAddr));
         if (V.error()) {
           SmallString<32> Name;
           std::error_code ec(Reloc.getTypeName(Name));

Modified: llvm/trunk/test/DebugInfo/X86/processes-relocations.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/processes-relocations.ll?rev=219280&r1=219279&r2=219280&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/processes-relocations.ll (original)
+++ llvm/trunk/test/DebugInfo/X86/processes-relocations.ll Wed Oct  8 01:38:50 2014
@@ -2,6 +2,10 @@
 ; RUN:     llvm-dwarfdump - 2>&1 | FileCheck %s
 ; RUN: llc -filetype=obj -O0 < %s -mtriple i386-none-linux | \
 ; RUN:     llvm-dwarfdump - 2>&1 | FileCheck %s
+; RUN: llc -filetype=obj -O0 < %s -mtriple x86_64-none-mingw32 | \
+; RUN:     llvm-dwarfdump - 2>&1 | FileCheck %s
+; RUN: llc -filetype=obj -O0 < %s -mtriple i386-none-mingw32 | \
+; RUN:     llvm-dwarfdump - 2>&1 | FileCheck %s
 
 ; CHECK-NOT: failed to compute relocation
 
@@ -13,5 +17,5 @@
 !1 = metadata !{metadata !"empty.c", metadata !"/a"}
 !2 = metadata !{}
 !3 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-!4 = metadata !{i32 2, metadata !"Debug Info Version", i32 1}
+!4 = metadata !{i32 2, metadata !"Debug Info Version", i32 2}
 !5 = metadata !{metadata !"clang version 3.6.0 "}





More information about the llvm-commits mailing list