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
15namespace mcld {
16
17class Archive;
18class ELFObjectReader;
19class Input;
20class LinkerConfig;
21class Module;
22
23/** \class GNUArchiveReader
24 *  \brief GNUArchiveReader reads GNU archive files.
25 */
26class 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