[Object]
authorDavid Meyer <pdox@google.com>
Thu, 1 Mar 2012 22:19:54 +0000 (22:19 +0000)
committerDavid Meyer <pdox@google.com>
Thu, 1 Mar 2012 22:19:54 +0000 (22:19 +0000)
Add ObjectFile::getLoadName() for retrieving the soname/installname of a shared object.

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

include/llvm/Object/COFF.h
include/llvm/Object/ELF.h
include/llvm/Object/MachO.h
include/llvm/Object/ObjectFile.h
lib/Object/COFFObjectFile.cpp
lib/Object/MachOObjectFile.cpp
test/Object/readobj-shared-object.test
tools/llvm-readobj/llvm-readobj.cpp

index 6212785e3f2f1db7d2c7aa35afcd53face3d79eb..4f90187895722a7d574443985c80a40fbf4cb19f 100644 (file)
@@ -164,6 +164,7 @@ public:
   virtual uint8_t getBytesInAddress() const;
   virtual StringRef getFileFormatName() const;
   virtual unsigned getArch() const;
+  virtual StringRef getLoadName() const;
 
   error_code getHeader(const coff_file_header *&Res) const;
   error_code getSection(int32_t index, const coff_section *&Res) const;
index ce002f2e4e329ddbe4f56fc7eaa6d81501bc2f1f..e746b0aaa55d2edb12a232dbd883b69fbe878756 100644 (file)
@@ -369,6 +369,9 @@ private:
   DenseMap<const Elf_Sym*, ELF::Elf64_Word> ExtendedSymbolTable;
 
   const Elf_Shdr *dot_dynamic_sec; // .dynamic
+  // Pointer to SONAME entry in dynamic string table
+  // This is set the first time getLoadName is called.
+  mutable const char *dt_soname;
 
   /// @brief Map sections to an array of relocation sections that reference
   ///        them sorted by section index.
@@ -471,6 +474,7 @@ public:
   virtual uint8_t getBytesInAddress() const;
   virtual StringRef getFileFormatName() const;
   virtual unsigned getArch() const;
+  virtual StringRef getLoadName() const;
 
   uint64_t getNumSections() const;
   uint64_t getStringTableIndex() const;
@@ -1259,7 +1263,8 @@ ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object
   , dot_shstrtab_sec(0)
   , dot_strtab_sec(0)
   , dot_dynstr_sec(0)
