[llvm-commits] [llvm] r143561 - in /llvm/trunk: include/llvm/Object/Archive.h lib/Object/Archive.cpp

Michael J. Spencer bigcheesegs at gmail.com
Wed Nov 2 12:33:12 PDT 2011


Author: mspencer
Date: Wed Nov  2 14:33:12 2011
New Revision: 143561

URL: http://llvm.org/viewvc/llvm-project?rev=143561&view=rev
Log:
Object/Archive: Add symbol table iteration.

Modified:
    llvm/trunk/include/llvm/Object/Archive.h
    llvm/trunk/lib/Object/Archive.cpp

Modified: llvm/trunk/include/llvm/Object/Archive.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/Archive.h?rev=143561&r1=143560&r2=143561&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/Archive.h (original)
+++ llvm/trunk/include/llvm/Object/Archive.h Wed Nov  2 14:33:12 2011
@@ -50,6 +50,7 @@
   class child_iterator {
     Child child;
   public:
+    child_iterator() : child(Child(0, StringRef())) {}
     child_iterator(const Child &c) : child(c) {}
     const Child* operator->() const {
       return &child;
@@ -69,11 +70,55 @@
     }
   };
 
+  class Symbol {
+    const Archive *Parent;
+    uint32_t SymbolIndex;
+    uint32_t StringIndex; // Extra index to the string.
+
+  public:
+    bool operator ==(const Symbol &other) const {
+      return (Parent == other.Parent) && (SymbolIndex == other.SymbolIndex);
+    }
+
+    Symbol(const Archive *p, uint32_t symi, uint32_t stri)
+      : Parent(p)
+      , SymbolIndex(symi)
+      , StringIndex(stri) {}
+    error_code getName(StringRef &Result) const;
+    error_code getMember(child_iterator &Result) const;
+    Symbol getNext() const;
+  };
+
+  class symbol_iterator {
+    Symbol symbol;
+  public:
+    symbol_iterator(const Symbol &s) : symbol(s) {}
+    const Symbol *operator->() const {
+      return &symbol;
+    }
+
+    bool operator==(const symbol_iterator &other) const {
+      return symbol == other.symbol;
+    }
+
+    bool operator!=(const symbol_iterator &other) const {
+      return !(*this == other);
+    }
+
+    symbol_iterator& operator++() {  // Preincrement
+      symbol = symbol.getNext();
+      return *this;
+    }
+  };
+
   Archive(MemoryBuffer *source, error_code &ec);
 
   child_iterator begin_children(bool skip_internal = true) const;
   child_iterator end_children() const;
 
+  symbol_iterator begin_symbols() const;
+  symbol_iterator end_symbols() const;
+
   // Cast methods.
   static inline bool classof(Archive const *v) { return true; }
   static inline bool classof(Binary const *v) {
@@ -81,6 +126,7 @@
   }
 
 private:
+  child_iterator SymbolTable;
   child_iterator StringTable;
 };
 

Modified: llvm/trunk/lib/Object/Archive.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/Archive.cpp?rev=143561&r1=143560&r2=143561&view=diff
==============================================================================
--- llvm/trunk/lib/Object/Archive.cpp (original)
+++ llvm/trunk/lib/Object/Archive.cpp Wed Nov  2 14:33:12 2011
@@ -13,6 +13,7 @@
 
 #include "llvm/Object/Archive.h"
 #include "llvm/ADT/APInt.h"
+#include "llvm/Support/Endian.h"
 #include "llvm/Support/MemoryBuffer.h"
 
 using namespace llvm;
@@ -171,8 +172,7 @@
 }
 
 Archive::Archive(MemoryBuffer *source, error_code &ec)
-  : Binary(Binary::isArchive, source)
-  , StringTable(Child(this, StringRef(0, 0))) {
+  : Binary(Binary::isArchive, source) {
   // Check for sufficient magic.
   if (!source || source->getBufferSize()
                  < (8 + sizeof(ArchiveMemberHeader) + 2) // Smallest archive.
@@ -181,15 +181,18 @@
     return;
   }
 
-  // Get the string table. It's the 3rd member.
-  child_iterator StrTable = begin_children(false);
+  // Get the special members.
+  child_iterator i = begin_children(false);
   child_iterator e = end_children();
-  for (int i = 0; StrTable != e && i < 2; ++StrTable, ++i) {}
 
-  // Check to see if there were 3 members, or the 3rd member wasn't named "//".
-  StringRef name;
-  if (StrTable != e && !StrTable->getName(name) && name == "//")
-    StringTable = StrTable;
+  if (i != e) ++i; // Nobody cares about the first member.
+  if (i != e) {
+    SymbolTable = i;
+    ++i;
+  }
+  if (i != e) {
+    StringTable = i;
+  }
 
   ec = object_error::success;
 }
@@ -208,3 +211,62 @@
 Archive::child_iterator Archive::end_children() const {
   return Child(this, StringRef(0, 0));
 }
+
+error_code Archive::Symbol::getName(StringRef &Result) const {
+  Result =
+    StringRef(Parent->SymbolTable->getBuffer()->getBufferStart() + StringIndex);
+  return object_error::success;
+}
+
+error_code Archive::Symbol::getMember(child_iterator &Result) const {
+  const char *buf = Parent->SymbolTable->getBuffer()->getBufferStart();
+  uint32_t member_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
+  const char *offsets = buf + 4;
+  buf += 4 + (member_count * 4); // Skip offsets.
+  uint32_t symbol_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
+  const char *indicies = buf + 4;
+
+  uint16_t offsetindex =
+    *(reinterpret_cast<const support::ulittle16_t*>(indicies)
+      + SymbolIndex);
+
+  uint32_t offset = *(reinterpret_cast<const support::ulittle32_t*>(offsets)
+                      + (offsetindex - 1));
+
+  const char *Loc = Parent->getData().begin() + offset;
+  size_t Size = sizeof(ArchiveMemberHeader) +
+    ToHeader(Loc)->getSize();
+  Result = Child(Parent, StringRef(Loc, Size));
+
+  return object_error::success;
+}
+
+Archive::Symbol Archive::Symbol::getNext() const {
+  Symbol t(*this);
+  const char *buf = Parent->SymbolTable->getBuffer()->getBufferStart();
+  buf += t.StringIndex;
+  while (*buf++); // Go to one past next null.
+  t.StringIndex = buf - Parent->SymbolTable->getBuffer()->getBufferStart();
+  ++t.SymbolIndex;
+  return t;
+}
+
+Archive::symbol_iterator Archive::begin_symbols() const {
+  const char *buf = SymbolTable->getBuffer()->getBufferStart();
+  uint32_t member_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
+  buf += 4 + (member_count * 4); // Skip offsets.
+  uint32_t symbol_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
+  buf += 4 + (symbol_count * 2); // Skip indices.
+  uint32_t string_start_offset =
+    buf - SymbolTable->getBuffer()->getBufferStart();
+  return symbol_iterator(Symbol(this, 0, string_start_offset));
+}
+
+Archive::symbol_iterator Archive::end_symbols() const {
+  const char *buf = SymbolTable->getBuffer()->getBufferStart();
+  uint32_t member_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
+  buf += 4 + (member_count * 4); // Skip offsets.
+  uint32_t symbol_count = *reinterpret_cast<const support::ulittle32_t*>(buf);
+  return symbol_iterator(
+    Symbol(this, symbol_count, 0));
+}





More information about the llvm-commits mailing list