X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FObject%2FArchive.h;h=8dd042a2533fe2916ccf1c6dcc210fa6ab352efe;hb=5c542537c1330e18cce3744b519849e2c0c11fff;hp=af6c995c1d05603b009ebc78f3a86b35083febb7;hpb=0d50598d71c5cc81c0e777a0ddf3e692e634f565;p=oota-llvm.git diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h index af6c995c1d0..8dd042a2533 100644 --- a/include/llvm/Object/Archive.h +++ b/include/llvm/Object/Archive.h @@ -15,6 +15,7 @@ #define LLVM_OBJECT_ARCHIVE_H #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/Object/Binary.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorOr.h" @@ -36,10 +37,13 @@ struct ArchiveMemberHeader { llvm::StringRef getName() const; /// Members are not larger than 4GB. - uint32_t getSize() const; + ErrorOr 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; }; @@ -48,6 +52,7 @@ class Archive : public Binary { virtual void anchor(); public: class Child { + friend Archive; const Archive *Parent; /// \brief Includes header but not padding byte. StringRef Data; @@ -58,67 +63,74 @@ public: return reinterpret_cast(Data.data()); } + bool isThinMember() const; + public: - Child(const Archive *Parent, const char *Start); + Child(const Archive *Parent, const char *Start, std::error_code *EC); + Child(const Archive *Parent, StringRef Data, uint16_t StartOfFile); bool operator ==(const Child &other) const { 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; + const Archive *getParent() const { return Parent; } + ErrorOr getNext() const; 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 Data.size() - StartOfFile; } + ErrorOr getSize() const; + /// \return the size in the archive header for this member. + ErrorOr getRawSize() const; - StringRef getBuffer() const { - return StringRef(Data.data() + StartOfFile, getSize()); - } + ErrorOr getBuffer() const; + uint64_t getChildOffset() const; - ErrorOr> - getMemoryBuffer(bool FullPath = false) const; + ErrorOr getMemoryBufferRef() const; ErrorOr> getAsBinary(LLVMContext *Context = nullptr) const; }; class child_iterator { - Child child; + ErrorOr child; + public: - child_iterator() : child(Child(nullptr, nullptr)) {} + child_iterator() : child(Child(nullptr, nullptr, nullptr)) {} child_iterator(const Child &c) : child(c) {} - const Child* operator->() const { - return &child; - } + child_iterator(std::error_code EC) : child(EC) {} + const ErrorOr *operator->() const { return &child; } + const ErrorOr &operator*() const { return child; } bool operator==(const child_iterator &other) const { - return child == other.child; + // We ignore error states so that comparisions with end() work, which + // allows range loops. + if (child.getError() || other.child.getError()) + return false; + return *child == *other.child; } bool operator!=(const child_iterator &other) const { return !(*this == other); } - bool operator <(const child_iterator &other) const { - return child < other.child; - } - - child_iterator& operator++() { // Preincrement - child = child.getNext(); + // Code in loops with child_iterators must check for errors on each loop + // iteration. And if there is an error break out of the loop. + child_iterator &operator++() { // Preincrement + assert(child && "Can't increment iterator with error"); + child = child->getNext(); return *this; } }; @@ -138,7 +150,7 @@ public: , SymbolIndex(symi) , StringIndex(stri) {} StringRef getName() const; - ErrorOr getMember() const; + ErrorOr getMember() const; Symbol getNext() const; }; @@ -146,9 +158,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; @@ -164,24 +175,30 @@ public: } }; - Archive(std::unique_ptr Source, std::error_code &EC); - static ErrorOr create(std::unique_ptr Source); + Archive(MemoryBufferRef Source, std::error_code &EC); + static ErrorOr> create(MemoryBufferRef Source); enum Kind { K_GNU, + K_MIPS64, K_BSD, K_COFF }; - Kind kind() const { - return Format; - } + Kind kind() const { return (Kind)Format; } + bool isThin() const { return IsThin; } child_iterator child_begin(bool SkipInternal = true) const; child_iterator child_end() const; + iterator_range children(bool SkipInternal = true) const { + return make_range(child_begin(SkipInternal), child_end()); + } symbol_iterator symbol_begin() const; symbol_iterator symbol_end() const; + iterator_range symbols() const { + return make_range(symbol_begin(), symbol_end()); + } // Cast methods. static inline bool classof(Binary const *v) { @@ -192,12 +209,20 @@ public: child_iterator findSym(StringRef name) const; bool hasSymbolTable() const; + StringRef getSymbolTable() const { return SymbolTable; } + uint32_t getNumberOfSymbols() const; private: - child_iterator SymbolTable; - child_iterator StringTable; - child_iterator FirstRegular; - Kind Format; + StringRef SymbolTable; + StringRef StringTable; + + StringRef FirstRegularData; + uint16_t FirstRegularStartOfFile = -1; + void setFirstRegular(const Child &C); + + unsigned Format : 2; + unsigned IsThin : 1; + mutable std::vector> ThinBuffers; }; }