• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 //===----------------------------------------------------------------------===//
OutputSectDesc(const std::string & pName,const Prolog & pProlog)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 
~OutputSectDesc()34 OutputSectDesc::~OutputSectDesc() {
35   for (iterator it = begin(), ie = end(); it != ie; ++it) {
36     if (*it != NULL)
37       delete *it;
38   }
39 }
40 
dump() const41 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 
push_back(ScriptCommand * pCommand)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 
setEpilog(const Epilog & pEpilog)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 
activate(Module & pModule)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