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