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