[llvm-commits] [llvm] r151785 - in /llvm/trunk: include/llvm/Object/ lib/Object/ test/Object/ test/Object/Inputs/ tools/ tools/llvm-readobj/

David Meyer pdox at google.com
Wed Feb 29 17:36:50 PST 2012


Author: pdox
Date: Wed Feb 29 19:36:50 2012
New Revision: 151785

URL: http://llvm.org/viewvc/llvm-project?rev=151785&view=rev
Log:
[Object]
* Add begin_dynamic_table() / end_dynamic_table() private interface to ELFObjectFile.
* Add begin_libraries_needed() / end_libraries_needed() interface to ObjectFile, for grabbing the list of needed libraries for a shared object or dynamic executable.
* Implement this new interface completely for ELF, leave stubs for COFF and MachO.
* Add 'llvm-readobj' tool for dumping ObjectFile information.


Added:
    llvm/trunk/test/Object/readobj-shared-object.test
    llvm/trunk/tools/llvm-readobj/
    llvm/trunk/tools/llvm-readobj/CMakeLists.txt
    llvm/trunk/tools/llvm-readobj/LLVMBuild.txt
    llvm/trunk/tools/llvm-readobj/Makefile
    llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
Modified:
    llvm/trunk/include/llvm/Object/COFF.h
    llvm/trunk/include/llvm/Object/ELF.h
    llvm/trunk/include/llvm/Object/MachO.h
    llvm/trunk/include/llvm/Object/ObjectFile.h
    llvm/trunk/lib/Object/COFFObjectFile.cpp
    llvm/trunk/lib/Object/MachOObjectFile.cpp
    llvm/trunk/test/Object/Inputs/shared-object-test.elf-i386   (contents, props changed)
    llvm/trunk/test/Object/Inputs/shared-object-test.elf-x86-64   (contents, props changed)
    llvm/trunk/test/Object/Inputs/shared.ll
    llvm/trunk/tools/CMakeLists.txt
    llvm/trunk/tools/Makefile

Modified: llvm/trunk/include/llvm/Object/COFF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/COFF.h?rev=151785&r1=151784&r2=151785&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/COFF.h (original)
+++ llvm/trunk/include/llvm/Object/COFF.h Wed Feb 29 19:36:50 2012
@@ -145,12 +145,19 @@
   virtual error_code getRelocationValueString(DataRefImpl Rel,
                                            SmallVectorImpl<char> &Result) const;
 
+  virtual error_code getLibraryNext(DataRefImpl LibData,
+                                    LibraryRef &Result) const;
+  virtual error_code getLibraryPath(DataRefImpl LibData,
+                                    StringRef &Result) const;
+
 public:
   COFFObjectFile(MemoryBuffer *Object, error_code &ec);
   virtual symbol_iterator begin_symbols() const;
   virtual symbol_iterator end_symbols() const;
   virtual symbol_iterator begin_dynamic_symbols() const;
   virtual symbol_iterator end_dynamic_symbols() const;
+  virtual library_iterator begin_libraries_needed() const;
+  virtual library_iterator end_libraries_needed() const;
   virtual section_iterator begin_sections() const;
   virtual section_iterator end_sections() const;
 

Modified: llvm/trunk/include/llvm/Object/ELF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ELF.h?rev=151785&r1=151784&r2=151785&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELF.h (original)
+++ llvm/trunk/include/llvm/Object/ELF.h Wed Feb 29 19:36:50 2012
@@ -176,6 +176,71 @@
   }
 };
 
