Home | History | Annotate | Download | only in LD
      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   {
     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;
     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                     hash::StringCompare<llvm::StringRef> > ArchiveMemberEntryType;
     98 
     99 public:
    100   typedef HashTable<ArchiveMemberEntryType,
    101                     hash::StringHash<hash::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 
    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