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