X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FObject%2FArchive.h;h=7c03dcda172ea519bf32d91d1cafe4c3545cb489;hb=4976a53fb76817cc405a7b1a7c18d40c3b7e7e3a;hp=c6b6ed087e87d539f0b6a001395bdfacadad82f8;hpb=a51d7d97b0b8187ed68d4cbad2374f514d2cd168;p=oota-llvm.git diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h index c6b6ed087e8..7c03dcda172 100644 --- a/include/llvm/Object/Archive.h +++ b/include/llvm/Object/Archive.h @@ -14,46 +14,96 @@ #ifndef LLVM_OBJECT_ARCHIVE_H #define LLVM_OBJECT_ARCHIVE_H -#include "llvm/Object/Binary.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/StringRef.h" -#include "llvm/Support/DataTypes.h" +#include "llvm/Object/Binary.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ErrorOr.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/MemoryBuffer.h" namespace llvm { namespace object { +struct ArchiveMemberHeader { + char Name[16]; + char LastModified[12]; + char UID[6]; + char GID[6]; + char AccessMode[8]; + char Size[10]; ///< Size of data, not including header or padding. + char Terminator[2]; + + /// Get the name without looking up long names. + llvm::StringRef getName() const; + + /// Members are not larger than 4GB. + uint32_t getSize() const; + + sys::fs::perms getAccessMode() const; + sys::TimeValue getLastModified() const; + unsigned getUID() const; + unsigned getGID() const; +}; class Archive : public Binary { + virtual void anchor(); public: class Child { - Archive *Parent; + const Archive *Parent; + /// \brief Includes header but not padding byte. StringRef Data; + /// \brief Offset from Data to the start of the file. + uint16_t StartOfFile; + + const ArchiveMemberHeader *getHeader() const { + return reinterpret_cast(Data.data()); + } public: - Child(Archive *p, StringRef d) : Parent(p), Data(d) {} + Child(const Archive *Parent, const char *Start); bool operator ==(const Child &other) const { - return (Parent == other.Parent) && (Data.begin() == other.Data.begin()); + assert(Parent == other.Parent); + return Data.begin() == other.Data.begin(); + } + + bool operator <(const Child &other) const { + return Data.begin() < other.Data.begin(); } Child getNext() const; - error_code getName(StringRef &Result) const; - int getLastModified() const; - int getUID() const; - int getGID() const; - int getAccessMode() const; - ///! Return the size of the archive member without the header or padding. - uint64_t getSize() const; - - MemoryBuffer *getBuffer() const; - error_code getAsBinary(OwningPtr &Result) const; + + ErrorOr getName() const; + StringRef getRawName() const { return getHeader()->getName(); } + sys::TimeValue getLastModified() const { + return getHeader()->getLastModified(); + } + unsigned getUID() const { return getHeader()->getUID(); } + unsigned getGID() const { return getHeader()->getGID(); } + sys::fs::perms getAccessMode() const { + return getHeader()->getAccessMode(); + } + /// \return the size of the archive member without the header or padding. + uint64_t getSize() const { return Data.size() - StartOfFile; } + + StringRef getBuffer() const { + return StringRef(Data.data() + StartOfFile, getSize()); + } + + ErrorOr getMemoryBufferRef() const; + + ErrorOr> + getAsBinary(LLVMContext *Context = nullptr) const; }; class child_iterator { Child child; + public: + child_iterator() : child(Child(nullptr, nullptr)) {} child_iterator(const Child &c) : child(c) {} - const Child* operator->() const { - return &child; - } + const Child *operator->() const { return &child; } + const Child &operator*() const { return child; } bool operator==(const child_iterator &other) const { return child == other.child; @@ -63,25 +113,95 @@ public: return !(*this == other); } - child_iterator& operator++() { // Preincrement + bool operator<(const child_iterator &other) const { + return child < other.child; + } + + child_iterator &operator++() { // Preincrement child = child.getNext(); return *this; } }; - Archive(MemoryBuffer *source, error_code &ec); + 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) {} + StringRef getName() const; + ErrorOr getMember() 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(MemoryBufferRef Source, std::error_code &EC); + static ErrorOr> create(MemoryBufferRef Source); - child_iterator begin_children(); - child_iterator end_children(); + enum Kind { + K_GNU, + K_BSD, + K_COFF + }; + + Kind kind() const { + return Format; + } + + child_iterator child_begin(bool SkipInternal = true) const; + child_iterator child_end() const; + iterator_range children(bool SkipInternal = true) const { + return iterator_range(child_begin(SkipInternal), + child_end()); + } + + symbol_iterator symbol_begin() const; + symbol_iterator symbol_end() const; // Cast methods. - static inline bool classof(Archive const *v) { return true; } static inline bool classof(Binary const *v) { - return v->getType() == Binary::isArchive; + return v->isArchive(); } + // check if a symbol is in the archive + child_iterator findSym(StringRef name) const; + + bool hasSymbolTable() const; + private: + child_iterator SymbolTable; child_iterator StringTable; + child_iterator FirstRegular; + Kind Format; }; }