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