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