+// Elf_Dyn: Entry in the dynamic table
+template<support::endianness target_endianness, bool is64Bits>
+struct Elf_Dyn_Base;
+
+template<support::endianness target_endianness>
+struct Elf_Dyn_Base<target_endianness, false> {
+  LLVM_ELF_IMPORT_TYPES(target_endianness, false)
+  Elf_Sword d_tag;
+  union {
+    Elf_Word d_val;
+    Elf_Addr d_ptr;
+  } d_un;
+};
+
+template<support::endianness target_endianness>
+struct Elf_Dyn_Base<target_endianness, true> {
+  LLVM_ELF_IMPORT_TYPES(target_endianness, true)
+  Elf_Sxword d_tag;
+  union {
+    Elf_Xword d_val;
+    Elf_Addr d_ptr;
+  } d_un;
+};
+
+template<support::endianness target_endianness, bool is64Bits>
+struct Elf_Dyn_Impl : Elf_Dyn_Base<target_endianness, is64Bits> {
+  using Elf_Dyn_Base<target_endianness, is64Bits>::d_tag;
+  using Elf_Dyn_Base<target_endianness, is64Bits>::d_un;
+  int64_t getTag() const { return d_tag; }
+  uint64_t getVal() const { return d_un.d_val; }
+  uint64_t getPtr() const { return d_un.ptr; }
+};
+
+template<support::endianness target_endianness, bool is64Bits>
+class ELFObjectFile;
+
+// DynRefImpl: Reference to an entry in the dynamic table
+// This is an ELF-specific interface.
+template<support::endianness target_endianness, bool is64Bits>
+class DynRefImpl {
+  typedef Elf_Dyn_Impl<target_endianness, is64Bits> Elf_Dyn;
+  typedef ELFObjectFile<target_endianness, is64Bits> OwningType;
+
+  DataRefImpl DynPimpl;
+  const OwningType *OwningObject;
+
+public:
+  DynRefImpl() : OwningObject(NULL) {
+    std::memset(&DynPimpl, 0, sizeof(DynPimpl));
+  }
+
+  DynRefImpl(DataRefImpl DynP, const OwningType *Owner);
+
+  bool operator==(const DynRefImpl &Other) const;
+  bool operator <(const DynRefImpl &Other) const;
+
+  error_code getNext(DynRefImpl &Result) const;
+  int64_t getTag() const;
+  uint64_t getVal() const;
+  uint64_t getPtr() const;
+
+  DataRefImpl getRawDataRefImpl() const;
+};
+
+// Elf_Rel: Elf Relocation
 template<support::endianness target_endianness, bool is64Bits, bool isRela>
 struct Elf_Rel_Base;
 
@@ -255,8 +320,11 @@
 
   typedef Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;
   typedef Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
+  typedef Elf_Dyn_Impl<target_endianness, is64Bits> Elf_Dyn;
   typedef Elf_Rel_Impl<target_endianness, is64Bits, false> Elf_Rel;
   typedef Elf_Rel_Impl<target_endianness, is64Bits, true> Elf_Rela;
