Handle relocations that don't point to symbols.
authorRafael Espindola <rafael.espindola@gmail.com>
Wed, 5 Jun 2013 01:33:53 +0000 (01:33 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Wed, 5 Jun 2013 01:33:53 +0000 (01:33 +0000)
In ELF (as in MachO), not all relocations point to symbols. Represent this
properly by using a symbol_iterator instead of a SymbolRef. Update llvm-readobj
ELF's dumper to handle relocatios without symbols.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@183284 91177308-0d34-0410-b5e6-96231b3b80d8

19 files changed:
include/llvm/Object/COFF.h
include/llvm/Object/ELF.h
include/llvm/Object/MachO.h
include/llvm/Object/ObjectFile.h
lib/DebugInfo/DWARFContext.cpp
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
lib/Object/COFFObjectFile.cpp
lib/Object/MachOObjectFile.cpp
lib/Object/Object.cpp
lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp
lib/Target/X86/MCTargetDesc/X86MachORelocationInfo.cpp
test/Object/Inputs/elf-reloc-no-sym.x86_64 [new file with mode: 0755]
test/Object/elf-reloc-no-sym.test [new file with mode: 0644]
tools/llvm-objdump/COFFDump.cpp
tools/llvm-objdump/MachODump.cpp
tools/llvm-readobj/COFFDumper.cpp
tools/llvm-readobj/ELFDumper.cpp
tools/llvm-readobj/MachODumper.cpp

index 1127263c9955cf732c814d9a8d5be483879a3259..c0efbbaab127b6a70e4bbce0c0abc16b81baa5f5 100644 (file)
@@ -243,8 +243,7 @@ protected:
                                           uint64_t &Res) const;
   virtual error_code getRelocationOffset(DataRefImpl Rel,
                                          uint64_t &Res) const;
-  virtual error_code getRelocationSymbol(DataRefImpl Rel,
-                                         SymbolRef &Res) const;
+  virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const;
   virtual error_code getRelocationType(DataRefImpl Rel,
                                        uint64_t &Res) const;
   virtual error_code getRelocationTypeName(DataRefImpl Rel,
index 592dbae39e4d1e8e284f2778c996b37d101313ee..a6c545ec9d15953ba413848ee66670becd0b3bfc 100644 (file)
@@ -716,8 +716,7 @@ protected:
                                           uint64_t &Res) const;
   virtual error_code getRelocationOffset(DataRefImpl Rel,
                                          uint64_t &Res) const;
-  virtual error_code getRelocationSymbol(DataRefImpl Rel,
-                                         SymbolRef &Res) const;
+  virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const;
   virtual error_code getRelocationType(DataRefImpl Rel,
                                        uint64_t &Res) const;
   virtual error_code getRelocationTypeName(DataRefImpl Rel,
@@ -1503,9 +1502,9 @@ error_code ELFObjectFile<ELFT>::getRelocationNext(DataRefImpl Rel,
   return object_error::success;
 }
 
-template<class ELFT>
-error_code ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel,
-                                                    SymbolRef &Result) const {
+template <class ELFT>
+symbol_iterator
+ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
   uint32_t symbolIdx;
   const Elf_Shdr *sec = getRelSection(Rel);
   switch (sec->sh_type) {
@@ -1520,6 +1519,9 @@ error_code ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel,
       break;
     }
   }
+  if (!symbolIdx)
+    return end_symbols();
+
   DataRefImpl SymbolData;
   IndexMap_t::const_iterator it =
       SymbolTableSectionsIndexMap.find(sec->sh_link);
@@ -1527,8 +1529,7 @@ error_code ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel,
     report_fatal_error("Relocation symbol table not found!");
   SymbolData.d.a = symbolIdx;
   SymbolData.d.b = it->second;
-  Result = SymbolRef(SymbolData, this);
-  return object_error::success;
+  return symbol_iterator(SymbolRef(SymbolData, this));
 }
 
 template<class ELFT>
index bedf5c101e2a1343793a118954855e21b8948340..f3ba8ef7572e57c427752c1f8ffa2029044c19c7 100644 (file)
@@ -72,7 +72,7 @@ public:
                                        RelocationRef &Res) const;
   virtual error_code getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const;
   virtual error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const;
-  virtual error_code getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const;
+  virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const;
   virtual error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const;
   virtual error_code getRelocationTypeName(DataRefImpl Rel,
                                            SmallVectorImpl<char> &Result) const;
