1 //===- GNUArchiveReader.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_GNUARCHIVEREADER_H_
10 #define MCLD_LD_GNUARCHIVEREADER_H_
11 
12 #include "mcld/LD/Archive.h"
13 #include "mcld/LD/ArchiveReader.h"
14 
15 namespace mcld {
16 
17 class Archive;
18 class ELFObjectReader;
19 class Input;
20 class LinkerConfig;
21 class Module;
22 
23 /** \class GNUArchiveReader
24  *  \brief GNUArchiveReader reads GNU archive files.
25  */
26 class GNUArchiveReader : public ArchiveReader {
27  public:
28   GNUArchiveReader(Module& pModule, ELFObjectReader& pELFObjectReader);
29 
30   ~GNUArchiveReader();
31 
32   /// readArchive - read an archive, include the needed members, and build up
33   /// the subtree
34   bool readArchive(const LinkerConfig& pConfig, Archive& pArchive);
35 
36   /// isMyFormat
37   bool isMyFormat(Input& input, bool& pContinue) const;
38 
39  private:
40   /// isArchive
41   bool isArchive(const char* pStr) const;
42 
43   /// isThinArchive
44   bool isThinArchive(const char* pStr) const;
45 
46   /// isThinArchive
47   bool isThinArchive(Input& input) const;
48 
49   /// readMemberHeader - read the header of a member in a archive file and then
50   /// return the corresponding archive member (it may be an input object or
51   /// another archive)
52   /// @param pArchiveRoot  - the archive root that holds the strtab (extended
53   ///                        name table)
54   /// @param pArchiveFile  - the archive that contains the needed object
55   /// @param pFileOffset   - file offset of the member header in the archive
56   /// @param pNestedOffset - used when we find a nested archive
57   /// @param pMemberSize   - the file size of this member
58   Input* readMemberHeader(Archive& pArchiveRoot,
59                           Input& pArchiveFile,
60                           uint32_t pFileOffset,
61                           uint32_t& pNestedOffset,
62                           size_t& pMemberSize);
63 
64   /// readSymbolTable - read the archive symbol map (armap)
65   bool readSymbolTable(Archive& pArchive);
66 
67   /// readStringTable - read the strtab for long file name of the archive
68   bool readStringTable(Archive& pArchive);
69 
70   /// shouldIncludeSymbol - given a sym name from armap and check if we should
71   /// include the corresponding archive member, and then return the decision
72   enum Archive::Symbol::Status shouldIncludeSymbol(
73       const llvm::StringRef& pSymName) const;
74 
75   /// includeMember - include the object member in the given file offset, and
76   /// return the size of the object
77   /// @param pConfig - LinkerConfig
78   /// @param pArchiveRoot - the archive root
79   /// @param pFileOffset  - file offset of the member header in the archive
80   size_t includeMember(const LinkerConfig& pConfig,
81                        Archive& pArchiveRoot,
82                        uint32_t pFileOffset);
83 
84   /// includeAllMembers - include all object members. This is called if
85   /// --whole-archive is the attribute for this archive file.
86   bool includeAllMembers(const LinkerConfig& pConfig, Archive& pArchive);
87 
88  private:
89   Module& m_Module;
90   ELFObjectReader& m_ELFObjectReader;
91 };
92 
93 }  // namespace mcld
94 
95 #endif  // MCLD_LD_GNUARCHIVEREADER_H_
96