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