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