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