X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=include%2Fllvm%2FObject%2FArchive.h;h=8da6919a46555cf515e8ab379c87f2bf47fcf9a1;hp=b12b17e1f5b5e4b30867cc09277261a2a72f41ac;hb=cd52a7a381a73c53ec4ef517ad87f19808cb1a28;hpb=c8a55a660e93bb7a4854969b4c5814bf7bb0101b diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h index b12b17e1f5b..8da6919a465 100644 --- a/include/llvm/Object/Archive.h +++ b/include/llvm/Object/Archive.h @@ -14,47 +14,105 @@ #ifndef LLVM_OBJECT_ARCHIVE_H #define LLVM_OBJECT_ARCHIVE_H -#include "llvm/Object/Binary.h" #include "llvm/ADT/StringRef.h" -#include "llvm/Support/DataTypes.h" +#include "llvm/ADT/iterator_range.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; + llvm::StringRef getRawLastModified() const { + return StringRef(LastModified, sizeof(LastModified)).rtrim(" "); + } + unsigned getUID() const; + unsigned getGID() const; +}; class Archive : public Binary { + virtual void anchor(); public: class Child { 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(const 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. + + ErrorOr getName() const; + StringRef getRawName() const { return getHeader()->getName(); } + sys::TimeValue getLastModified() const { + return getHeader()->getLastModified(); + } + StringRef getRawLastModified() const { + return getHeader()->getRawLastModified(); + } + 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 the size in the archive header for this member. + uint64_t getRawSize() const; + + StringRef getBuffer() const { + return StringRef(Data.data() + StartOfFile, getSize()); + } + uint64_t getChildOffset() const; - MemoryBuffer *getBuffer() const; - error_code getAsBinary(OwningPtr &Result) const; + ErrorOr getMemoryBufferRef() const; + + ErrorOr> + getAsBinary(LLVMContext *Context = nullptr) const; }; class child_iterator { Child child; + public: - child_iterator() : child(Child(0, StringRef())) {} + 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; @@ -64,7 +122,11 @@ 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; } @@ -84,8 +146,8 @@ public: : Parent(p) , SymbolIndex(symi) , StringIndex(stri) {} - error_code getName(StringRef &Result) const; - error_code getMember(child_iterator &Result) const; + StringRef getName() const; + ErrorOr getMember() const; Symbol getNext() const; }; @@ -93,9 +155,8 @@ public: Symbol symbol; public: symbol_iterator(const Symbol &s) : symbol(s) {} - const Symbol *operator->() const { - return &symbol; - } + const Symbol *operator->() const { return &symbol; } + const Symbol &operator*() const { return symbol; } bool operator==(const symbol_iterator &other) const { return symbol == other.symbol; @@ -111,23 +172,49 @@ public: } }; - Archive(MemoryBuffer *source, error_code &ec); + Archive(MemoryBufferRef Source, std::error_code &EC); + static ErrorOr> create(MemoryBufferRef Source); - child_iterator begin_children(bool skip_internal = true) const; - child_iterator end_children() const; + enum Kind { + K_GNU, + K_MIPS64, + K_BSD, + K_COFF + }; - symbol_iterator begin_symbols() const; - symbol_iterator end_symbols() const; + Kind kind() const { return (Kind)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; + iterator_range symbols() const { + return iterator_range(symbol_begin(), symbol_end()); + } // 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; + child_iterator getSymbolTableChild() const { return SymbolTable; } + uint32_t getNumberOfSymbols() const; + private: child_iterator SymbolTable; child_iterator StringTable; + child_iterator FirstRegular; + unsigned Format : 2; + unsigned IsThin : 1; }; }