1 //===- Archive.h ----------------------------------------------------------===// 2 // 3 // The MCLinker Project 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 #ifndef MCLD_ARCHIVE_H 10 #define MCLD_ARCHIVE_H 11 #ifdef ENABLE_UNITTEST 12 #include <gtest.h> 13 #endif 14 15 #include <mcld/InputTree.h> 16 #include <mcld/ADT/HashEntry.h> 17 #include <mcld/ADT/HashTable.h> 18 #include <mcld/ADT/StringHash.h> 19 #include <mcld/Support/GCFactory.h> 20 21 #include <vector> 22 #include <string> 23 24 namespace mcld { 25 26 class Input; 27 class InputFactory; 28 class InputBuilder; 29 class AttributeFactory; 30 class ContextFactory; 31 class MemoryAreaFactory; 32 33 /** \class Archive 34 * \brief This class define the interfacee to Archive files 35 */ 36 class Archive 37 { 38 public: 39 static const char MAGIC[]; ///< magic string 40 static const char THIN_MAGIC[]; ///< magic of thin archive 41 static const size_t MAGIC_LEN; ///< length of magic string 42 static const char SVR4_SYMTAB_NAME[]; ///< SVR4 symtab entry name 43 static const char STRTAB_NAME[]; ///< Name of string table 44 static const char PAD[]; ///< inter-file align padding 45 static const char MEMBER_MAGIC[]; ///< fmag field magic # 46 47 struct MemberHeader 48 { 49 char name[16]; ///< Name of the file member. 50 char date[12]; ///< File date, decimal seconds since Epoch 51 char uid[6]; ///< user id in ASCII decimal 52 char gid[6]; ///< group id in ASCII decimal 53 char mode[8]; ///< file mode in ASCII octal 54 char size[10]; ///< file size in ASCII decimal 55 char fmag[2]; ///< Always contains ARFILE_MAGIC_TERMINATOR 56 }; 57 58 private: 59 template<typename OFFSET_TYPE> 60 struct OffsetCompare 61 { 62 bool operator()(OFFSET_TYPE X, OFFSET_TYPE Y) const 63 { return (X == Y); } 64 }; 65 66 struct MurmurHash3 67 { 68 size_t operator()(uint32_t pKey) const 69 { 70 pKey ^= pKey >> 16; 71 pKey *= 0x85ebca6b; 72 pKey ^= pKey >> 13; 73 pKey *= 0xc2b2ae35; 74 pKey ^= pKey >> 16; 75 return pKey; 76 } 77 }; 78 79 typedef HashEntry<uint32_t, 80 InputTree::iterator, 81 OffsetCompare<uint32_t> > ObjectMemberEntryType; 82 public: 83 typedef HashTable<ObjectMemberEntryType, 84 MurmurHash3, 85 EntryFactory<ObjectMemberEntryType> > ObjectMemberMapType; 86 87 struct ArchiveMember 88 { 89 Input* file; 90 InputTree::iterator lastPos; 91 InputTree::Mover* move; 92 }; 93 94 private: 95 typedef HashEntry<const llvm::StringRef, 96 ArchiveMember, 97 StringCompare<llvm::StringRef> > ArchiveMemberEntryType; 98 99 public: 100 typedef HashTable<ArchiveMemberEntryType, 101 StringHash<ELF>, 102 EntryFactory<ArchiveMemberEntryType> > ArchiveMemberMapType; 103 104 struct Symbol 105 { 106 public: 107 enum Status 108 { 109 Include, 110 Exclude, 111 Unknown 112 }; 113 114 Symbol(const char* pName, 115 uint32_t pOffset, 116 enum Status pStatus) 117 : name(pName), fileOffset(pOffset), status(pStatus) 118 {} 119 120 ~Symbol() 121 {} 122 123 public: 124 std::string name; 125 uint32_t fileOffset; 126 enum Status status; 127 }; 128 129 typedef std::vector<Symbol*> SymTabType; 130 131 public: 132 Archive(Input& pInputFile, InputBuilder& pBuilder); 133 134 ~Archive(); 135 136 /// getARFile - get the Input& of the archive file 137 Input& getARFile(); 138 139 /// getARFile - get the Input& of the archive file 140 const Input& getARFile() const; 141 142 /// inputs - get the input tree built from this archive 143 InputTree& inputs(); 144 145 /// inputs - get the input tree built from this archive 146 const InputTree& inputs() const; 147 148 /// getObjectMemberMap - get the map that contains the included object files 149 ObjectMemberMapType& getObjectMemberMap(); 150 151 /// getObjectMemberMap - get the map that contains the included object files 152 const ObjectMemberMapType& getObjectMemberMap() const; 153 154 /// numOfObjectMember - return the number of included object files 155 size_t numOfObjectMember() const; 156 157 /// addObjectMember - add a object in the object member map 158 /// @param pFileOffset - file offset in symtab represents a object file 159 /// @param pIter - the iterator in the input tree built from this archive 160 bool addObjectMember(uint32_t pFileOffset, InputTree::iterator pIter); 161 162 /// hasObjectMember - check if a object file is included or not 163 /// @param pFileOffset - file offset in symtab represents a object file 164 bool hasObjectMember(uint32_t pFileOffset) const; 165 166 /// getArchiveMemberMap - get the map that contains the included archive files 167 ArchiveMemberMapType& getArchiveMemberMap(); 168 169 /// getArchiveMemberMap - get the map that contains the included archive files 170 const ArchiveMemberMapType& getArchiveMemberMap() const; 171 172 /// addArchiveMember - add an archive in the archive member map 173 /// @param pName - the name of the new archive member 174 /// @param pLastPos - this records the point to insert the next node in the 175 /// subtree of this archive member 176 /// @param pMove - this records the direction to insert the next node in 177 /// the subtree of this archive member 178 bool addArchiveMember(const llvm::StringRef& pName, 179 InputTree::iterator pLastPos, 180 InputTree::Mover* pMove); 181 182 /// hasArchiveMember - check if an archive file is included or not 183 bool hasArchiveMember(const llvm::StringRef& pName) const; 184 185 /// getArchiveMember - get a archive member 186 ArchiveMember* getArchiveMember(const llvm::StringRef& pName); 187 188 /// getSymbolTable - get the symtab 189 SymTabType& getSymbolTable(); 190 191 /// getSymbolTable - get the symtab 192 const SymTabType& getSymbolTable() const; 193 194 /// setSymTabSize - set the memory size of symtab 195 void setSymTabSize(size_t pSize); 196 197 /// getSymTabSize - get the memory size of symtab 198 size_t getSymTabSize() const; 199 200 /// numOfSymbols - return the number of symbols in symtab 201 size_t numOfSymbols() const; 202 203 /// addSymbol - add a symtab entry to symtab 204 /// @param pName - symbol name 205 /// @param pFileOffset - file offset in symtab represents a object file 206 void 207 addSymbol(const char* pName, 208 uint32_t pFileOffset, 209 enum Symbol::Status pStatus = Archive::Symbol::Unknown); 210 211 /// getSymbolName - get the symbol name with the given index 212 const std::string& getSymbolName(size_t pSymIdx) const; 213 214 /// getObjFileOffset - get the file offset that represent a object file 215 uint32_t getObjFileOffset(size_t pSymIdx) const; 216 217 /// getSymbolStatus - get the status of a symbol 218 enum Symbol::Status getSymbolStatus(size_t pSymIdx) const; 219 220 /// setSymbolStatus - set the status of a symbol 221 void setSymbolStatus(size_t pSymIdx, enum Symbol::Status pStatus); 222 223 /// getStrTable - get the extended name table 224 std::string& getStrTable(); 225 226 /// getStrTable - get the extended name table 227 const std::string& getStrTable() const; 228 229 /// hasStrTable - return true if this archive has extended name table 230 bool hasStrTable() const; 231 232 /// getMemberFile - get the member file in an archive member 233 /// @param pArchiveFile - Input reference of the archive member 234 /// @param pIsThinAR - denote the archive menber is a Thin Archive or not 235 /// @param pName - the name of the member file we want to get 236 /// @param pPath - the path of the member file 237 /// @param pFileOffset - the file offset of the member file in a regular AR 238 Input* getMemberFile(Input& pArchiveFile, 239 bool isThinAR, 240 const std::string& pName, 241 const sys::fs::Path& pPath, 242 off_t pFileOffset = 0); 243 244 private: 245 typedef GCFactory<Symbol, 0> SymbolFactory; 246 247 private: 248 Input& m_ArchiveFile; 249 InputTree *m_pInputTree; 250 ObjectMemberMapType m_ObjectMemberMap; 251 ArchiveMemberMapType m_ArchiveMemberMap; 252 SymbolFactory m_SymbolFactory; 253 SymTabType m_SymTab; 254 size_t m_SymTabSize; 255 std::string m_StrTab; 256 InputBuilder& m_Builder; 257 }; 258 259 } // namespace of mcld 260 261 #endif 262 263