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