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