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_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   {
     57     bool operator()(OFFSET_TYPE X, OFFSET_TYPE Y) const
     58     { return (X == Y); }
     59   };
     60 
     61   struct MurmurHash3
     62   {
     63     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 
    109     Symbol(const char* pName,
    110            uint32_t pOffset,
    111            enum Status pStatus)
    112      : name(pName), fileOffset(pOffset), status(pStatus)
    113     {}
    114 
    115     ~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