1 //===- OutputSectDesc.cpp -------------------------------------------------===// 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 #include "mcld/Script/OutputSectDesc.h" 10 11 #include "mcld/Script/InputSectDesc.h" 12 #include "mcld/Script/RpnExpr.h" 13 #include "mcld/Script/StringList.h" 14 #include "mcld/Script/StrToken.h" 15 #include "mcld/Support/raw_ostream.h" 16 #include "mcld/LinkerScript.h" 17 #include "mcld/Module.h" 18 19 #include <llvm/Support/Casting.h> 20 21 #include <cassert> 22 23 namespace mcld { 24 25 //===----------------------------------------------------------------------===// 26 // OutputSectDesc 27 //===----------------------------------------------------------------------===// 28 OutputSectDesc::OutputSectDesc(const std::string& pName, const Prolog& pProlog) 29 : ScriptCommand(ScriptCommand::OUTPUT_SECT_DESC), 30 m_Name(pName), 31 m_Prolog(pProlog) { 32 } 33 34 OutputSectDesc::~OutputSectDesc() { 35 for (iterator it = begin(), ie = end(); it != ie; ++it) { 36 if (*it != NULL) 37 delete *it; 38 } 39 } 40 41 void OutputSectDesc::dump() const { 42 mcld::outs() << m_Name << "\t"; 43 44 if (m_Prolog.hasVMA()) { 45 m_Prolog.vma().dump(); 46 mcld::outs() << "\t"; 47 } 48 49 switch (m_Prolog.type()) { 50 case NOLOAD: 51 mcld::outs() << "(NOLOAD)"; 52 break; 53 case DSECT: 54 mcld::outs() << "(DSECT)"; 55 break; 56 case COPY: 57 mcld::outs() << "(COPY)"; 58 break; 59 case INFO: 60 mcld::outs() << "(INFO)"; 61 break; 62 case OVERLAY: 63 mcld::outs() << "(OVERLAY)"; 64 break; 65 default: 66 break; 67 } 68 mcld::outs() << ":\n"; 69 70 if (m_Prolog.hasLMA()) { 71 mcld::outs() << "\tAT ( "; 72 m_Prolog.lma().dump(); 73 mcld::outs() << " )\n"; 74 } 75 76 if (m_Prolog.hasAlign()) { 77 mcld::outs() << "\tALIGN ( "; 78 m_Prolog.align().dump(); 79 mcld::outs() << " )\n"; 80 } 81 82 if (m_Prolog.hasSubAlign()) { 83 mcld::outs() << "\tSUBALIGN ( "; 84 m_Prolog.subAlign().dump(); 85 mcld::outs() << " )\n"; 86 } 87 88 switch (m_Prolog.constraint()) { 89 case ONLY_IF_RO: 90 mcld::outs() << "\tONLY_IF_RO\n"; 91 break; 92 case ONLY_IF_RW: 93 mcld::outs() << "\tONLY_IF_RW\n"; 94 break; 95 default: 96 break; 97 } 98 99 mcld::outs() << "\t{\n"; 100 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 101 switch ((*it)->getKind()) { 102 case ScriptCommand::ASSIGNMENT: 103 case ScriptCommand::INPUT_SECT_DESC: 104 mcld::outs() << "\t\t"; 105 (*it)->dump(); 106 break; 107 default: 108 assert(0); 109 break; 110 } 111 } 112 mcld::outs() << "\t}"; 113 114 if (m_Epilog.hasRegion()) 115 mcld::outs() << "\t>" << m_Epilog.region(); 116 if (m_Epilog.hasLMARegion()) 117 mcld::outs() << "\tAT>" << m_Epilog.lmaRegion(); 118 119 if (m_Epilog.hasPhdrs()) { 120 for (StringList::const_iterator it = m_Epilog.phdrs().begin(), 121 ie = m_Epilog.phdrs().end(); 122 it != ie; 123 ++it) { 124 assert((*it)->kind() == StrToken::String); 125 mcld::outs() << ":" << (*it)->name() << " "; 126 } 127 } 128 129 if (m_Epilog.hasFillExp()) { 130 mcld::outs() << "= "; 131 m_Epilog.fillExp().dump(); 132 } 133 mcld::outs() << "\n"; 134 } 135 136 void OutputSectDesc::push_back(ScriptCommand* pCommand) { 137 switch (pCommand->getKind()) { 138 case ScriptCommand::ASSIGNMENT: 139 case ScriptCommand::INPUT_SECT_DESC: 140 m_OutputSectCmds.push_back(pCommand); 141 break; 142 default: 143 assert(0); 144 break; 145 } 146 } 147 148 void OutputSectDesc::setEpilog(const Epilog& pEpilog) { 149 m_Epilog.m_pRegion = pEpilog.m_pRegion; 150 m_Epilog.m_pLMARegion = pEpilog.m_pLMARegion; 151 m_Epilog.m_pPhdrs = pEpilog.m_pPhdrs; 152 m_Epilog.m_pFillExp = pEpilog.m_pFillExp; 153 } 154 155 void OutputSectDesc::activate(Module& pModule) { 156 // Assignment in an output section 157 OutputSectCmds assignments; 158 159 for (const_iterator it = begin(), ie = end(); it != ie; ++it) { 160 switch ((*it)->getKind()) { 161 case ScriptCommand::ASSIGNMENT: 162 assignments.push_back(*it); 163 break; 164 case ScriptCommand::INPUT_SECT_DESC: { 165 (*it)->activate(pModule); 166 167 for (iterator assign = assignments.begin(), 168 assignEnd = assignments.end(); 169 assign != assignEnd; 170 ++assign) { 171 (*assign)->activate(pModule); 172 } 173 assignments.clear(); 174 break; 175 } 176 default: 177 assert(0); 178 break; 179 } 180 } 181 182 if (!assignments.empty()) { 183 InputSectDesc::Spec spec; 184 spec.m_pWildcardFile = NULL; 185 spec.m_pExcludeFiles = NULL; 186 spec.m_pWildcardSections = NULL; 187 InputSectDesc inputDesc(InputSectDesc::Keep, spec, *this); 188 pModule.getScript().sectionMap().insert(inputDesc, *this); 189 190 for (iterator assign = assignments.begin(), assignEnd = assignments.end(); 191 assign != assignEnd; 192 ++assign) { 193 (*assign)->activate(pModule); 194 } 195 assignments.clear(); 196 } 197 } 198 199 } // namespace mcld 200