ScriptFile.h revision 87f34658dec9097d987d254a990ea7f311bfc95f
1//===- ScriptFile.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_SCRIPT_SCRIPTFILE_H
10#define MCLD_SCRIPT_SCRIPTFILE_H
11#ifdef ENABLE_UNITTEST
12#include <gtest.h>
13#endif
14
15#include <mcld/Script/Assignment.h>
16#include <mcld/Script/OutputSectDesc.h>
17#include <mcld/Script/InputSectDesc.h>
18#include <vector>
19#include <string>
20
21namespace mcld
22{
23
24class ScriptCommand;
25class Input;
26class InputTree;
27class InputBuilder;
28class GroupReader;
29class LinkerConfig;
30class RpnExpr;
31class StringList;
32class Module;
33
34/** \class ScriptFile
35 *  \brief This class defines the interfaces to a linker script file.
36 */
37
38class ScriptFile
39{
40public:
41  enum Kind {
42    LDScript,      // -T
43    Expression,    // --defsym
44    VersionScript, // --version-script
45    DynamicList,   // --dynamic-list
46    Unknown
47  };
48
49  typedef std::vector<ScriptCommand*> CommandQueue;
50  typedef CommandQueue::const_iterator const_iterator;
51  typedef CommandQueue::iterator iterator;
52  typedef CommandQueue::const_reference const_reference;
53  typedef CommandQueue::reference reference;
54
55public:
56  ScriptFile(Kind pKind, Input& pInput, InputBuilder& pBuilder);
57  ~ScriptFile();
58
59  const_iterator  begin() const { return m_CommandQueue.begin(); }
60  iterator        begin()       { return m_CommandQueue.begin(); }
61  const_iterator  end()   const { return m_CommandQueue.end(); }
62  iterator        end()         { return m_CommandQueue.end(); }
63
64  const_reference front() const { return m_CommandQueue.front(); }
65  reference       front()       { return m_CommandQueue.front(); }
66  const_reference back()  const { return m_CommandQueue.back(); }
67  reference       back()        { return m_CommandQueue.back(); }
68
69  const Input& input() const { return m_Input; }
70  Input&       input()       { return m_Input; }
71
72  size_t size() const { return m_CommandQueue.size(); }
73
74  Kind getKind() const { return m_Kind; }
75
76  const InputTree& inputs() const { return *m_pInputTree; }
77  InputTree&       inputs()       { return *m_pInputTree; }
78
79  const std::string& name() const { return m_Name; }
80  std::string&       name()       { return m_Name; }
81
82  void dump() const;
83  void activate(Module& pModule);
84
85  /// ENTRY(symbol)
86  void addEntryPoint(const std::string& pSymbol);
87
88  /// OUTPUT_FORMAT(bfdname)
89  /// OUTPUT_FORMAT(default, big, little)
90  void addOutputFormatCmd(const std::string& pFormat);
91  void addOutputFormatCmd(const std::string& pDefault,
92                          const std::string& pBig,
93                          const std::string& pLittle);
94
95  /// GROUP(file, file, ...)
96  /// GROUP(file file ...)
97  void addGroupCmd(StringList& pStringList,
98                   GroupReader& pGroupReader,
99                   const LinkerConfig& pConfig);
100
101  /// OUTPUT(filename)
102  void addOutputCmd(const std::string& pFileName);
103
104  /// SEARCH_DIR(path)
105  void addSearchDirCmd(const std::string& pPath);
106
107  /// OUTPUT_ARCH(bfdarch)
108  void addOutputArchCmd(const std::string& pArch);
109
110  /// ASSERT(exp, message)
111  void addAssertCmd(RpnExpr& pRpnExpr, const std::string& pMessage);
112
113  /// assignment
114  void addAssignment(const std::string& pSymbol,
115                     RpnExpr& pRpnExpr,
116                     Assignment::Type pType = Assignment::DEFAULT);
117
118  bool hasSectionsCmd() const;
119
120  void enterSectionsCmd();
121
122  void leaveSectionsCmd();
123
124  void enterOutputSectDesc(const std::string& pName,
125                           const OutputSectDesc::Prolog& pProlog);
126
127  void leaveOutputSectDesc(const OutputSectDesc::Epilog& pEpilog);
128
129  void addInputSectDesc(InputSectDesc::KeepPolicy pPolicy,
130                        const InputSectDesc::Spec& pSpec);
131
132  RpnExpr* createRpnExpr();
133  const RpnExpr* getCurrentRpnExpr() const { return m_pRpnExpr; }
134  RpnExpr*       getCurrentRpnExpr()       { return m_pRpnExpr; }
135
136  StringList* createStringList();
137  const StringList* getCurrentStringList() const { return m_pStringList; }
138  StringList*       getCurrentStringList()       { return m_pStringList; }
139
140  void setAsNeeded(bool pEnable = true);
141  bool asNeeded() const { return m_bAsNeeded; }
142
143  static const std::string& createParserStr(const char* pText, size_t pLength);
144
145  static void clearParserStrPool();
146
147private:
148  Kind m_Kind;
149  Input& m_Input;
150  std::string m_Name;
151  InputTree* m_pInputTree;
152  InputBuilder& m_Builder;
153  CommandQueue m_CommandQueue;
154  bool m_bHasSectionsCmd;
155  bool m_bInSectionsCmd;
156  bool m_bInOutputSectDesc;
157  RpnExpr* m_pRpnExpr;
158  StringList* m_pStringList;
159  bool m_bAsNeeded;
160};
161
162} // namespace of mcld
163
164#endif
165
166