macho-dump: Add support for dumping symbol table entries.
authorDaniel Dunbar <daniel@zuster.org>
Sat, 27 Nov 2010 13:52:53 +0000 (13:52 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Sat, 27 Nov 2010 13:52:53 +0000 (13:52 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120218 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Object/MachOFormat.h
include/llvm/Object/MachOObject.h
lib/Object/MachOObject.cpp
tools/macho-dump/macho-dump.cpp

index 0a2cceccb8302d4c0daddae154a14cb7c7dc52b3..28bb40fba97135021c9a47e0f97259b0be726962 100644 (file)
@@ -250,6 +250,25 @@ namespace macho {
     uint32_t Reserved3;
   };
 
+  /// @}
+  /// @name Symbol Table Entries
+  /// @{
+
+  struct SymbolTableEntry {
+    uint32_t StringIndex;
+    uint8_t Type;
+    uint8_t SectionIndex;
+    uint16_t Flags;
+    uint32_t Value;
+  };
+  struct Symbol64TableEntry {
+    uint32_t StringIndex;
+    uint8_t Type;
+    uint8_t SectionIndex;
+    uint16_t Flags;
+    uint64_t Value;
+  };
+
   /// @}
   /// @name Indirect Symbol Table
   /// @{
index 836e5491d21b93f02bb2f0d0fb2695d0cf96a1d2..6c0a1d0cad0f98747d1f482e277fd3c73edd1e8c 100644 (file)
@@ -111,6 +111,11 @@ public:
     return StringTable;
   }
 
+  StringRef getStringAtIndex(unsigned Index) const {
+    size_t End = getStringTableData().find('\0', Index);
+    return getStringTableData().slice(Index, End);
+  }
+
   void RegisterStringTable(macho::SymtabLoadCommand &SLC);
 
   /// @}
@@ -157,6 +162,12 @@ public:
   void ReadRelocationEntry(
     uint64_t RelocationTableOffset, unsigned Index,
     InMemoryStruct<macho::RelocationEntry> &Res) const;
+  void ReadSymbolTableEntry(
+    uint64_t SymbolTableOffset, unsigned Index,
+    InMemoryStruct<macho::SymbolTableEntry> &Res) const;
+  void ReadSymbol64TableEntry(
+    uint64_t SymbolTableOffset, unsigned Index,
+    InMemoryStruct<macho::Symbol64TableEntry> &Res) const;
 
   /// @}
 };
index 45c9bff45fcc3afd9a8bc1f00e7ef9071623de0d..33890f6617a6d75c25ddf5ffe3377ba1a830108b 100644 (file)
@@ -308,3 +308,31 @@ void MachOObject::ReadRelocationEntry(uint64_t RelocationTableOffset,
                      Index * sizeof(macho::RelocationEntry));
   ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
 }
+
+template<>
+void SwapStruct(macho::SymbolTableEntry &Value) {
+  SwapValue(Value.StringIndex);
+  SwapValue(Value.Flags);
+  SwapValue(Value.Value);
+}
+void MachOObject::ReadSymbolTableEntry(uint64_t SymbolTableOffset,
+                                       unsigned Index,
+                           InMemoryStruct<macho::SymbolTableEntry> &Res) const {
+  uint64_t Offset = (SymbolTableOffset +
+                     Index * sizeof(macho::SymbolTableEntry));
+  ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
+}
+
+template<>
+void SwapStruct(macho::Symbol64TableEntry &Value) {
+  SwapValue(Value.StringIndex);
+  SwapValue(Value.Flags);
+  SwapValue(Value.Value);
+}
+void MachOObject::ReadSymbol64TableEntry(uint64_t SymbolTableOffset,
+                                       unsigned Index,
+                         InMemoryStruct<macho::Symbol64TableEntry> &Res) const {
+  uint64_t Offset = (SymbolTableOffset +
+                     Index * sizeof(macho::Symbol64TableEntry));
+  ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
+}
index e2a8ef136ec7da8b08e7ad5af7fd5755ae157f2f..abe06f4f4dc639f734b82909b2cc803c18ad9376 100644 (file)
@@ -201,6 +201,20 @@ static int DumpSegment64Command(MachOObject &Obj,
   return 0;
 }
 
+static void DumpSymbolTableEntryData(MachOObject &Obj,
+                                     unsigned Index, uint32_t StringIndex,
+                                     uint8_t Type, uint8_t SectionIndex,
+                                     uint16_t Flags, uint64_t Value) {
+  outs() << "    # Symbol " << Index << "\n";
+  outs() << "   (('n_strx', " << StringIndex << ")\n";
+  outs() << "    ('n_type', " << format("%#x", Type) << ")\n";
+  outs() << "    ('n_sect', " << uint32_t(SectionIndex) << ")\n";
+  outs() << "    ('n_desc', " << Flags << ")\n";
+  outs() << "    ('n_value', " << Value << ")\n";
+  outs() << "    ('_string', '" << Obj.getStringAtIndex(StringIndex) << "')\n";
+  outs() << "   ),\n";
+}
+
 static int DumpSymtabCommand(MachOObject &Obj,
                              const MachOObject::LoadCommandInfo &LCI) {
   InMemoryStruct<macho::SymtabLoadCommand> SLC;
@@ -221,7 +235,35 @@ static int DumpSymtabCommand(MachOObject &Obj,
   outs().write_escaped(Obj.getStringTableData(),
                        /*UseHexEscapes=*/true) << "')\n";
 
-  return 0;
+  // Dump the symbol table.
+  int Res = 0;
+  outs() << "  ('_symbols', [\n";
+  for (unsigned i = 0; i != SLC->NumSymbolTableEntries; ++i) {
+    if (Obj.is64Bit()) {
+      InMemoryStruct<macho::Symbol64TableEntry> STE;
+      Obj.ReadSymbol64TableEntry(SLC->SymbolTableOffset, i, STE);
+      if (!STE) {
+        Res = Error("unable to read symbol: '" + Twine(i) + "'");
+        break;
+      }
+
+      DumpSymbolTableEntryData(Obj, i, STE->StringIndex, STE->Type,
+                               STE->SectionIndex, STE->Flags, STE->Value);
+    } else {
+      InMemoryStruct<macho::SymbolTableEntry> STE;
+      Obj.ReadSymbolTableEntry(SLC->SymbolTableOffset, i, STE);
+      if (!SLC) {
+        Res = Error("unable to read symbol: '" + Twine(i) + "'");
+        break;
+      }
+
+      DumpSymbolTableEntryData(Obj, i, STE->StringIndex, STE->Type,
+                               STE->SectionIndex, STE->Flags, STE->Value);
+    }
+  }
+  outs() << "  ])\n";
+
+  return Res;
 }
 
 static int DumpDysymtabCommand(MachOObject &Obj,