-  , dot_dynamic_sec(0) {
+  , dot_dynamic_sec(0)
+  , dt_soname(0) {
 
   const uint64_t FileSize = Data->getBufferSize();
 
@@ -1485,6 +1490,32 @@ error_code ELFObjectFile<target_endianness, is64Bits>
   return object_error::success;
 }
 
+template<support::endianness target_endianness, bool is64Bits>
+StringRef
+ELFObjectFile<target_endianness, is64Bits>::getLoadName() const {
+  if (!dt_soname) {
+    // Find the DT_SONAME entry
+    dyn_iterator it = begin_dynamic_table();
+    dyn_iterator ie = end_dynamic_table();
+    error_code ec;
+    while (it != ie) {
+      if (it->getTag() == ELF::DT_SONAME)
+        break;
+      it.increment(ec);
+      if (ec)
+        report_fatal_error("dynamic table iteration failed");
+    }
+    if (it != ie) {
+      if (dot_dynstr_sec == NULL)
+        report_fatal_error("Dynamic string table is missing");
+      dt_soname = getString(dot_dynstr_sec, it->getVal());
+    } else {
+      dt_soname = "";
+    }
+  }
+  return dt_soname;
+}
+
 template<support::endianness target_endianness, bool is64Bits>
 library_iterator ELFObjectFile<target_endianness, is64Bits>
                              ::begin_libraries_needed() const {
index 185df06a996cd6cee88cf6abbb4f18e37488b90b..1aae85ab36c3c659252586e680d089638fbad6da 100644 (file)
@@ -42,6 +42,7 @@ public:
   virtual uint8_t getBytesInAddress() const;
   virtual StringRef getFileFormatName() const;
   virtual unsigned getArch() const;
+  virtual StringRef getLoadName() const;
 
   MachOObject *getObject() { return MachOObj; }
 
index dd47ceb7479582150099ec5f5e013cd57acde2db..1e9d89549d631d4727eb5a41a5ef66ef06022550 100644 (file)
@@ -359,6 +359,11 @@ public:
   virtual StringRef getFileFormatName() const = 0;
   virtual /* Triple::ArchType */ unsigned getArch() const = 0;
 
+  /// For shared objects, returns the name which this object should be
+  /// loaded from at runtime. This corresponds to DT_SONAME on ELF and
+  /// LC_ID_DYLIB (install name) on MachO.
+  virtual StringRef getLoadName() const = 0;
+
   /// @returns Pointer to ObjectFile subclass to handle this type of object.
   /// @param ObjectPath The path to the object file. ObjectPath.isObject must
   ///        return true.
index 393c574d5324b19ac688bcf7cc030cc1081c0d7e..a3fdd5bb6a7eb6630fa2944de8ee087a39f48729 100644 (file)
@@ -525,6 +525,12 @@ library_iterator COFFObjectFile::end_libraries_needed() const {
   report_fatal_error("Libraries needed unimplemented in COFFObjectFile");
 }
 
+StringRef COFFObjectFile::getLoadName() const {
+  // COFF does not have this field.
+  return "";
+}
+
+
 section_iterator COFFObjectFile::begin_sections() const {
   DataRefImpl ret;
   std::memset(&ret, 0, sizeof(DataRefImpl));
index 360ab1676c46558b9733ad217b217f44c907344a..655c40aeda563374330c97937c29eddfc0056056 100644 (file)
@@ -387,6 +387,11 @@ library_iterator MachOObjectFile::end_libraries_needed() const {
   report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
 }
 
+StringRef MachOObjectFile::getLoadName() const {
+  // TODO: Implement
+  report_fatal_error("get_load_name() unimplemented in MachOObjectFile");
+}
+
 /*===-- Sections ----------------------------------------------------------===*/
 
 void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const {
index be71907c23b3b9d460c1176bf4833d07fdb31ece..3b5457ce073725a3d37ea3b31d58c734c2a94756 100644 (file)
@@ -1,7 +1,22 @@
 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-i386 \
+RUN:         | FileCheck %s -check-prefix ELF32
+
 RUN: llvm-readobj %p/Inputs/shared-object-test.elf-x86-64 \
 RUN:         | FileCheck %s -check-prefix ELF
+RUN: llvm-readobj %p/Inputs/shared-object-test.elf-x86-64 \
+RUN:         | FileCheck %s -check-prefix ELF64
+
+ELF64:File Format : ELF64-x86-64
+ELF64:Arch        : x86_64
+ELF64:Address Size: 64 bits
+ELF64:Load Name   : libfoo.so
+
+ELF32:File Format : ELF32-i386
+ELF32:Arch        : i386
+ELF32:Address Size: 32 bits
+ELF32:Load Name   : libfoo.so
 
 ELF:Symbols:
 ELF:  .dynsym                DBG             {{[0-9a-f]+}}  {{[0-9a-f]+}}  {{[0-9a-f]+}}  formatspecific
index 7b8683f134b8c7ca80cdfd220fc8a0baadf61a6c..215039f5be762f87c615132545ca730f5cad95d2 100644 (file)
@@ -14,6 +14,7 @@
 #include <string.h>
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Analysis/Verifier.h"
+#include "llvm/ADT/Triple.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/PrettyStackTrace.h"
@@ -155,6 +156,16 @@ void DumpLibrariesNeeded(const ObjectFile *obj) {
   outs() << "  Total: " << count << "\n\n";
 }
 
+void DumpHeaders(const ObjectFile *obj) {
+  outs() << "File Format : " << obj->getFileFormatName() << "\n";
+  outs() << "Arch        : "
+         << Triple::getArchTypeName((llvm::Triple::ArchType)obj->getArch())
+         << "\n";
+  outs() << "Address Size: " << (8*obj->getBytesInAddress()) << " bits\n";
+  outs() << "Load Name   : " << obj->getLoadName() << "\n";
+  outs() << "\n";
+}
+
 int main(int argc, char** argv) {
   error_code ec;
   sys::PrintStackTraceOnErrorSignal();
@@ -180,6 +191,7 @@ int main(int argc, char** argv) {
     errs() << InputFilename << ": Object type not recognized\n";
   }
 
+  DumpHeaders(obj);
   DumpSymbols(obj);
   DumpDynamicSymbols(obj);
   DumpLibrariesNeeded(obj);