[PATCH 06/28] llvm-dwarfdump: Add support for some COFF relocations

Rafael EspĂ­ndola rafael.espindola at gmail.com
Thu Oct 16 07:53:33 PDT 2014


Please don't use "llc -filetype=obj". Checkin a .s file and use llvm-mc.

On 8 October 2014 09:50, Aaron Watry <awatry at gmail.com> wrote:
> From: David Majnemer <david.majnemer at gmail.com>
>
> DWARF in COFF utilizes several relocations.  Implement support for them
> in RelocVisitor to support llvm-dwarfdump.
>
> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219280 91177308-0d34-0410-b5e6-96231b3b80d8
> ---
>  include/llvm/Object/ELFObjectFile.h         |   2 +
>  include/llvm/Object/RelocVisitor.h          | 106 ++++++++++++++++++++--------
>  lib/DebugInfo/DWARFContext.cpp              |   9 +--
>  test/DebugInfo/X86/processes-relocations.ll |   6 +-
>  4 files changed, 87 insertions(+), 36 deletions(-)
>
> diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h
> index 2c9c07a..9e18a20 100644
> --- a/include/llvm/Object/ELFObjectFile.h
> +++ b/include/llvm/Object/ELFObjectFile.h
> @@ -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 {
> diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h
> index 9eb768d..4fffd7e 100644
> --- a/include/llvm/Object/RelocVisitor.h
> +++ b/include/llvm/Object/RelocVisitor.h
> @@ -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);
> +  }
>  };
>
>  }
> diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp
> index 2cacfd9..a121639 100644
> --- a/lib/DebugInfo/DWARFContext.cpp
> +++ b/lib/DebugInfo/DWARFContext.cpp
> @@ -620,15 +620,12 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile &Obj)
>          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));
> diff --git a/test/DebugInfo/X86/processes-relocations.ll b/test/DebugInfo/X86/processes-relocations.ll
> index f9a31eb..2a29be4 100644
> --- a/test/DebugInfo/X86/processes-relocations.ll
> +++ b/test/DebugInfo/X86/processes-relocations.ll
> @@ -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 "}
> --
> 2.1.0
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list