[llvm] r179294 - Print more information about relocations.

Rafael Espindola rafael.espindola at gmail.com
Thu Apr 11 09:31:38 PDT 2013


Author: rafael
Date: Thu Apr 11 11:31:37 2013
New Revision: 179294

URL: http://llvm.org/viewvc/llvm-project?rev=179294&view=rev
Log:
Print more information about relocations.

With this patch llvm-readobj now prints if a relocation is pcrel, its length,
if it is extern and if it is scattered.

It also refactors the code a bit to use bit fields instead of shifts and
masks all over the place.

Modified:
    llvm/trunk/include/llvm/Object/MachO.h
    llvm/trunk/lib/Object/MachOObjectFile.cpp
    llvm/trunk/test/tools/llvm-readobj/relocations.test
    llvm/trunk/test/tools/llvm-readobj/sections-ext.test
    llvm/trunk/tools/llvm-readobj/MachODumper.cpp

Modified: llvm/trunk/include/llvm/Object/MachO.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/MachO.h?rev=179294&r1=179293&r2=179294&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/MachO.h (original)
+++ llvm/trunk/include/llvm/Object/MachO.h Thu Apr 11 11:31:37 2013
@@ -115,8 +115,23 @@ namespace MachOFormat {
   template<endianness TargetEndianness>
   struct RelocationEntry {
     LLVM_MACHOB_IMPORT_TYPES(TargetEndianness)
-    MachOInt32 Word0;
-    MachOInt32 Word1;
+    MachOInt32 Address;
+    unsigned SymbolNum : 24;
+    unsigned PCRel : 1;
+    unsigned Length : 2;
+    unsigned External : 1;
+    unsigned Type : 4;
+  };
+
+  template<endianness TargetEndianness>
+  struct ScatteredRelocationEntry {
+    LLVM_MACHOB_IMPORT_TYPES(TargetEndianness)
+    unsigned Address : 24;
+    unsigned Type : 4;
+    unsigned Length : 2;
+    unsigned PCRel : 1;
+    unsigned Scattered : 1;
+    MachOInt32 Value;
   };
 
   template<endianness TargetEndianness>
@@ -206,6 +221,8 @@ public:
     SymbolTableEntryBase;
   typedef MachOFormat::SymtabLoadCommand<support::little> SymtabLoadCommand;
   typedef MachOFormat::RelocationEntry<support::little> RelocationEntry;
+  typedef MachOFormat::ScatteredRelocationEntry<support::little>
+    ScatteredRelocationEntry;
   typedef MachOFormat::SectionBase SectionBase;
   typedef MachOFormat::LoadCommand<support::little> LoadCommand;
   typedef MachOFormat::Header<support::little> Header;
@@ -243,6 +260,11 @@ public:
   const Header *getHeader() const;
   unsigned getHeaderSize() const;
   StringRef getData(size_t Offset, size_t Size) const;
+  const RelocationEntry *getRelocation(DataRefImpl Rel) const;
+  bool isScattered(const RelocationEntry *RE) const;
+  bool isPCRel(const RelocationEntry *RE) const;
+  unsigned getLength(const RelocationEntry *RE) const;
+  unsigned getType(const RelocationEntry *RE) const;
 
   static inline bool classof(const Binary *v) {
     return v->isMachO();
@@ -479,15 +501,12 @@ MachOObjectFile<MachOT>::getRelocationAd
   const Section *Sect = getSection(Sections[Rel.d.b]);
   uint64_t SectAddress = Sect->Address;
   const RelocationEntry *RE = getRelocation(Rel);
-  unsigned Arch = getArch();
-  bool isScattered = (Arch != Triple::x86_64) &&
-                     (RE->Word0 & macho::RF_Scattered);
 
   uint64_t RelAddr;
-  if (isScattered)
-    RelAddr = RE->Word0 & 0xFFFFFF;
+  if (isScattered(RE))
+    RelAddr = RE->Address & 0xFFFFFF;
   else
-    RelAddr = RE->Word0;
+    RelAddr = RE->Address;
 
   Res = SectAddress + RelAddr;
   return object_error::success;
@@ -498,14 +517,10 @@ error_code
 MachOObjectFile<MachOT>::getRelocationOffset(DataRefImpl Rel,
                                              uint64_t &Res) const {
   const RelocationEntry *RE = getRelocation(Rel);
-
-  unsigned Arch = getArch();
-  bool isScattered = (Arch != Triple::x86_64) &&
-                     (RE->Word0 & macho::RF_Scattered);
-  if (isScattered)
-    Res = RE->Word0 & 0xFFFFFF;
+  if (isScattered(RE))
+    Res = RE->Address & 0xFFFFFF;
   else
-    Res = RE->Word0;
+    Res = RE->Address;
   return object_error::success;
 }
 
@@ -514,8 +529,8 @@ error_code
 MachOObjectFile<MachOT>::getRelocationSymbol(DataRefImpl Rel,
                                              SymbolRef &Res) const {
   const RelocationEntry *RE = getRelocation(Rel);
-  uint32_t SymbolIdx = RE->Word1 & 0xffffff;
-  bool isExtern = (RE->Word1 >> 27) & 1;
+  uint32_t SymbolIdx = RE->SymbolNum;
+  bool isExtern = RE->External;
 
   DataRefImpl Sym;
   moveToNextSymbol(Sym);
@@ -535,9 +550,7 @@ template<class MachOT>
 error_code MachOObjectFile<MachOT>::getRelocationType(DataRefImpl Rel,
                                                       uint64_t &Res) const {
   const RelocationEntry *RE = getRelocation(Rel);
-  Res = RE->Word0;
-  Res <<= 32;
-  Res |= RE->Word1;
+  Res = getType(RE);
   return object_error::success;
 }
 
@@ -550,14 +563,8 @@ MachOObjectFile<MachOT>::getRelocationTy
   const RelocationEntry *RE = getRelocation(Rel);
 
   unsigned Arch = getArch();
-  bool isScattered = (Arch != Triple::x86_64) &&
-                     (RE->Word0 & macho::RF_Scattered);
 
-  unsigned r_type;
-  if (isScattered)
-    r_type = (RE->Word0 >> 24) & 0xF;
-  else
-    r_type = (RE->Word1 >> 28) & 0xF;
+  unsigned r_type = getType(RE);
 
   switch (Arch) {
     case Triple::x86: {
@@ -650,30 +657,20 @@ MachOObjectFile<MachOT>::getRelocationVa
   const RelocationEntry *RE = getRelocation(Rel);
 
   unsigned Arch = getArch();
-  bool isScattered = (Arch != Triple::x86_64) &&
-                     (RE->Word0 & macho::RF_Scattered);
+  bool IsScattered = isScattered(RE);
 
   std::string fmtbuf;
   raw_string_ostream fmt(fmtbuf);
 
-  unsigned Type;
-  if (isScattered)
-    Type = (RE->Word0 >> 24) & 0xF;
-  else
-    Type = (RE->Word1 >> 28) & 0xF;
-
-  bool isPCRel;
-  if (isScattered)
-    isPCRel = ((RE->Word0 >> 30) & 1);
-  else
-    isPCRel = ((RE->Word1 >> 24) & 1);
+  unsigned Type = getType(RE);
+  bool IsPCRel = isPCRel(RE);
 
   // Determine any addends that should be displayed with the relocation.
   // These require decoding the relocation type, which is triple-specific.
 
   // X86_64 has entirely custom relocation types.
   if (Arch == Triple::x86_64) {
-    bool isPCRel = ((RE->Word1 >> 24) & 1);
+    bool isPCRel = RE->PCRel;
 
     switch (Type) {
       case macho::RIT_X86_64_GOTLoad:   // X86_64_RELOC_GOT_LOAD
@@ -691,7 +688,7 @@ MachOObjectFile<MachOT>::getRelocationVa
         // X86_64_SUBTRACTOR must be followed by a relocation of type
         // X86_64_RELOC_UNSIGNED.
         // NOTE: Scattered relocations don't exist on x86_64.
-        unsigned RType = (RENext->Word1 >> 28) & 0xF;
+        unsigned RType = RENext->Type;
         if (RType != 0)
           report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
                              "X86_64_RELOC_SUBTRACTOR.");
@@ -738,12 +735,12 @@ MachOObjectFile<MachOT>::getRelocationVa
         // X86 sect diff's must be followed by a relocation of type
         // GENERIC_RELOC_PAIR.
         bool isNextScattered = (Arch != Triple::x86_64) &&
-                               (RENext->Word0 & macho::RF_Scattered);
+                               (RENext->Address & macho::RF_Scattered);
         unsigned RType;
         if (isNextScattered)
-          RType = (RENext->Word0 >> 24) & 0xF;
+          RType = (RENext->Address >> 24) & 0xF;
         else
-          RType = (RENext->Word1 >> 28) & 0xF;
+          RType = RENext->Type;
         if (RType != 1)
           report_fatal_error("Expected GENERIC_RELOC_PAIR after "
                              "GENERIC_RELOC_SECTDIFF.");
@@ -767,12 +764,12 @@ MachOObjectFile<MachOT>::getRelocationVa
           // X86 sect diff's must be followed by a relocation of type
           // GENERIC_RELOC_PAIR.
           bool isNextScattered = (Arch != Triple::x86_64) &&
-                               (RENext->Word0 & macho::RF_Scattered);
+                               (RENext->Address & macho::RF_Scattered);
           unsigned RType;
           if (isNextScattered)
-            RType = (RENext->Word0 >> 24) & 0xF;
+            RType = (RENext->Address >> 24) & 0xF;
           else
-            RType = (RENext->Word1 >> 28) & 0xF;
+            RType = RENext->Type;
           if (RType != 1)
             report_fatal_error("Expected GENERIC_RELOC_PAIR after "
                                "GENERIC_RELOC_LOCAL_SECTDIFF.");
@@ -785,7 +782,7 @@ MachOObjectFile<MachOT>::getRelocationVa
         case macho::RIT_Generic_TLV: {
           printRelocationTargetName(RE, fmt);
           fmt << "@TLV";
-          if (isPCRel) fmt << "P";
+          if (IsPCRel) fmt << "P";
           break;
         }
         default:
@@ -798,10 +795,10 @@ MachOObjectFile<MachOT>::getRelocationVa
           // Half relocations steal a bit from the length field to encode
           // whether this is an upper16 or a lower16 relocation.
           bool isUpper;
-          if (isScattered)
-            isUpper = (RE->Word0 >> 28) & 1;
+          if (IsScattered)
+            isUpper = (RE->Address >> 28) & 1;
           else
-            isUpper = (RE->Word1 >> 25) & 1;
+            isUpper = (RE->Length >> 1) & 1;
 
           if (isUpper)
             fmt << ":upper16:(";
@@ -816,12 +813,12 @@ MachOObjectFile<MachOT>::getRelocationVa
           // ARM half relocs must be followed by a relocation of type
           // ARM_RELOC_PAIR.
           bool isNextScattered = (Arch != Triple::x86_64) &&
-                                 (RENext->Word0 & macho::RF_Scattered);
+                                 (RENext->Address & macho::RF_Scattered);
           unsigned RType;
           if (isNextScattered)
-            RType = (RENext->Word0 >> 24) & 0xF;
+            RType = (RENext->Address >> 24) & 0xF;
           else
-            RType = (RENext->Word1 >> 28) & 0xF;
+            RType = RENext->Type;
 
           if (RType != 1)
             report_fatal_error("Expected ARM_RELOC_PAIR after "
@@ -860,15 +857,8 @@ error_code
 MachOObjectFile<MachOT>::getRelocationHidden(DataRefImpl Rel,
                                              bool &Result) const {
   const RelocationEntry *RE = getRelocation(Rel);
-
   unsigned Arch = getArch();
-  bool isScattered = (Arch != Triple::x86_64) &&
-                     (RE->Word0 & macho::RF_Scattered);
-  unsigned Type;
-  if (isScattered)
-    Type = (RE->Word0 >> 24) & 0xF;
-  else
-    Type = (RE->Word1 >> 28) & 0xF;
+  unsigned Type = getType(RE);
 
   Result = false;
 
@@ -884,7 +874,7 @@ MachOObjectFile<MachOT>::getRelocationHi
       RelPrev.d.a--;
       const RelocationEntry *REPrev = getRelocation(RelPrev);
 
-      unsigned PrevType = (REPrev->Word1 >> 28) & 0xF;
+      unsigned PrevType = REPrev->Type;
 
       if (PrevType == macho::RIT_X86_64_Subtractor) Result = true;
     }

Modified: llvm/trunk/lib/Object/MachOObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=179294&r1=179293&r2=179294&view=diff
==============================================================================
--- llvm/trunk/lib/Object/MachOObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/MachOObjectFile.cpp Thu Apr 11 11:31:37 2013
@@ -80,6 +80,46 @@ StringRef MachOObjectFileBase::getData(s
   return ObjectFile::getData().substr(Offset, Size);
 }
 
+const MachOObjectFileBase::RelocationEntry *
+MachOObjectFileBase::getRelocation(DataRefImpl Rel) const {
+  if (const MachOObjectFile32Le *O = dyn_cast<MachOObjectFile32Le>(this))
+    return O->getRelocation(Rel);
+  const MachOObjectFile64Le *O = dyn_cast<MachOObjectFile64Le>(this);
+  return O->getRelocation(Rel);
+}
+
+bool MachOObjectFileBase::isScattered(const RelocationEntry *RE) const {
+  unsigned Arch = getArch();
+  return (Arch != Triple::x86_64) && (RE->Address & macho::RF_Scattered);
+}
+
+bool MachOObjectFileBase::isPCRel(const RelocationEntry *RE) const {
+  if (isScattered(RE)) {
+    const ScatteredRelocationEntry *SRE =
+      reinterpret_cast<const ScatteredRelocationEntry *>(RE);
+    return SRE->PCRel;
+  }
+  return RE->PCRel;
+}
+
+unsigned MachOObjectFileBase::getLength(const RelocationEntry *RE) const {
+  if (isScattered(RE)) {
+    const ScatteredRelocationEntry *SRE =
+      reinterpret_cast<const ScatteredRelocationEntry *>(RE);
+    return SRE->Length;
+  }
+  return RE->Length;
+}
+
+unsigned MachOObjectFileBase::getType(const RelocationEntry *RE) const {
+  if (isScattered(RE)) {
+    const ScatteredRelocationEntry *SRE =
+      reinterpret_cast<const ScatteredRelocationEntry *>(RE);
+    return SRE->Type;
+  }
+  return RE->Type;
+}
+
 ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
   StringRef Magic = Buffer->getBuffer().slice(0, 4);
   error_code ec;
@@ -435,16 +475,12 @@ void advanceTo(T &it, size_t Val) {
 void
 MachOObjectFileBase::printRelocationTargetName(const RelocationEntry *RE,
                                                raw_string_ostream &fmt) const {
-  unsigned Arch = getArch();
-  bool isScattered = (Arch != Triple::x86_64) &&
-                     (RE->Word0 & macho::RF_Scattered);
-
   // Target of a scattered relocation is an address.  In the interest of
   // generating pretty output, scan through the symbol table looking for a
   // symbol that aligns with that address.  If we find one, print it.
   // Otherwise, we just print the hex address of the target.
-  if (isScattered) {
-    uint32_t Val = RE->Word1;
+  if (isScattered(RE)) {
+    uint32_t Val = RE->SymbolNum;
 
     error_code ec;
     for (symbol_iterator SI = begin_symbols(), SE = end_symbols(); SI != SE;
@@ -486,8 +522,8 @@ MachOObjectFileBase::printRelocationTarg
   }
 
   StringRef S;
-  bool isExtern = (RE->Word1 >> 27) & 1;
-  uint32_t Val = RE->Word1 & 0xFFFFFF;
+  bool isExtern = RE->External;
+  uint32_t Val = RE->Address;
 
   if (isExtern) {
     symbol_iterator SI = begin_symbols();

Modified: llvm/trunk/test/tools/llvm-readobj/relocations.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/relocations.test?rev=179294&r1=179293&r2=179294&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/relocations.test (original)
+++ llvm/trunk/test/tools/llvm-readobj/relocations.test Thu Apr 11 11:31:37 2013
@@ -26,17 +26,17 @@ ELF-NEXT: ]
 
 MACHO-I386:      Relocations [
 MACHO-I386-NEXT:   Section __text {
-MACHO-I386-NEXT:     0x18 GENERIC_RELOC_VANILLA _SomeOtherFunction 0x0
-MACHO-I386-NEXT:     0x13 GENERIC_RELOC_VANILLA _puts 0x0
-MACHO-I386-NEXT:     0xB GENERIC_RELOC_LOCAL_SECTDIFF _main 0x{{[0-9A-F]+}}
-MACHO-I386-NEXT:     0x0 GENERIC_RELOC_PAIR _main 0x{{[0-9A-F]+}}
+MACHO-I386-NEXT:     0x18 1 2 1 GENERIC_RELOC_VANILLA 0 _SomeOtherFunction
+MACHO-I386-NEXT:     0x13 1 2 1 GENERIC_RELOC_VANILLA 0 _puts
+MACHO-I386-NEXT:     0xB 0 2 n/a GENERIC_RELOC_LOCAL_SECTDIFF 1 _main
+MACHO-I386-NEXT:     0x0 0 2 n/a GENERIC_RELOC_PAIR 1 _main
 MACHO-I386-NEXT:   }
 MACHO-I386-NEXT: ]
 
 MACHO-X86-64: Relocations [
 MACHO-X86-64-NEXT:  Section __text {
-MACHO-X86-64-NEXT:    0xE X86_64_RELOC_BRANCH _SomeOtherFunction 0x0
-MACHO-X86-64-NEXT:    0x9 X86_64_RELOC_BRANCH _puts 0x0
-MACHO-X86-64-NEXT:    0x4 X86_64_RELOC_SIGNED L_.str 0x0
+MACHO-X86-64-NEXT:    0xE 1 2 1 X86_64_RELOC_BRANCH 0 _SomeOtherFunction
+MACHO-X86-64-NEXT:    0x9 1 2 1 X86_64_RELOC_BRANCH 0 _puts
+MACHO-X86-64-NEXT:    0x4 1 2 1 X86_64_RELOC_SIGNED 0 L_.str
 MACHO-X86-64-NEXT:  }
 MACHO-X86-64-NEXT:]

Modified: llvm/trunk/test/tools/llvm-readobj/sections-ext.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/sections-ext.test?rev=179294&r1=179293&r2=179294&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/sections-ext.test (original)
+++ llvm/trunk/test/tools/llvm-readobj/sections-ext.test Thu Apr 11 11:31:37 2013
@@ -153,10 +153,10 @@ MACHO-I386-NEXT:     ]
 MACHO-I386-NEXT:     Reserved1: 0x0
 MACHO-I386-NEXT:     Reserved2: 0x0
 MACHO-I386-NEXT:     Relocations [
-MACHO-I386-NEXT:       0x18 GENERIC_RELOC_VANILLA _SomeOtherFunction 0x0
-MACHO-I386-NEXT:       0x13 GENERIC_RELOC_VANILLA _puts 0x0
-MACHO-I386-NEXT:       0xB GENERIC_RELOC_LOCAL_SECTDIFF _main 0x{{[0-9A-F]+}}
-MACHO-I386-NEXT:       0x0 GENERIC_RELOC_PAIR _main 0x{{[0-9A-F]+}}
+MACHO-I386-NEXT:       0x18 1 2 1 GENERIC_RELOC_VANILLA 0 _SomeOtherFunction
+MACHO-I386-NEXT:       0x13 1 2 1 GENERIC_RELOC_VANILLA 0 _puts
+MACHO-I386-NEXT:       0xB 0 2 n/a GENERIC_RELOC_LOCAL_SECTDIFF 1 _main
+MACHO-I386-NEXT:       0x0 0 2 n/a GENERIC_RELOC_PAIR 1 _main
 MACHO-I386-NEXT:     ]
 MACHO-I386-NEXT:     Symbols [
 MACHO-I386-NEXT:       Symbol {
@@ -196,9 +196,9 @@ MACHO-X86-64-NEXT:    ]
 MACHO-X86-64-NEXT:    Reserved1: 0x0
 MACHO-X86-64-NEXT:    Reserved2: 0x0
 MACHO-X86-64-NEXT:    Relocations [
-MACHO-X86-64-NEXT:      0xE X86_64_RELOC_BRANCH _SomeOtherFunction 0x0
-MACHO-X86-64-NEXT:      0x9 X86_64_RELOC_BRANCH _puts 0x0
-MACHO-X86-64-NEXT:      0x4 X86_64_RELOC_SIGNED L_.str 0x0
+MACHO-X86-64-NEXT:      0xE 1 2 1 X86_64_RELOC_BRANCH 0 _SomeOtherFunction
+MACHO-X86-64-NEXT:      0x9 1 2 1 X86_64_RELOC_BRANCH 0 _puts
+MACHO-X86-64-NEXT:      0x4 1 2 1 X86_64_RELOC_SIGNED 0 L_.str
 MACHO-X86-64-NEXT:    ]
 MACHO-X86-64-NEXT:    Symbols [
 MACHO-X86-64-NEXT:      Symbol {

Modified: llvm/trunk/tools/llvm-readobj/MachODumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/MachODumper.cpp?rev=179294&r1=179293&r2=179294&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/MachODumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/MachODumper.cpp Thu Apr 11 11:31:37 2013
@@ -330,20 +330,28 @@ void MachODumper::printRelocation(sectio
                                   relocation_iterator RelI) {
   uint64_t Offset;
   SmallString<32> RelocName;
-  int64_t Info;
   StringRef SymbolName;
   SymbolRef Symbol;
   if (error(RelI->getOffset(Offset))) return;
   if (error(RelI->getTypeName(RelocName))) return;
-  if (error(RelI->getAdditionalInfo(Info))) return;
   if (error(RelI->getSymbol(Symbol))) return;
   if (error(Symbol.getName(SymbolName))) return;
 
+  DataRefImpl DR = RelI->getRawDataRefImpl();
+  const MachOObjectFileBase::RelocationEntry *RE = Obj->getRelocation(DR);
+  bool IsScattered = Obj->isScattered(RE);
+
   raw_ostream& OS = W.startLine();
   OS << W.hex(Offset)
-     << " " << RelocName
+     << " " << Obj->isPCRel(RE)
+     << " " << Obj->getLength(RE);
+  if (IsScattered)
+    OS << " n/a";
+  else
+    OS << " " << RE->External;
+  OS << " " << RelocName
+     << " " << IsScattered
      << " " << (SymbolName.size() > 0 ? SymbolName : "-")
-     << " " << W.hex(Info)
      << "\n";
 }
 





More information about the llvm-commits mailing list