+  typedef DynRefImpl<target_endianness, is64Bits> DynRef;
+  typedef content_iterator<DynRef> dyn_iterator;
 
 protected:
   struct Elf_Ehdr {
@@ -300,6 +368,8 @@
   IndexMap_t SymbolTableSectionsIndexMap;
   DenseMap<const Elf_Sym*, ELF::Elf64_Word> ExtendedSymbolTable;
 
+  const Elf_Shdr *dot_dynamic_sec; // .dynamic
+
   /// @brief Map sections to an array of relocation sections that reference
   ///        them sorted by section index.
   RelocMap_t SectionRelocMap;
@@ -329,6 +399,9 @@
   const Elf_Sym  *getSymbol(DataRefImpl Symb) const; // FIXME: Should be private?
   void            validateSymbol(DataRefImpl Symb) const;
 
+public:
+  const Elf_Dyn  *getDyn(DataRefImpl DynData) const;
+
 protected:
   virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
   virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
@@ -341,6 +414,12 @@
   virtual error_code getSymbolSection(DataRefImpl Symb,
                                       section_iterator &Res) const;
 
+  friend class DynRefImpl<target_endianness, is64Bits>;
+  virtual error_code getDynNext(DataRefImpl DynData, DynRef &Result) const;
+
+  virtual error_code getLibraryNext(DataRefImpl Data, LibraryRef &Result) const;
+  virtual error_code getLibraryPath(DataRefImpl Data, StringRef &Res) const;
+
   virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
   virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
   virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
@@ -376,11 +455,19 @@
   ELFObjectFile(MemoryBuffer *Object, error_code &ec);
   virtual symbol_iterator begin_symbols() const;
   virtual symbol_iterator end_symbols() const;
+
   virtual symbol_iterator begin_dynamic_symbols() const;
   virtual symbol_iterator end_dynamic_symbols() const;
+
   virtual section_iterator begin_sections() const;
   virtual section_iterator end_sections() const;
 
+  virtual library_iterator begin_libraries_needed() const;
+  virtual library_iterator end_libraries_needed() const;
+
+  virtual dyn_iterator begin_dynamic_table() const;
+  virtual dyn_iterator end_dynamic_table() const;
+
   virtual uint8_t getBytesInAddress() const;
   virtual StringRef getFileFormatName() const;
   virtual unsigned getArch() const;
@@ -1171,7 +1258,8 @@
   , SectionHeaderTable(0)
   , dot_shstrtab_sec(0)
   , dot_strtab_sec(0)
-  , dot_dynstr_sec(0) {
+  , dot_dynstr_sec(0)
+  , dot_dynamic_sec(0) {
 
   const uint64_t FileSize = Data->getBufferSize();
 
@@ -1227,6 +1315,12 @@
     if (sh->sh_type == ELF::SHT_REL || sh->sh_type == ELF::SHT_RELA) {
       SectionRelocMap[getSection(sh->sh_info)].push_back(i);
     }
+    if (sh->sh_type == ELF::SHT_DYNAMIC) {
+      if (dot_dynamic_sec != NULL)
+        // FIXME: Proper error handling.
+        report_fatal_error("More than one .dynamic!");
+      dot_dynamic_sec = sh;
+    }
     ++sh;
   }
 
@@ -1353,6 +1447,121 @@
 }
 
 template<support::endianness target_endianness, bool is64Bits>
+typename ELFObjectFile<target_endianness, is64Bits>::dyn_iterator
+ELFObjectFile<target_endianness, is64Bits>::begin_dynamic_table() const {
+  DataRefImpl DynData;
+  memset(&DynData, 0, sizeof(DynData));
+  if (dot_dynamic_sec == NULL || dot_dynamic_sec->sh_size == 0) {
+    DynData.d.a = std::numeric_limits<uint32_t>::max();
+  } else {
+    DynData.d.a = 0;
+  }
+  return dyn_iterator(DynRef(DynData, this));
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+typename ELFObjectFile<target_endianness, is64Bits>::dyn_iterator
+ELFObjectFile<target_endianness, is64Bits>
+                          ::end_dynamic_table() const {
+  DataRefImpl DynData;
+  memset(&DynData, 0, sizeof(DynData));
+  DynData.d.a = std::numeric_limits<uint32_t>::max();
+  return dyn_iterator(DynRef(DynData, this));
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+                        ::getDynNext(DataRefImpl DynData,
+                                     DynRef &Result) const {
+  ++DynData.d.a;
+
+  // Check to see if we are at the end of .dynamic
+  if (DynData.d.a >= dot_dynamic_sec->getEntityCount()) {
+    // We are at the end. Return the terminator.
+    DynData.d.a = std::numeric_limits<uint32_t>::max();
+  }
+
+  Result = DynRef(DynData, this);
+  return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+library_iterator ELFObjectFile<target_endianness, is64Bits>
+                             ::begin_libraries_needed() const {
+  // Find the first DT_NEEDED entry
+  dyn_iterator i = begin_dynamic_table();
+  dyn_iterator e = end_dynamic_table();
+  error_code ec;
+  while (i != e) {
+    if (i->getTag() == ELF::DT_NEEDED)
+      break;
+    i.increment(ec);
+    if (ec)
+      report_fatal_error("dynamic table iteration failed");
+  }
+  // Use the same DataRefImpl format as DynRef.
+  return library_iterator(LibraryRef(i->getRawDataRefImpl(), this));
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+                        ::getLibraryNext(DataRefImpl Data,
+                                         LibraryRef &Result) const {
+  // Use the same DataRefImpl format as DynRef.
+  dyn_iterator i = dyn_iterator(DynRef(Data, this));
+  dyn_iterator e = end_dynamic_table();
+
+  // Skip the current dynamic table entry.
+  error_code ec;
+  if (i != e) {
+    i.increment(ec);
+    // TODO: proper error handling
+    if (ec)
+      report_fatal_error("dynamic table iteration failed");
+  }
+
+  // Find the next DT_NEEDED entry.
+  while (i != e) {
+    if (i->getTag() == ELF::DT_NEEDED)
+      break;
+    i.increment(ec);
+    if (ec)
+      report_fatal_error("dynamic table iteration failed");
+  }
+  Result = LibraryRef(i->getRawDataRefImpl(), this);
+  return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+error_code ELFObjectFile<target_endianness, is64Bits>
+         ::getLibraryPath(DataRefImpl Data, StringRef &Res) const {
+  dyn_iterator i = dyn_iterator(DynRef(Data, this));
+  if (i == end_dynamic_table())
+    report_fatal_error("getLibraryPath() called on iterator end");
+
+  if (i->getTag() != ELF::DT_NEEDED)
+    report_fatal_error("Invalid library_iterator");
+
+  // This uses .dynstr to lookup the name of the DT_NEEDED entry.
+  // THis works as long as DT_STRTAB == .dynstr. This is true most of
+  // the time, but the specification allows exceptions.
+  // TODO: This should really use DT_STRTAB instead. Doing this requires
+  // reading the program headers.
+  if (dot_dynstr_sec == NULL)
+    report_fatal_error("Dynamic string table is missing");
+  Res = getString(dot_dynstr_sec, i->getVal());
+  return object_error::success;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+library_iterator ELFObjectFile<target_endianness, is64Bits>
+                             ::end_libraries_needed() const {
+  dyn_iterator e = end_dynamic_table();
+  // Use the same DataRefImpl format as DynRef.
+  return library_iterator(LibraryRef(e->getRawDataRefImpl(), this));
+}
+
+template<support::endianness target_endianness, bool is64Bits>
 uint8_t ELFObjectFile<target_endianness, is64Bits>::getBytesInAddress() const {
   return is64Bits ? 8 : 4;
 }
@@ -1450,6 +1659,12 @@
 }
 
 template<support::endianness target_endianness, bool is64Bits>
+const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Dyn *
+ELFObjectFile<target_endianness, is64Bits>::getDyn(DataRefImpl DynData) const {
+  return getEntry<Elf_Dyn>(dot_dynamic_sec, DynData.d.a);
+}
+
+template<support::endianness target_endianness, bool is64Bits>
 const typename ELFObjectFile<target_endianness, is64Bits>::Elf_Rel *
 ELFObjectFile<target_endianness, is64Bits>::getRel(DataRefImpl Rel) const {
   return getEntry<Elf_Rel>(Rel.w.b, Rel.w.c);
@@ -1527,6 +1742,54 @@
   return object_error::success;
 }
 
+template<support::endianness target_endianness, bool is64Bits>
+inline DynRefImpl<target_endianness, is64Bits>
+                 ::DynRefImpl(DataRefImpl DynP, const OwningType *Owner)
+  : DynPimpl(DynP)
+  , OwningObject(Owner) {}
+
+template<support::endianness target_endianness, bool is64Bits>
+inline bool DynRefImpl<target_endianness, is64Bits>
+                      ::operator==(const DynRefImpl &Other) const {
+  return DynPimpl == Other.DynPimpl;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+inline bool DynRefImpl<target_endianness, is64Bits>
+                      ::operator <(const DynRefImpl &Other) const {
+  return DynPimpl < Other.DynPimpl;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+inline error_code DynRefImpl<target_endianness, is64Bits>
+                            ::getNext(DynRefImpl &Result) const {
+  return OwningObject->getDynNext(DynPimpl, Result);
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+inline int64_t DynRefImpl<target_endianness, is64Bits>
+                            ::getTag() const {
+  return OwningObject->getDyn(DynPimpl)->d_tag;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+inline uint64_t DynRefImpl<target_endianness, is64Bits>
+                            ::getVal() const {
+  return OwningObject->getDyn(DynPimpl)->d_un.d_val;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+inline uint64_t DynRefImpl<target_endianness, is64Bits>
+                            ::getPtr() const {
+  return OwningObject->getDyn(DynPimpl)->d_un.d_ptr;
+}
+
+template<support::endianness target_endianness, bool is64Bits>
+inline DataRefImpl DynRefImpl<target_endianness, is64Bits>
+                             ::getRawDataRefImpl() const {
+  return DynPimpl;
+}
+
 }
 }
 

Modified: llvm/trunk/include/llvm/Object/MachO.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/MachO.h?rev=151785&r1=151784&r2=151785&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/MachO.h (original)
+++ llvm/trunk/include/llvm/Object/MachO.h Wed Feb 29 19:36:50 2012
@@ -34,6 +34,8 @@
   virtual symbol_iterator end_symbols() const;
   virtual symbol_iterator begin_dynamic_symbols() const;
   virtual symbol_iterator end_dynamic_symbols() const;
+  virtual library_iterator begin_libraries_needed() const;
+  virtual library_iterator end_libraries_needed() const;
   virtual section_iterator begin_sections() const;
   virtual section_iterator end_sections() const;
 
@@ -92,6 +94,9 @@
                                            SmallVectorImpl<char> &Result) const;
   virtual error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const;
 
+  virtual error_code getLibraryNext(DataRefImpl LibData, LibraryRef &Res) const;
+  virtual error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const;
+
 private:
   MachOObject *MachOObj;
   mutable uint32_t RegisteredStringTable;

Modified: llvm/trunk/include/llvm/Object/ObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ObjectFile.h?rev=151785&r1=151784&r2=151785&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ObjectFile.h (original)
+++ llvm/trunk/include/llvm/Object/ObjectFile.h Wed Feb 29 19:36:50 2012
@@ -228,6 +228,32 @@
 };
 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.
+class LibraryRef {
+  friend class SectionRef;
+  DataRefImpl LibraryPimpl;
+  const ObjectFile *OwningObject;
+
+public:
+  LibraryRef() : OwningObject(NULL) {
+    std::memset(&LibraryPimpl, 0, sizeof(LibraryPimpl));
+  }
+
+  LibraryRef(DataRefImpl LibraryP, const ObjectFile *Owner);
+
+  bool operator==(const LibraryRef &Other) const;
+  bool operator <(const LibraryRef &Other) const;
+
+  error_code getNext(LibraryRef &Result) const;
+
+  // Get the path to this library, as stored in the object file.
+  error_code getPath(StringRef &Result) const;
+
+  DataRefImpl getRawDataRefImpl() const;
+};
+typedef content_iterator<LibraryRef> library_iterator;
+
 const uint64_t UnknownAddressOrSize = ~0ULL;
 
 /// ObjectFile - This class is the base class for all object file types.
@@ -307,6 +333,11 @@
     return object_error::success;
   }
 
+  // Same for LibraryRef
+  friend class LibraryRef;
+  virtual error_code getLibraryNext(DataRefImpl Lib, LibraryRef &Res) const = 0;
+  virtual error_code getLibraryPath(DataRefImpl Lib, StringRef &Res) const = 0;
+
 public:
 
   virtual symbol_iterator begin_symbols() const = 0;
@@ -318,6 +349,9 @@
   virtual section_iterator begin_sections() const = 0;
   virtual section_iterator end_sections() const = 0;
 
+  virtual library_iterator begin_libraries_needed() const = 0;
+  virtual library_iterator end_libraries_needed() const = 0;
+
   /// @brief The number of bytes used to represent an address in this object
   ///        file format.
   virtual uint8_t getBytesInAddress() const = 0;
@@ -509,6 +543,26 @@
 inline error_code RelocationRef::getHidden(bool &Result) const {
   return OwningObject->getRelocationHidden(RelocationPimpl, Result);
 }
+// Inline function definitions.
+inline LibraryRef::LibraryRef(DataRefImpl LibraryP, const ObjectFile *Owner)
+  : LibraryPimpl(LibraryP)
+  , OwningObject(Owner) {}
+
+inline bool LibraryRef::operator==(const LibraryRef &Other) const {
+  return LibraryPimpl == Other.LibraryPimpl;
+}
+
+inline bool LibraryRef::operator <(const LibraryRef &Other) const {
+  return LibraryPimpl < Other.LibraryPimpl;
+}
+
+inline error_code LibraryRef::getNext(LibraryRef &Result) const {
+  return OwningObject->getLibraryNext(LibraryPimpl, Result);
+}
+
+inline error_code LibraryRef::getPath(StringRef &Result) const {
+  return OwningObject->getLibraryPath(LibraryPimpl, Result);
+}
 
 } // end namespace object
 } // end namespace llvm

Modified: llvm/trunk/lib/Object/COFFObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/COFFObjectFile.cpp?rev=151785&r1=151784&r2=151785&view=diff
==============================================================================
--- llvm/trunk/lib/Object/COFFObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/COFFObjectFile.cpp Wed Feb 29 19:36:50 2012
@@ -515,6 +515,16 @@
   report_fatal_error("Dynamic symbols unimplemented in COFFObjectFile");
 }
 
+library_iterator COFFObjectFile::begin_libraries_needed() const {
+  // TODO: implement
+  report_fatal_error("Libraries needed unimplemented in COFFObjectFile");
+}
+
+library_iterator COFFObjectFile::end_libraries_needed() const {
+  // TODO: implement
+  report_fatal_error("Libraries needed unimplemented in COFFObjectFile");
+}
+
 section_iterator COFFObjectFile::begin_sections() const {
   DataRefImpl ret;
   std::memset(&ret, 0, sizeof(DataRefImpl));
@@ -726,6 +736,16 @@
   return object_error::success;
 }
 
+error_code COFFObjectFile::getLibraryNext(DataRefImpl LibData,
+                                          LibraryRef &Result) const {
+  report_fatal_error("getLibraryNext not implemented in COFFObjectFile");
+}
+
+error_code COFFObjectFile::getLibraryPath(DataRefImpl LibData,
+                                          StringRef &Result) const {
+  report_fatal_error("getLibraryPath not implemented in COFFObjectFile");
+}
+
 namespace llvm {
 
   ObjectFile *ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) {

Modified: llvm/trunk/lib/Object/MachOObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=151785&r1=151784&r2=151785&view=diff
==============================================================================
--- llvm/trunk/lib/Object/MachOObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/MachOObjectFile.cpp Wed Feb 29 19:36:50 2012
@@ -377,6 +377,16 @@
   report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile");
 }
 
+library_iterator MachOObjectFile::begin_libraries_needed() const {
+  // TODO: implement
+  report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
+}
+
+library_iterator MachOObjectFile::end_libraries_needed() const {
+  // TODO: implement
+  report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
+}
+
 /*===-- Sections ----------------------------------------------------------===*/
 
 void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const {
@@ -1175,6 +1185,17 @@
   return object_error::success;
 }
 
+error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData,
+                                           LibraryRef &Res) const {
+  report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
+}
+
+error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
+                                           StringRef &Res) const {
+  report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
+}
+
+
 /*===-- Miscellaneous -----------------------------------------------------===*/
 
 uint8_t MachOObjectFile::getBytesInAddress() const {

Modified: llvm/trunk/test/Object/Inputs/shared-object-test.elf-i386
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/Inputs/shared-object-test.elf-i386?rev=151785&r1=151784&r2=151785&view=diff
==============================================================================
Binary files - no diff available.

Propchange: llvm/trunk/test/Object/Inputs/shared-object-test.elf-i386
------------------------------------------------------------------------------
    svn:mime-type = application/x-object-file

Modified: llvm/trunk/test/Object/Inputs/shared-object-test.elf-x86-64
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/Inputs/shared-object-test.elf-x86-64?rev=151785&r1=151784&r2=151785&view=diff
==============================================================================
Binary files - no diff available.

Propchange: llvm/trunk/test/Object/Inputs/shared-object-test.elf-x86-64
------------------------------------------------------------------------------
    svn:mime-type = application/x-object-file

Modified: llvm/trunk/test/Object/Inputs/shared.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/Inputs/shared.ll?rev=151785&r1=151784&r2=151785&view=diff
==============================================================================
--- llvm/trunk/test/Object/Inputs/shared.ll (original)
+++ llvm/trunk/test/Object/Inputs/shared.ll Wed Feb 29 19:36:50 2012
@@ -1,12 +1,14 @@
 ; How to make the shared objects from this file:
 ;
+; LDARGS="--unresolved-symbols=ignore-all -soname=libfoo.so --no-as-needed -lc -lm"
+;
 ; X86-32 ELF:
 ;   llc -mtriple=i386-linux-gnu shared.ll -filetype=obj -o tmp32.o -relocation-model=pic
-;   ld -melf_i386 -shared tmp32.o -o shared-object-test.elf-i386 --unresolved-symbols=ignore-all
+;   ld -melf_i386 -shared tmp32.o -o shared-object-test.elf-i386 $LDARGS
 ;
 ; X86-64 ELF:
 ;   llc -mtriple=x86_64-linux-gnu shared.ll -filetype=obj -o tmp64.o -relocation-model=pic
-;   ld -melf_x86_64 -shared tmp64.o -o shared-object-test.elf-x86-64 --unresolved-symbols=ignore-all
+;   ld -melf_x86_64 -shared tmp64.o -o shared-object-test.elf-x86-64 $LDARGS
 
 @defined_sym = global i32 1, align 4
 

Added: llvm/trunk/test/Object/readobj-shared-object.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/readobj-shared-object.test?rev=151785&view=auto
==============================================================================
--- llvm/trunk/test/Object/readobj-shared-object.test (added)
+++ llvm/trunk/test/Object/readobj-shared-object.test Wed Feb 29 19:36:50 2012
@@ -0,0 +1,44 @@
+RUN: llvm-readobj %p/Inputs/shared-object-test.elf-i386 \
+RUN:         | FileCheck %s -check-prefix ELF
+RUN: llvm-readobj %p/Inputs/shared-object-test.elf-x86-64 \
+RUN:         | FileCheck %s -check-prefix ELF
+
+ELF:Symbols:
+ELF:  .dynsym                DBG             {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  formatspecific
+ELF:  .dynstr                DBG             {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  formatspecific
+ELF:  .text                  DBG             {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  formatspecific
+ELF:  .eh_frame              DBG             {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  formatspecific
+ELF:  .tdata                 DBG             {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  formatspecific
+ELF:  .dynamic               DBG             {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  formatspecific
+ELF:  .got.plt               DBG             {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  formatspecific
+ELF:  .data                  DBG             {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  formatspecific
+ELF:  .bss                   DBG             {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  formatspecific
+ELF:  shared.ll              FILE            {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  absolute,formatspecific
+ELF:  local_func             FUNC            {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}
+ELF:  _GLOBAL_OFFSET_TABLE_  DATA            {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  absolute
+ELF:  _DYNAMIC               DATA            {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  absolute
+ELF:  common_sym             DATA            {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  global
+ELF:  tls_sym                DATA            {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  global,threadlocal
+ELF:  defined_sym            DATA            {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  global
+ELF:  __bss_start            ?               {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  global,absolute
+ELF:  _end                   ?               {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  global,absolute
+ELF:  global_func            FUNC            {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  global
+ELF:  _edata                 ?               {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  global,absolute
+ELF:  Total: 21
+
+ELF:Dynamic Symbols:
+ELF:  common_sym             DATA            {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  global
+ELF:  tls_sym                DATA            {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  global,threadlocal
+ELF:  defined_sym            DATA            {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  global
+ELF:  __bss_start            ?               {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  global,absolute
+ELF:  _end                   ?               {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  global,absolute
+ELF:  global_func            FUNC            {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  global
+ELF:  _edata                 ?               {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  global,absolute
+ELF:  Total: {{[0-9a-f]+}}
+
+ELF:Libraries needed:
+ELF:  libc.so.6
+ELF:  libm.so.6
+ELF:  Total: 2
+
+

Modified: llvm/trunk/tools/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/CMakeLists.txt?rev=151785&r1=151784&r2=151785&view=diff
==============================================================================
--- llvm/trunk/tools/CMakeLists.txt (original)
+++ llvm/trunk/tools/CMakeLists.txt Wed Feb 29 19:36:50 2012
@@ -37,6 +37,7 @@
 add_subdirectory(llvm-diff)
 add_subdirectory(macho-dump)
 add_subdirectory(llvm-objdump)
+add_subdirectory(llvm-readobj)
 add_subdirectory(llvm-rtdyld)
 add_subdirectory(llvm-dwarfdump)
 

Modified: llvm/trunk/tools/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/Makefile?rev=151785&r1=151784&r2=151785&view=diff
==============================================================================
--- llvm/trunk/tools/Makefile (original)
+++ llvm/trunk/tools/Makefile Wed Feb 29 19:36:50 2012
@@ -32,7 +32,7 @@
                  llvm-ld llvm-prof llvm-link \
                  lli llvm-extract llvm-mc \
                  bugpoint llvm-bcanalyzer llvm-stub \
-                 llvm-diff macho-dump llvm-objdump \
+                 llvm-diff macho-dump llvm-objdump llvm-readobj \
 	         llvm-rtdyld llvm-dwarfdump llvm-cov \
 	         llvm-size llvm-stress
 

Added: llvm/trunk/tools/llvm-readobj/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/CMakeLists.txt?rev=151785&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-readobj/CMakeLists.txt (added)
+++ llvm/trunk/tools/llvm-readobj/CMakeLists.txt Wed Feb 29 19:36:50 2012
@@ -0,0 +1,5 @@
+set(LLVM_LINK_COMPONENTS archive bitreader object)
+
+add_llvm_tool(llvm-readobj
+  llvm-readobj.cpp
+  )

Added: llvm/trunk/tools/llvm-readobj/LLVMBuild.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/LLVMBuild.txt?rev=151785&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-readobj/LLVMBuild.txt (added)
+++ llvm/trunk/tools/llvm-readobj/LLVMBuild.txt Wed Feb 29 19:36:50 2012
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-readobj/LLVMBuild.txt ---------------------------*- Conf -*--===;
+;
+;                     The LLVM Compiler Infrastructure
+;
+; This file is distributed under the University of Illinois Open Source
+; License. See LICENSE.TXT for details.
+;
+;===------------------------------------------------------------------------===;
+;
+; This is an LLVMBuild description file for the components in this subdirectory.
+;
+; For more information on the LLVMBuild system, please see:
+;
+;   http://llvm.org/docs/LLVMBuild.html
+;
+;===------------------------------------------------------------------------===;
+
+[component_0]
+type = Tool
+name = llvm-readobj
+parent = Tools
+required_libraries = Archive BitReader Object

Added: llvm/trunk/tools/llvm-readobj/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/Makefile?rev=151785&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-readobj/Makefile (added)
+++ llvm/trunk/tools/llvm-readobj/Makefile Wed Feb 29 19:36:50 2012
@@ -0,0 +1,18 @@
+##===- tools/llvm-readobj/Makefile -----------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+LEVEL := ../..
+TOOLNAME := llvm-readobj
+LINK_COMPONENTS := archive bitreader object
+
+# This tool has no plugins, optimize startup time.
+TOOL_NO_EXPORTS := 1
+
+include $(LEVEL)/Makefile.common
+

Added: llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp?rev=151785&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp (added)
+++ llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp Wed Feb 29 19:36:50 2012
@@ -0,0 +1,188 @@
+/*===- pso-stub.c - Stub executable to run llvm bitcode files -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/FormattedStream.h"
+
+using namespace llvm;
+using namespace llvm::object;
+
+static cl::opt<std::string>
+InputFilename(cl::Positional, cl::desc("<input object>"), cl::init(""));
+
+void DumpSymbolHeader() {
+  outs() << format("  %-32s", (const char*)"Name")
+         << format("  %-4s", (const char*)"Type")
+         << format("  %-16s", (const char*)"Address")
+         << format("  %-16s", (const char*)"Size")
+         << format("  %-16s", (const char*)"FileOffset")
+         << format("  %-26s", (const char*)"Flags")
+         << "\n";
+}
+
+const char *GetTypeStr(SymbolRef::Type Type) {
+  switch (Type) {
+  case SymbolRef::ST_Unknown: return "?";
+  case SymbolRef::ST_Data: return "DATA";
+  case SymbolRef::ST_Debug: return "DBG";
+  case SymbolRef::ST_File: return "FILE";
+  case SymbolRef::ST_Function: return "FUNC";
+  case SymbolRef::ST_Other: return "-";
+  }
+  return "INV";
+}
+
+std::string GetFlagStr(uint32_t Flags) {
+  std::string result;
+  if (Flags & SymbolRef::SF_Undefined)
+    result += "undef,";
+  if (Flags & SymbolRef::SF_Global)
+    result += "global,";
+  if (Flags & SymbolRef::SF_Weak)
+    result += "weak,";
+  if (Flags & SymbolRef::SF_Absolute)
+    result += "absolute,";
+  if (Flags & SymbolRef::SF_ThreadLocal)
+    result += "threadlocal,";
+  if (Flags & SymbolRef::SF_Common)
+    result += "common,";
+  if (Flags & SymbolRef::SF_FormatSpecific)
+    result += "formatspecific,";
+
+  // Remove trailing comma
+  if (result.size() > 0) {
+    result.erase(result.size() - 1);
+  }
+  return result;
+}
+
+void DumpSymbol(const SymbolRef &sym) {
+    StringRef Name;
+    SymbolRef::Type Type;
+    uint32_t Flags;
+    uint64_t Address;
+    uint64_t Size;
+    uint64_t FileOffset;
+    sym.getName(Name);
+    sym.getAddress(Address);
+    sym.getSize(Size);
+    sym.getFileOffset(FileOffset);
+    sym.getType(Type);
+    sym.getFlags(Flags);
+
+    // format() can't handle StringRefs
+    outs() << format("  %-32s", Name.str().c_str())
+           << format("  %-4s", GetTypeStr(Type))
+           << format("  %16"PRIx64, Address)
+           << format("  %16"PRIx64, Size)
+           << format("  %16"PRIx64, FileOffset)
+           << "  " << GetFlagStr(Flags)
+           << "\n";
+}
+
+
+// Iterate through the normal symbols in the ObjectFile
+void DumpSymbols(const ObjectFile *obj) {
+  error_code ec;
+  uint32_t count = 0;
+  outs() << "Symbols:\n";
+  symbol_iterator it = obj->begin_symbols();
+  symbol_iterator ie = obj->end_symbols();
+  while (it != ie) {
+    DumpSymbol(*it);
+    it.increment(ec);
+    if (ec)
+      report_fatal_error("Symbol iteration failed");
+    ++count;
+  }
+  outs() << "  Total: " << count << "\n\n";
+}
+
+// Iterate through the dynamic symbols in the ObjectFile.
+void DumpDynamicSymbols(const ObjectFile *obj) {
+  error_code ec;
+  uint32_t count = 0;
+  outs() << "Dynamic Symbols:\n";
+  symbol_iterator it = obj->begin_dynamic_symbols();
+  symbol_iterator ie = obj->end_dynamic_symbols();
+  while (it != ie) {
+    DumpSymbol(*it);
+    it.increment(ec);
+    if (ec)
+      report_fatal_error("Symbol iteration failed");
+    ++count;
+  }
+  outs() << "  Total: " << count << "\n\n";
+}
+
+void DumpLibrary(const LibraryRef &lib) {
+  StringRef path;
+  lib.getPath(path);
+  outs() << "  " << path << "\n";
+}
+
+// Iterate through needed libraries
+void DumpLibrariesNeeded(const ObjectFile *obj) {
+  error_code ec;
+  uint32_t count = 0;
+  library_iterator it = obj->begin_libraries_needed();
+  library_iterator ie = obj->end_libraries_needed();
+  outs() << "Libraries needed:\n";
+  while (it != ie) {
+    DumpLibrary(*it);
+    it.increment(ec);
+    if (ec)
+      report_fatal_error("Needed libraries iteration failed");
+    ++count;
+  }
+  outs() << "  Total: " << count << "\n\n";
+}
+
+int main(int argc, char** argv) {
+  error_code ec;
+  sys::PrintStackTraceOnErrorSignal();
+  PrettyStackTraceProgram X(argc, argv);
+
+  cl::ParseCommandLineOptions(argc, argv,
+                              "LLVM Object Reader\n");
+
+  if (InputFilename.empty()) {
+    errs() << "Please specify an input filename\n";
+    return 1;
+  }
+
+  // Open the object file
+  OwningPtr<MemoryBuffer> File;
+  if (MemoryBuffer::getFile(InputFilename, File)) {
+    errs() << InputFilename << ": Open failed\n";
+    return 1;
+  }
+
+  ObjectFile *obj = ObjectFile::createObjectFile(File.take());
+  if (!obj) {
+    errs() << InputFilename << ": Object type not recognized\n";
+  }
+
+  DumpSymbols(obj);
+  DumpDynamicSymbols(obj);
+  DumpLibrariesNeeded(obj);
+  return 0;
+}
+





More information about the llvm-commits mailing list