index ba1bb6945b0be9f9f3e6e937ffdfcc0c44722ba8..f434d63736f65866fb5664c21be6f7da15dd5ecb 100644 (file)
@@ -85,6 +85,7 @@ inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
 }
 
 class SymbolRef;
+typedef content_iterator<SymbolRef> symbol_iterator;
 
 /// RelocationRef - This is a value type class that represents a single
 /// relocation in the list of relocations in the object file.
@@ -103,7 +104,7 @@ public:
 
   error_code getAddress(uint64_t &Result) const;
   error_code getOffset(uint64_t &Result) const;
-  error_code getSymbol(SymbolRef &Result) const;
+  symbol_iterator getSymbol() const;
   error_code getType(uint64_t &Result) const;
 
   /// @brief Indicates whether this relocation should hidden when listing
@@ -236,7 +237,6 @@ public:
 
   DataRefImpl getRawDataRefImpl() const;
 };
-typedef content_iterator<SymbolRef> symbol_iterator;
 
 /// LibraryRef - This is a value type class that represents a single library in
 /// the list of libraries needed by a shared or dynamic object.
@@ -334,8 +334,7 @@ protected:
                                           uint64_t &Res) const =0;
   virtual error_code getRelocationOffset(DataRefImpl Rel,
                                          uint64_t &Res) const =0;
