1 //===- OutputSectDesc.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_OUTPUTSECTDESC_H_
10 #define MCLD_SCRIPT_OUTPUTSECTDESC_H_
11 
12 #include "mcld/Script/ScriptCommand.h"
13 
14 #include <string>
15 #include <vector>
16 
17 #include <cassert>
18 
19 namespace mcld {
20 
21 class RpnExpr;
22 class StringList;
23 
24 /** \class OutputSectDesc
25  *  \brief This class defines the interfaces to output section description.
26  */
27 
28 class OutputSectDesc : public ScriptCommand {
29  public:
30   enum Type {
31     LOAD,  // ALLOC
32     NOLOAD,
33     DSECT,
34     COPY,
35     INFO,
36     OVERLAY
37   };
38 
39   enum Constraint { NO_CONSTRAINT, ONLY_IF_RO, ONLY_IF_RW };
40 
41   struct Prolog {
hasVMAProlog42     bool hasVMA() const { return m_pVMA != NULL; }
vmaProlog43     const RpnExpr& vma() const {
44       assert(hasVMA());
45       return *m_pVMA;
46     }
vmaProlog47     RpnExpr& vma() {
48       assert(hasVMA());
49       return *m_pVMA;
50     }
51 
setTypeProlog52     void setType(Type pType) { m_Type = pType; }
53 
typeProlog54     Type type() const { return m_Type; }
55 
hasLMAProlog56     bool hasLMA() const { return m_pLMA != NULL; }
lmaProlog57     const RpnExpr& lma() const {
58       assert(hasLMA());
59       return *m_pLMA;
60     }
lmaProlog61     RpnExpr& lma() {
62       assert(hasLMA());
63       return *m_pLMA;
64     }
65 
hasAlignProlog66     bool hasAlign() const { return m_pAlign != NULL; }
alignProlog67     const RpnExpr& align() const {
68       assert(hasAlign());
69       return *m_pAlign;
70     }
71 
hasSubAlignProlog72     bool hasSubAlign() const { return m_pSubAlign != NULL; }
subAlignProlog73     const RpnExpr& subAlign() const {
74       assert(hasSubAlign());
75       return *m_pSubAlign;
76     }
77 
constraintProlog78     Constraint constraint() const { return m_Constraint; }
79 
80     bool operator==(const Prolog& pRHS) const {
81       /* FIXME: currently I don't check the real content */
82       if (this == &pRHS)
83         return true;
84       if (m_pVMA != pRHS.m_pVMA)
85         return false;
86       if (m_Type != pRHS.m_Type)
87         return false;
88       if (m_pLMA != pRHS.m_pLMA)
89         return false;
90       if (m_pAlign != pRHS.m_pAlign)
91         return false;
92       if (m_pSubAlign != pRHS.m_pSubAlign)
93         return false;
94       if (m_Constraint != pRHS.m_Constraint)
95         return false;
96       return true;
97     }
98 
99     RpnExpr* m_pVMA;
100     Type m_Type;
101     RpnExpr* m_pLMA;
102     RpnExpr* m_pAlign;
103     RpnExpr* m_pSubAlign;
104     Constraint m_Constraint;
105   };
106 
107   struct Epilog {
hasRegionEpilog108     bool hasRegion() const { return m_pRegion != NULL; }
regionEpilog109     const std::string& region() const {
110       assert(hasRegion());
111       return *m_pRegion;
112     }
113 
hasLMARegionEpilog114     bool hasLMARegion() const { return m_pLMARegion != NULL; }
lmaRegionEpilog115     const std::string& lmaRegion() const {
116       assert(hasLMARegion());
117       return *m_pLMARegion;
118     }
119 
hasPhdrsEpilog120     bool hasPhdrs() const { return m_pPhdrs != NULL; }
phdrsEpilog121     const StringList& phdrs() const {
122       assert(hasPhdrs());
123       return *m_pPhdrs;
124     }
125 
hasFillExpEpilog126     bool hasFillExp() const { return m_pFillExp != NULL; }
fillExpEpilog127     const RpnExpr& fillExp() const {
128       assert(hasFillExp());
129       return *m_pFillExp;
130     }
131 
132     bool operator==(const Epilog& pRHS) const {
133       /* FIXME: currently I don't check the real content */
134       if (this == &pRHS)
135         return true;
136       if (m_pRegion != pRHS.m_pRegion)
137         return false;
138       if (m_pLMARegion != pRHS.m_pLMARegion)
139         return false;
140       if (m_pPhdrs != pRHS.m_pPhdrs)
141         return false;
142       if (m_pFillExp != pRHS.m_pFillExp)
143         return false;
144       return true;
145     }
146 
147     const std::string* m_pRegion;
148     const std::string* m_pLMARegion;
149     StringList* m_pPhdrs;
150     RpnExpr* m_pFillExp;
151   };
152 
153   typedef std::vector<ScriptCommand*> OutputSectCmds;
154   typedef OutputSectCmds::const_iterator const_iterator;
155   typedef OutputSectCmds::iterator iterator;
156   typedef OutputSectCmds::const_reference const_reference;
157   typedef OutputSectCmds::reference reference;
158 
159  public:
160   OutputSectDesc(const std::string& pName, const Prolog& pProlog);
161   ~OutputSectDesc();
162 
begin()163   const_iterator begin() const { return m_OutputSectCmds.begin(); }
begin()164   iterator begin() { return m_OutputSectCmds.begin(); }
end()165   const_iterator end() const { return m_OutputSectCmds.end(); }
end()166   iterator end() { return m_OutputSectCmds.end(); }
167 
front()168   const_reference front() const { return m_OutputSectCmds.front(); }
front()169   reference front() { return m_OutputSectCmds.front(); }
back()170   const_reference back() const { return m_OutputSectCmds.back(); }
back()171   reference back() { return m_OutputSectCmds.back(); }
172 
name()173   const std::string& name() const { return m_Name; }
174 
size()175   size_t size() const { return m_OutputSectCmds.size(); }
176 
empty()177   bool empty() const { return m_OutputSectCmds.empty(); }
178 
179   void dump() const;
180 
classof(const ScriptCommand * pCmd)181   static bool classof(const ScriptCommand* pCmd) {
182     return pCmd->getKind() == ScriptCommand::OUTPUT_SECT_DESC;
183   }
184 
185   void activate(Module& pModule);
186 
187   void push_back(ScriptCommand* pCommand);
188 
189   void setEpilog(const Epilog& pEpilog);
190 
prolog()191   const Prolog& prolog() const { return m_Prolog; }
192 
epilog()193   const Epilog& epilog() const { return m_Epilog; }
194 
195  private:
196   OutputSectCmds m_OutputSectCmds;
197   std::string m_Name;
198   Prolog m_Prolog;
199   Epilog m_Epilog;
200 };
201 
202 }  // namespace mcld
203 
204 #endif  // MCLD_SCRIPT_OUTPUTSECTDESC_H_
205