• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
13 using namespace mcld;
14 
15 //===----------------------------------------------------------------------===//
16 // Archive
17 const char   Archive::MAGIC[]            = "!<arch>\n";
18 const char   Archive::THIN_MAGIC[]       = "!<thin>\n";
19 const size_t Archive::MAGIC_LEN          = sizeof(Archive::MAGIC) - 1;
20 const char   Archive::SVR4_SYMTAB_NAME[] = "/               ";
21 const char   Archive::STRTAB_NAME[]      = "//              ";
22 const char   Archive::PAD[]              = "\n";
23 const char   Archive::MEMBER_MAGIC[]     = "`\n";
24 
Archive(Input & pInputFile,InputFactory & pInputFactory)25 Archive::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 
~Archive()33 Archive::~Archive()
34 {
35   delete m_pInputTree;
36 }
37 
38 /// getARFile - get the Input& of the archive file
getARFile()39 Input& Archive::getARFile()
40 {
41   return m_ArchiveFile;
42 }
43 
44 /// getARFile - get the Input& of the archive file
getARFile() const45 const Input& Archive::getARFile() const
46 {
47   return m_ArchiveFile;
48 }
49 
50 /// inputs - get the input tree built from this archive
inputs()51 InputTree& Archive::inputs()
52 {
53   return *m_pInputTree;
54 }
55 
56 /// inputs - get the input tree built from this archive
inputs() const57 const InputTree& Archive::inputs() const
58 {
59   return *m_pInputTree;
60 }
61 
62 /// getObjectMemberMap - get the map that contains the included object files
getObjectMemberMap()63 Archive::ObjectMemberMapType& Archive::getObjectMemberMap()
64 {
65   return m_ObjectMemberMap;
66 }
67 
68 /// getObjectMemberMap - get the map that contains the included object files
getObjectMemberMap() const69 const Archive::ObjectMemberMapType& Archive::getObjectMemberMap() const
70 {
71   return m_ObjectMemberMap;
72 }
73 
74 /// numOfObjectMember - return the number of included object files
numOfObjectMember() const75 size_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
addObjectMember(uint32_t pFileOffset,InputTree::iterator pIter)83 bool 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
hasObjectMember(uint32_t pFileOffset) const94 bool 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
getArchiveMemberMap()100 Archive::ArchiveMemberMapType& Archive::getArchiveMemberMap()
101 {
102   return m_ArchiveMemberMap;
103 }
104 
105 /// getArchiveMemberMap - get the map that contains the included archive files
getArchiveMemberMap() const106 const 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
addArchiveMember(const llvm::StringRef & pName,InputTree::iterator pLastPos,InputTree::Mover * pMove)117 bool 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
hasArchiveMember(const llvm::StringRef & pName) const133 bool 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
getArchiveMember(const llvm::StringRef & pName)139 Archive::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
getSymbolTable()148 Archive::SymTabType& Archive::getSymbolTable()
149 {
150   return m_SymTab;
151 }
152 
153 /// getSymbolTable - get the symtab
getSymbolTable() const154 const Archive::SymTabType& Archive::getSymbolTable() const
155 {
156   return m_SymTab;
157 }
158 
159 /// setSymTabSize - set the memory size of symtab
setSymTabSize(size_t pSize)160 void Archive::setSymTabSize(size_t pSize)
161 {
162   m_SymTabSize = pSize;
163 }
164 
165 /// getSymTabSize - get the memory size of symtab
getSymTabSize() const166 size_t Archive::getSymTabSize() const
167 {
168   return m_SymTabSize;
169 }
170 
171 /// numOfSymbols - return the number of symbols in symtab
numOfSymbols() const172 size_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
addSymbol(const char * pName,uint32_t pFileOffset,enum Archive::Symbol::Status pStatus)180 void 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
getSymbolName(size_t pSymIdx) const190 const 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
getObjFileOffset(size_t pSymIdx) const197 uint32_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
getSymbolStatus(size_t pSymIdx) const204 enum 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
setSymbolStatus(size_t pSymIdx,enum Archive::Symbol::Status pStatus)211 void 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
getStrTable()219 std::string& Archive::getStrTable()
220 {
221   return m_StrTab;
222 }
223 
224 /// getStrTable - get the extended name table
getStrTable() const225 const std::string& Archive::getStrTable() const
226 {
227   return m_StrTab;
228 }
229 
230