1//===- Archive.cpp --------------------------------------------------------===// 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#include <mcld/LD/Archive.h> 10#include <mcld/MC/InputFactory.h> 11#include <llvm/ADT/StringRef.h> 12 13using namespace mcld; 14 15//===----------------------------------------------------------------------===// 16// Archive 17const char Archive::MAGIC[] = "!<arch>\n"; 18const char Archive::THIN_MAGIC[] = "!<thin>\n"; 19const size_t Archive::MAGIC_LEN = sizeof(Archive::MAGIC) - 1; 20const char Archive::SVR4_SYMTAB_NAME[] = "/ "; 21const char Archive::STRTAB_NAME[] = "// "; 22const char Archive::PAD[] = "\n"; 23const char Archive::MEMBER_MAGIC[] = "`\n"; 24 25Archive::Archive(Input& pInputFile, InputFactory& pInputFactory) 26 : m_ArchiveFile(pInputFile), 27 m_pInputTree(NULL), 28 m_SymbolFactory(32) 29{ 30 m_pInputTree = new InputTree(pInputFactory); 31} 32 33Archive::~Archive() 34{ 35 delete m_pInputTree; 36} 37 38/// getARFile - get the Input& of the archive file 39Input& Archive::getARFile() 40{ 41 return m_ArchiveFile; 42} 43 44/// getARFile - get the Input& of the archive file 45const Input& Archive::getARFile() const 46{ 47 return m_ArchiveFile; 48} 49 50/// inputs - get the input tree built from this archive 51InputTree& Archive::inputs() 52{ 53 return *m_pInputTree; 54} 55 56/// inputs - get the input tree built from this archive 57const InputTree& Archive::inputs() const 58{ 59 return *m_pInputTree; 60} 61 62/// getObjectMemberMap - get the map that contains the included object files 63Archive::ObjectMemberMapType& Archive::getObjectMemberMap() 64{ 65 return m_ObjectMemberMap; 66} 67 68/// getObjectMemberMap - get the map that contains the included object files 69const Archive::ObjectMemberMapType& Archive::getObjectMemberMap() const 70{ 71 return m_ObjectMemberMap; 72} 73 74/// numOfObjectMember - return the number of included object files 75size_t Archive::numOfObjectMember() const 76{ 77 return m_ObjectMemberMap.numOfEntries(); 78} 79 80/// addObjectMember - add a object in the object member map 81/// @param pFileOffset - file offset in symtab represents a object file 82/// @param pIter - the iterator in the input tree built from this archive 83bool Archive::addObjectMember(uint32_t pFileOffset, InputTree::iterator pIter) 84{ 85 bool exist; 86 ObjectMemberEntryType* entry = m_ObjectMemberMap.insert(pFileOffset, exist); 87 if (!exist) 88 entry->setValue(pIter); 89 return !exist; 90} 91 92/// hasObjectMember - check if a object file is included or not 93/// @param pFileOffset - file offset in symtab represents a object file 94bool Archive::hasObjectMember(uint32_t pFileOffset) const 95{ 96 return (m_ObjectMemberMap.find(pFileOffset) != m_ObjectMemberMap.end()); 97} 98 99/// getArchiveMemberMap - get the map that contains the included archive files 100Archive::ArchiveMemberMapType& Archive::getArchiveMemberMap() 101{ 102 return m_ArchiveMemberMap; 103} 104 105/// getArchiveMemberMap - get the map that contains the included archive files 106const Archive::ArchiveMemberMapType& Archive::getArchiveMemberMap() const 107{ 108 return m_ArchiveMemberMap; 109} 110 111/// addArchiveMember - add an archive in the archive member map 112/// @param pName - the name of the new archive member 113/// @param pLastPos - this records the point to insert the next node in the 114/// subtree of this archive member 115/// @param pMove - this records the direction to insert the next node in the 116/// subtree of this archive member 117bool Archive::addArchiveMember(const llvm::StringRef& pName, 118 InputTree::iterator pLastPos, 119 InputTree::Mover* pMove) 120{ 121 bool exist; 122 ArchiveMemberEntryType* entry = m_ArchiveMemberMap.insert(pName, exist); 123 if (!exist) { 124 ArchiveMember& ar = entry->value(); 125 ar.file = *pLastPos; 126 ar.lastPos = pLastPos; 127 ar.move = pMove; 128 } 129 return !exist; 130} 131 132/// hasArchiveMember - check if an archive file is included or not 133bool Archive::hasArchiveMember(const llvm::StringRef& pName) const 134{ 135 return (m_ArchiveMemberMap.find(pName) != m_ArchiveMemberMap.end()); 136} 137 138/// getArchiveMember - get a archive member 139Archive::ArchiveMember* Archive::getArchiveMember(const llvm::StringRef& pName) 140{ 141 ArchiveMemberMapType::iterator it = m_ArchiveMemberMap.find(pName); 142 if (it != m_ArchiveMemberMap.end()) 143 return &(it.getEntry()->value()); 144 return NULL; 145} 146 147/// getSymbolTable - get the symtab 148Archive::SymTabType& Archive::getSymbolTable() 149{ 150 return m_SymTab; 151} 152 153/// getSymbolTable - get the symtab 154const Archive::SymTabType& Archive::getSymbolTable() const 155{ 156 return m_SymTab; 157} 158 159/// setSymTabSize - set the memory size of symtab 160void Archive::setSymTabSize(size_t pSize) 161{ 162 m_SymTabSize = pSize; 163} 164 165/// getSymTabSize - get the memory size of symtab 166size_t Archive::getSymTabSize() const 167{ 168 return m_SymTabSize; 169} 170 171/// numOfSymbols - return the number of symbols in symtab 172size_t Archive::numOfSymbols() const 173{ 174 return m_SymTab.size(); 175} 176 177/// addSymbol - add a symtab entry to symtab 178/// @param pName - symbol name 179/// @param pFileOffset - file offset in symtab represents a object file 180void Archive::addSymbol(const char* pName, 181 uint32_t pFileOffset, 182 enum Archive::Symbol::Status pStatus) 183{ 184 Symbol* entry = m_SymbolFactory.allocate(); 185 new (entry) Symbol(pName, pFileOffset, pStatus); 186 m_SymTab.push_back(entry); 187} 188 189/// getSymbolName - get the symbol name with the given index 190const std::string& Archive::getSymbolName(size_t pSymIdx) const 191{ 192 assert(pSymIdx < numOfSymbols()); 193 return m_SymTab[pSymIdx]->name; 194} 195 196/// getObjFileOffset - get the file offset that represent a object file 197uint32_t Archive::getObjFileOffset(size_t pSymIdx) const 198{ 199 assert(pSymIdx < numOfSymbols()); 200 return m_SymTab[pSymIdx]->fileOffset; 201} 202 203/// getSymbolStatus - get the status of a symbol 204enum Archive::Symbol::Status Archive::getSymbolStatus(size_t pSymIdx) const 205{ 206 assert(pSymIdx < numOfSymbols()); 207 return m_SymTab[pSymIdx]->status; 208} 209 210/// setSymbolStatus - set the status of a symbol 211void Archive::setSymbolStatus(size_t pSymIdx, 212 enum Archive::Symbol::Status pStatus) 213{ 214 assert(pSymIdx < numOfSymbols()); 215 m_SymTab[pSymIdx]->status = pStatus; 216} 217 218/// getStrTable - get the extended name table 219std::string& Archive::getStrTable() 220{ 221 return m_StrTab; 222} 223 224/// getStrTable - get the extended name table 225const std::string& Archive::getStrTable() const 226{ 227 return m_StrTab; 228} 229 230