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 //===----------------------------------------------------------------------===//
OutputSectDesc(const std::string & pName,const Prolog & pProlog)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
~OutputSectDesc()33 OutputSectDesc::~OutputSectDesc()
34 {
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 {
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
push_back(ScriptCommand * pCommand)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
setEpilog(const Epilog & pEpilog)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
activate(Module & pModule)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