• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
24 namespace mcld {
25 
26 class Input;
27 class InputFactory;
28 class InputBuilder;
29 class AttributeFactory;
30 class ContextFactory;
31 class MemoryAreaFactory;
32 
33 /** \class Archive
34  *  \brief This class define the interfacee to Archive files
35  */
36 class Archive
37 {
38 public:
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 
58 private:
59   template<typename OFFSET_TYPE>
60   struct OffsetCompare
61   {
operatorOffsetCompare62     bool operator()(OFFSET_TYPE X, OFFSET_TYPE Y) const
63     { return (X == Y); }
64   };
65 
66   struct MurmurHash3
67   {
operatorMurmurHash368     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;
82 public:
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 
94 private:
95   typedef HashEntry<const llvm::StringRef,
96                     ArchiveMember,
97                     StringCompare<llvm::StringRef> > ArchiveMemberEntryType;
98 
99 public:
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 
SymbolSymbol114     Symbol(const char* pName,
115            uint32_t pOffset,
116            enum Status pStatus)
117      : name(pName), fileOffset(pOffset), status(pStatus)
118     {}
119 
~SymbolSymbol120     ~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 
131 public:
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 
244 private:
245   typedef GCFactory<Symbol, 0> SymbolFactory;
246 
247 private:
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