-  virtual error_code getRelocationSymbol(DataRefImpl Rel,
-                                         SymbolRef &Res) const = 0;
+  virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0;
   virtual error_code getRelocationType(DataRefImpl Rel,
                                        uint64_t &Res) const = 0;
   virtual error_code getRelocationTypeName(DataRefImpl Rel,
@@ -566,8 +565,8 @@ inline error_code RelocationRef::getOffset(uint64_t &Result) const {
   return OwningObject->getRelocationOffset(RelocationPimpl, Result);
 }
 
-inline error_code RelocationRef::getSymbol(SymbolRef &Result) const {
-  return OwningObject->getRelocationSymbol(RelocationPimpl, Result);
+inline symbol_iterator RelocationRef::getSymbol() const {
+  return OwningObject->getRelocationSymbol(RelocationPimpl);
 }
 
 inline error_code RelocationRef::getType(uint64_t &Result) const {
index 7e4132f059b37d799607ec14954f842e9d38ab0d..aaae952da5b10c114fa1a204fde8c8ab28814442 100644 (file)
@@ -595,9 +595,8 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
         uint64_t SymAddr = 0;
         // ELF relocations may need the symbol address
         if (Obj->isELF()) {
-          object::SymbolRef Sym;
-          reloc_i->getSymbol(Sym);
-          Sym.getAddress(SymAddr);
+          object::symbol_iterator Sym = reloc_i->getSymbol();
+          Sym->getAddress(SymAddr);
         }
 
         object::RelocVisitor V(Obj->getFileFormatName());
index ee424db6afff18bbc722822cf6198a4913b69f5e..e552cea1bc0260330ce6595c2f670d7ca75cb282 100644 (file)
@@ -551,9 +551,8 @@ void RuntimeDyldELF::findOPDEntrySection(ObjectImage &Obj,
         continue;
       }
 
-      SymbolRef TargetSymbol;
       uint64_t TargetSymbolOffset;
-      check(i->getSymbol(TargetSymbol));
+      symbol_iterator TargetSymbol = i->getSymbol();
       check(i->getOffset(TargetSymbolOffset));
       int64_t Addend;
       check(getELFRelocationAddend(*i, Addend));
@@ -576,7 +575,7 @@ void RuntimeDyldELF::findOPDEntrySection(ObjectImage &Obj,
         continue;
 
       section_iterator tsi(Obj.end_sections());
-      check(TargetSymbol.getSection(tsi));
+      check(TargetSymbol->getSection(tsi));
       Rel.SectionID = findOrEmitSection(Obj, (*tsi), true, LocalSections);
       Rel.Addend = (intptr_t)Addend;
       return;
@@ -777,12 +776,11 @@ void RuntimeDyldELF::processRelocationRef(unsigned SectionID,
   Check(RelI.getType(RelType));
   int64_t Addend;
   Check(getELFRelocationAddend(RelI, Addend));
-  SymbolRef Symbol;
-  Check(RelI.getSymbol(Symbol));
+  symbol_iterator Symbol = RelI.getSymbol();
 
   // Obtain the symbol name which is referenced in the relocation
   StringRef TargetName;
-  Symbol.getName(TargetName);
+  Symbol->getName(TargetName);
   DEBUG(dbgs() << "\t\tRelType: " << RelType
                << " Addend: " << Addend
                << " TargetName: " << TargetName
@@ -791,7 +789,7 @@ void RuntimeDyldELF::processRelocationRef(unsigned SectionID,
   // First search for the symbol in the local symbol table
   SymbolTableMap::const_iterator lsi = Symbols.find(TargetName.data());
   SymbolRef::Type SymType;
-  Symbol.getType(SymType);
+  Symbol->getType(SymType);
   if (lsi != Symbols.end()) {
     Value.SectionID = lsi->second.first;
     Value.Addend = lsi->second.second + Addend;
@@ -809,7 +807,7 @@ void RuntimeDyldELF::processRelocationRef(unsigned SectionID,
           // and can be changed by another developers. Maybe best way is add
           // a new symbol type ST_Section to SymbolRef and use it.
           section_iterator si(Obj.end_sections());
-          Symbol.getSection(si);
+          Symbol->getSection(si);
           if (si == Obj.end_sections())
             llvm_unreachable("Symbol section not found, bad object file format!");
           DEBUG(dbgs() << "\t\tThis is section symbol\n");
index 01a3fd9f82d9e53632bb95f6c69d5504d05db117..0384b322624dec1bc8ccbc2e49399c0bf21e00b8 100644 (file)
@@ -302,10 +302,9 @@ void RuntimeDyldMachO::processRelocationRef(unsigned SectionID,
 
   if (isExtern) {
     // Obtain the symbol name which is referenced in the relocation
-    SymbolRef Symbol;
-    RelI.getSymbol(Symbol);
+    symbol_iterator Symbol = RelI.getSymbol();
     StringRef TargetName;
-    Symbol.getName(TargetName);
+    Symbol->getName(TargetName);
     // First search for the symbol in the local symbol table
     SymbolTableMap::const_iterator lsi = Symbols.find(TargetName.data());
     if (lsi != Symbols.end()) {
index f5b49ab0618d1480891471042b4baaca09f86f57..bc5958d3c479289ff6bd2a14f69fca7bdbe27708 100644 (file)
@@ -712,13 +712,11 @@ error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel,
   Res = toRel(Rel)->VirtualAddress;
   return object_error::success;
 }
-error_code COFFObjectFile::getRelocationSymbol(DataRefImpl Rel,
-                                               SymbolRef &Res) const {
+symbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
   const coff_relocation* R = toRel(Rel);
   DataRefImpl Symb;
   Symb.p = reinterpret_cast<uintptr_t>(SymbolTable + R->SymbolTableIndex);
-  Res = SymbolRef(Symb, this);
-  return object_error::success;
+  return symbol_iterator(SymbolRef(Symb, this));
 }
 error_code COFFObjectFile::getRelocationType(DataRefImpl Rel,
                                              uint64_t &Res) const {
index 654af081f9e15ae3e368b9c908d8d261b885aa57..bd5ea57c1f536c09efae1ad7ef6ddda2563668ad 100644 (file)
@@ -869,15 +869,13 @@ error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
   return object_error::success;
 }
 
-error_code
-MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const {
+symbol_iterator
+MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
   macho::RelocationEntry RE = getRelocation(Rel);
   uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
   bool isExtern = getPlainRelocationExternal(RE);
-  if (!isExtern) {
-    Res = *end_symbols();
-    return object_error::success;
-  }
+  if (!isExtern)
+    return end_symbols();
 
   macho::SymtabLoadCommand S = getSymtabLoadCommand();
   unsigned SymbolTableEntrySize = is64Bit() ?
@@ -886,8 +884,7 @@ MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const {
   uint64_t Offset = S.SymbolTableOffset + SymbolIdx * SymbolTableEntrySize;
   DataRefImpl Sym;
   Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
-  Res = SymbolRef(Sym, this);
-  return object_error::success;
+  return symbol_iterator(SymbolRef(Sym, this));
 }
 
 error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
index 3e2c78ec47c180776b4a3893821380634038cef0..6941708dd349014dd65e40ed84bd3219c8026c86 100644 (file)
@@ -219,10 +219,7 @@ uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) {
 }
 
 LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) {
-  SymbolRef ret;
-  if (error_code ec = (*unwrap(RI))->getSymbol(ret))
-    report_fatal_error(ec.message());
-
+  symbol_iterator ret = (*unwrap(RI))->getSymbol();
   return wrap(new symbol_iterator(ret));
 }
 
index 917c37d2ca5ba03146f9a03ed7c9054a69b80f85..8f4ab4673d57fe90aedb4fb25f94de37c7dd7c35 100644 (file)
@@ -27,11 +27,11 @@ public:
 
   const MCExpr *createExprForRelocation(RelocationRef Rel) {
     uint64_t RelType; Rel.getType(RelType);
-    SymbolRef SymRef; Rel.getSymbol(SymRef);
+    symbol_iterator SymI = Rel.getSymbol();
 
-    StringRef SymName; SymRef.getName(SymName);
-    uint64_t  SymAddr; SymRef.getAddress(SymAddr);
-    uint64_t  SymSize; SymRef.getSize(SymSize);
+    StringRef SymName; SymI->getName(SymName);
+    uint64_t  SymAddr; SymI->getAddress(SymAddr);
+    uint64_t  SymSize; SymI->getSize(SymSize);
     int64_t  Addend;  getELFRelocationAddend(Rel, Addend);
 
     MCSymbol *Sym = Ctx.GetOrCreateSymbol(SymName);
index a76cad555dfb9311231414501e6a280d1f43be84..75b5acf508976c85aba7406df15602d619e08d62 100644 (file)
@@ -28,10 +28,10 @@ public:
     const MachOObjectFile *Obj = cast<MachOObjectFile>(Rel.getObjectFile());
 
     uint64_t RelType; Rel.getType(RelType);
-    SymbolRef SymRef; Rel.getSymbol(SymRef);
+    symbol_iterator SymI = Rel.getSymbol();
 
-    StringRef SymName; SymRef.getName(SymName);
-    uint64_t  SymAddr; SymRef.getAddress(SymAddr);
+    StringRef SymName; SymI->getName(SymName);
+    uint64_t  SymAddr; SymI->getAddress(SymAddr);
 
     RelocationEntry RE = Obj->getRelocation(Rel.getRawDataRefImpl());
     bool isPCRel = Obj->getAnyRelocationPCRel(RE);
@@ -86,12 +86,11 @@ public:
 
         const MCExpr *LHS = MCSymbolRefExpr::Create(Sym, Ctx);
 
-        SymbolRef RSymRef;
-        RelNext.getSymbol(RSymRef);
+        symbol_iterator RSymI = RelNext.getSymbol();
         uint64_t RSymAddr;
-        RSymRef.getAddress(RSymAddr);
+        RSymI->getAddress(RSymAddr);
         StringRef RSymName;
-        RSymRef.getName(RSymName);
+        RSymI->getName(RSymName);
 
         MCSymbol *RSym = Ctx.GetOrCreateSymbol(RSymName);
         if (RSym->isVariable() == false)
diff --git a/test/Object/Inputs/elf-reloc-no-sym.x86_64 b/test/Object/Inputs/elf-reloc-no-sym.x86_64
new file mode 100755 (executable)
index 0000000..a41b4e0
Binary files /dev/null and b/test/Object/Inputs/elf-reloc-no-sym.x86_64 differ
diff --git a/test/Object/elf-reloc-no-sym.test b/test/Object/elf-reloc-no-sym.test
new file mode 100644 (file)
index 0000000..eabde0c
--- /dev/null
@@ -0,0 +1,7 @@
+RUN: llvm-readobj -r %p/Inputs/elf-reloc-no-sym.x86_64 | FileCheck %s
+
+CHECK:      Relocations [
+CHECK-NEXT:   Section (1) .rela.plt {
+CHECK-NEXT:     0x4011D8 R_X86_64_IRELATIVE - 0x400120
+CHECK-NEXT:   }
+CHECK-NEXT: ]
index 2ada683f2df10db5c0410dbe3058d0823c2ea13b..7b550077ae54d01d67303394587b4ae769a06170 100644 (file)
@@ -178,7 +178,7 @@ static error_code resolveSymbol(const std::vector<RelocationRef> &Rels,
     uint64_t Ofs;
     if (error_code ec = I->getOffset(Ofs)) return ec;
     if (Ofs == Offset) {
-      if (error_code ec = I->getSymbol(Sym)) return ec;
+      Sym = *I->getSymbol();
       break;
     }
   }
index 03a383eb120d4d1c26c45a8ef9aaa1d115769315..1ee3e42dab7f40178e12d1be0c1c2d0a610b0fcc 100644 (file)
@@ -250,10 +250,9 @@ static void DisassembleInputMachO2(StringRef Filename,
       Sections[SectIdx].getAddress(SectionAddress);
       RelocOffset -= SectionAddress;
 
-      SymbolRef RelocSym;
-      RI->getSymbol(RelocSym);
+      symbol_iterator RelocSym = RI->getSymbol();
 
-      Relocs.push_back(std::make_pair(RelocOffset, RelocSym));
+      Relocs.push_back(std::make_pair(RelocOffset, *RelocSym));
     }
     array_pod_sort(Relocs.begin(), Relocs.end());
 
index 94aafa7eb11186118d1f095f68e5923eccbda7fe..3cbb9b3c34bf1b06eb229823db6a94263ccf6045 100644 (file)
@@ -201,8 +201,7 @@ static error_code resolveSymbol(const std::vector<RelocationRef> &Rels,
       return EC;
 
     if (Ofs == Offset) {
-      if (error_code EC = RelI->getSymbol(Sym))
-        return EC;
+      Sym = *RelI->getSymbol();
       return readobj_error::success;
     }
   }
@@ -670,14 +669,13 @@ void COFFDumper::printRelocation(section_iterator SecI,
   uint64_t Offset;
   uint64_t RelocType;
   SmallString<32> RelocName;
-  SymbolRef Symbol;
   StringRef SymbolName;
   StringRef Contents;
   if (error(RelI->getOffset(Offset))) return;
   if (error(RelI->getType(RelocType))) return;
   if (error(RelI->getTypeName(RelocName))) return;
-  if (error(RelI->getSymbol(Symbol))) return;
-  if (error(Symbol.getName(SymbolName))) return;
+  symbol_iterator Symbol = RelI->getSymbol();
+  if (error(Symbol->getName(SymbolName))) return;
   if (error(SecI->getContents(Contents))) return;
 
   if (opts::ExpandRelocs) {
index 2427b7d3b140ac489da8e823d8c88b54f0cb1c18..67bbafaf6f29de498e15de99c4c5f2f4217023ca 100644 (file)
@@ -571,7 +571,6 @@ void ELFDumper<ELFT>::printRelocation(section_iterator Sec,
   SmallString<32> RelocName;
   int64_t Addend;
   StringRef SymbolName;
-  SymbolRef Symbol;
   if (Obj->getElfHeader()->e_type == ELF::ET_REL){
     if (error(RelI->getOffset(Offset))) return;
   } else {
@@ -580,8 +579,9 @@ void ELFDumper<ELFT>::printRelocation(section_iterator Sec,
   if (error(RelI->getType(RelocType))) return;
   if (error(RelI->getTypeName(RelocName))) return;
   if (error(getELFRelocationAddend(*RelI, Addend))) return;
-  if (error(RelI->getSymbol(Symbol))) return;
-  if (error(Symbol.getName(SymbolName))) return;
+  symbol_iterator Symbol = RelI->getSymbol();
+  if (Symbol != Obj->end_symbols() && error(Symbol->getName(SymbolName)))
+    return;
 
   if (opts::ExpandRelocs) {
     DictScope Group(W, "Relocation");
index 31dc5ce24a2428c9c4242e9d58991f422ad77ffc..8df6fd6457ffd729c8980445b3039ea43a218ecc 100644 (file)
@@ -341,12 +341,11 @@ void MachODumper::printRelocation(const MachOObjectFile *Obj,
   uint64_t Offset;
   SmallString<32> RelocName;
   StringRef SymbolName;
-  SymbolRef Symbol;
   if (error(RelI->getOffset(Offset))) return;
   if (error(RelI->getTypeName(RelocName))) return;
-  if (error(RelI->getSymbol(Symbol))) return;
-  if (symbol_iterator(Symbol) != Obj->end_symbols() &&
-      error(Symbol.getName(SymbolName)))
+  symbol_iterator Symbol = RelI->getSymbol();
+  if (Symbol != Obj->end_symbols() &&
+      error(Symbol->getName(SymbolName)))
     return;
 
   DataRefImpl DR = RelI->getRawDataRefImpl();