LLVM API Documentation
00001 //===- Archive.h - ar archive file format -----------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file declares the ar archive file format class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_OBJECT_ARCHIVE_H 00015 #define LLVM_OBJECT_ARCHIVE_H 00016 00017 #include "llvm/ADT/StringRef.h" 00018 #include "llvm/Object/Binary.h" 00019 #include "llvm/Support/ErrorHandling.h" 00020 #include "llvm/Support/ErrorOr.h" 00021 #include "llvm/Support/FileSystem.h" 00022 #include "llvm/Support/MemoryBuffer.h" 00023 00024 namespace llvm { 00025 namespace object { 00026 struct ArchiveMemberHeader { 00027 char Name[16]; 00028 char LastModified[12]; 00029 char UID[6]; 00030 char GID[6]; 00031 char AccessMode[8]; 00032 char Size[10]; ///< Size of data, not including header or padding. 00033 char Terminator[2]; 00034 00035 /// Get the name without looking up long names. 00036 llvm::StringRef getName() const; 00037 00038 /// Members are not larger than 4GB. 00039 uint32_t getSize() const; 00040 00041 sys::fs::perms getAccessMode() const; 00042 sys::TimeValue getLastModified() const; 00043 unsigned getUID() const; 00044 unsigned getGID() const; 00045 }; 00046 00047 class Archive : public Binary { 00048 virtual void anchor(); 00049 public: 00050 class Child { 00051 const Archive *Parent; 00052 /// \brief Includes header but not padding byte. 00053 StringRef Data; 00054 /// \brief Offset from Data to the start of the file. 00055 uint16_t StartOfFile; 00056 00057 const ArchiveMemberHeader *getHeader() const { 00058 return reinterpret_cast<const ArchiveMemberHeader *>(Data.data()); 00059 } 00060 00061 public: 00062 Child(const Archive *Parent, const char *Start); 00063 00064 bool operator ==(const Child &other) const { 00065 assert(Parent == other.Parent); 00066 return Data.begin() == other.Data.begin(); 00067 } 00068 00069 bool operator <(const Child &other) const { 00070 return Data.begin() < other.Data.begin(); 00071 } 00072 00073 Child getNext() const; 00074 00075 ErrorOr<StringRef> getName() const; 00076 StringRef getRawName() const { return getHeader()->getName(); } 00077 sys::TimeValue getLastModified() const { 00078 return getHeader()->getLastModified(); 00079 } 00080 unsigned getUID() const { return getHeader()->getUID(); } 00081 unsigned getGID() const { return getHeader()->getGID(); } 00082 sys::fs::perms getAccessMode() const { 00083 return getHeader()->getAccessMode(); 00084 } 00085 /// \return the size of the archive member without the header or padding. 00086 uint64_t getSize() const { return Data.size() - StartOfFile; } 00087 00088 StringRef getBuffer() const { 00089 return StringRef(Data.data() + StartOfFile, getSize()); 00090 } 00091 00092 ErrorOr<MemoryBufferRef> getMemoryBufferRef() const; 00093 00094 ErrorOr<std::unique_ptr<Binary>> 00095 getAsBinary(LLVMContext *Context = nullptr) const; 00096 }; 00097 00098 class child_iterator { 00099 Child child; 00100 public: 00101 child_iterator() : child(Child(nullptr, nullptr)) {} 00102 child_iterator(const Child &c) : child(c) {} 00103 const Child* operator->() const { 00104 return &child; 00105 } 00106 00107 bool operator==(const child_iterator &other) const { 00108 return child == other.child; 00109 } 00110 00111 bool operator!=(const child_iterator &other) const { 00112 return !(*this == other); 00113 } 00114 00115 bool operator <(const child_iterator &other) const { 00116 return child < other.child; 00117 } 00118 00119 child_iterator& operator++() { // Preincrement 00120 child = child.getNext(); 00121 return *this; 00122 } 00123 }; 00124 00125 class Symbol { 00126 const Archive *Parent; 00127 uint32_t SymbolIndex; 00128 uint32_t StringIndex; // Extra index to the string. 00129 00130 public: 00131 bool operator ==(const Symbol &other) const { 00132 return (Parent == other.Parent) && (SymbolIndex == other.SymbolIndex); 00133 } 00134 00135 Symbol(const Archive *p, uint32_t symi, uint32_t stri) 00136 : Parent(p) 00137 , SymbolIndex(symi) 00138 , StringIndex(stri) {} 00139 StringRef getName() const; 00140 ErrorOr<child_iterator> getMember() const; 00141 Symbol getNext() const; 00142 }; 00143 00144 class symbol_iterator { 00145 Symbol symbol; 00146 public: 00147 symbol_iterator(const Symbol &s) : symbol(s) {} 00148 const Symbol *operator->() const { 00149 return &symbol; 00150 } 00151 00152 bool operator==(const symbol_iterator &other) const { 00153 return symbol == other.symbol; 00154 } 00155 00156 bool operator!=(const symbol_iterator &other) const { 00157 return !(*this == other); 00158 } 00159 00160 symbol_iterator& operator++() { // Preincrement 00161 symbol = symbol.getNext(); 00162 return *this; 00163 } 00164 }; 00165 00166 Archive(MemoryBufferRef Source, std::error_code &EC); 00167 static ErrorOr<std::unique_ptr<Archive>> create(MemoryBufferRef Source); 00168 00169 enum Kind { 00170 K_GNU, 00171 K_BSD, 00172 K_COFF 00173 }; 00174 00175 Kind kind() const { 00176 return Format; 00177 } 00178 00179 child_iterator child_begin(bool SkipInternal = true) const; 00180 child_iterator child_end() const; 00181 00182 symbol_iterator symbol_begin() const; 00183 symbol_iterator symbol_end() const; 00184 00185 // Cast methods. 00186 static inline bool classof(Binary const *v) { 00187 return v->isArchive(); 00188 } 00189 00190 // check if a symbol is in the archive 00191 child_iterator findSym(StringRef name) const; 00192 00193 bool hasSymbolTable() const; 00194 00195 private: 00196 child_iterator SymbolTable; 00197 child_iterator StringTable; 00198 child_iterator FirstRegular; 00199 Kind Format; 00200 }; 00201 00202 } 00203 } 00204 00205 #endif