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