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