1 //===- SectLinker.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 //
10 // This file implements the SectLinker class.
11 //
12 //===----------------------------------------------------------------------===//
13 #include <mcld/Support/FileHandle.h>
14 #include <mcld/MC/InputTree.h>
15 #include <mcld/MC/MCLDDriver.h>
16 #include <mcld/Support/FileSystem.h>
17 #include <mcld/Support/MsgHandling.h>
18 #include <mcld/Support/FileHandle.h>
19 #include <mcld/Support/raw_ostream.h>
20 #include <mcld/Support/MemoryAreaFactory.h>
21 #include <mcld/Support/DerivedPositionDependentOptions.h>
22 #include <mcld/Target/TargetLDBackend.h>
23 #include <mcld/CodeGen/SectLinker.h>
24 #include <mcld/CodeGen/SectLinkerOption.h>
25
26 #include <llvm/Module.h>
27
28 #include <algorithm>
29 #include <stack>
30 #include <string>
31
32 using namespace mcld;
33 using namespace llvm;
34
35 //===----------------------------------------------------------------------===//
36 // Forward declarations
37 char SectLinker::m_ID = 0;
38 static bool CompareOption(const PositionDependentOption* X,
39 const PositionDependentOption* Y);
40
41 //===----------------------------------------------------------------------===//
42 // SectLinker
SectLinker(SectLinkerOption & pOption,TargetLDBackend & pLDBackend)43 SectLinker::SectLinker(SectLinkerOption &pOption,
44 TargetLDBackend& pLDBackend)
45 : MachineFunctionPass(m_ID),
46 m_pOption(&pOption),
47 m_pLDBackend(&pLDBackend),
48 m_pLDDriver(NULL),
49 m_pMemAreaFactory(NULL)
50 {
51 m_pMemAreaFactory = new MemoryAreaFactory(32);
52 }
53
~SectLinker()54 SectLinker::~SectLinker()
55 {
56 delete m_pLDDriver;
57
58 // FIXME: current implementation can not change the order of delete.
59 //
60 // Instance of TargetLDBackend was created outside and is not managed by
61 // SectLinker. It should not be destroyed here and by SectLinker. However, in
62 // order to follow the LLVM convention - that is, the pass manages all the
63 // objects it used during the processing, we destroy the object of
64 // TargetLDBackend here.
65 delete m_pLDBackend;
66
67 delete m_pMemAreaFactory;
68 }
69
doInitialization(Module & pM)70 bool SectLinker::doInitialization(Module &pM)
71 {
72 MCLDInfo &info = m_pOption->info();
73
74 // ----- convert position dependent options into tree of input files ----- //
75 PositionDependentOptions &PosDepOpts = m_pOption->pos_dep_options();
76 std::stable_sort(PosDepOpts.begin(), PosDepOpts.end(), CompareOption);
77 initializeInputTree(PosDepOpts);
78 initializeInputOutput(info);
79 // Now, all input arguments are prepared well, send it into MCLDDriver
80 m_pLDDriver = new MCLDDriver(info, *m_pLDBackend, *memAreaFactory());
81
82 return false;
83 }
84
doFinalization(Module & pM)85 bool SectLinker::doFinalization(Module &pM)
86 {
87 const MCLDInfo &info = m_pOption->info();
88
89 // 2. - initialize MCLinker
90 if (!m_pLDDriver->initMCLinker())
91 return true;
92
93 // 3. - initialize output's standard sections
94 if (!m_pLDDriver->initStdSections())
95 return true;
96
97 // 4. - normalize the input tree
98 m_pLDDriver->normalize();
99
100 if (info.options().trace()) {
101 static int counter = 0;
102 mcld::outs() << "** name\ttype\tpath\tsize (" << info.inputs().size() << ")\n";
103 InputTree::const_dfs_iterator input, inEnd = info.inputs().dfs_end();
104 for (input=info.inputs().dfs_begin(); input!=inEnd; ++input) {
105 mcld::outs() << counter++ << " * " << (*input)->name();
106 switch((*input)->type()) {
107 case Input::Archive:
108 mcld::outs() << "\tarchive\t(";
109 break;
110 case Input::Object:
111 mcld::outs() << "\tobject\t(";
112 break;
113 case Input::DynObj:
114 mcld::outs() << "\tshared\t(";
115 break;
116 case Input::Script:
117 mcld::outs() << "\tscript\t(";
118 break;
119 case Input::External:
120 mcld::outs() << "\textern\t(";
121 break;
122 default:
123 unreachable(diag::err_cannot_trace_file) << (*input)->type()
124 << (*input)->name()
125 << (*input)->path();
126 }
127 mcld::outs() << (*input)->path() << ")\n";
128 }
129 }
130
131 // 5. - check if we can do static linking and if we use split-stack.
132 if (!m_pLDDriver->linkable())
133 return true;
134
135
136 // 6. - merge all sections
137 if (!m_pLDDriver->mergeSections())
138 return true;
139
140 // 7. - add standard symbols and target-dependent symbols
141 // m_pLDDriver->addUndefSymbols();
142 if (!m_pLDDriver->addStandardSymbols() ||
143 !m_pLDDriver->addTargetSymbols())
144 return true;
145
146 // 8. - read all relocation entries from input files
147 m_pLDDriver->readRelocations();
148
149 // 9. - pre-layout
150 m_pLDDriver->prelayout();
151
152 // 10. - linear layout
153 m_pLDDriver->layout();
154
155 // 10.b - post-layout (create segment, instruction relaxing)
156 m_pLDDriver->postlayout();
157
158 // 11. - finalize symbol value
159 m_pLDDriver->finalizeSymbolValue();
160
161 // 12. - apply relocations
162 m_pLDDriver->relocation();
163
164 // 13. - write out output
165 m_pLDDriver->emitOutput();
166
167 // 14. - post processing
168 m_pLDDriver->postProcessing();
169 return false;
170 }
171
runOnMachineFunction(MachineFunction & pF)172 bool SectLinker::runOnMachineFunction(MachineFunction& pF)
173 {
174 // basically, linkers do nothing during function is generated.
175 return false;
176 }
177
initializeInputOutput(MCLDInfo & pLDInfo)178 void SectLinker::initializeInputOutput(MCLDInfo &pLDInfo)
179 {
180 // ----- initialize output file ----- //
181 FileHandle::Permission perm;
182 if (Output::Object == pLDInfo.output().type())
183 perm = 0544;
184 else
185 perm = 0755;
186
187 MemoryArea* out_area = memAreaFactory()->produce(pLDInfo.output().path(),
188 FileHandle::ReadWrite,
189 perm);
190
191 if (!out_area->handler()->isGood()) {
192 // make sure output is openend successfully.
193 fatal(diag::err_cannot_open_output_file) << pLDInfo.output().name()
194 << pLDInfo.output().path();
195 }
196
197 pLDInfo.output().setMemArea(out_area);
198 pLDInfo.output().setContext(pLDInfo.contextFactory().produce());
199
200 // ----- initialize input files ----- //
201 InputTree::dfs_iterator input, inEnd = pLDInfo.inputs().dfs_end();
202 for (input = pLDInfo.inputs().dfs_begin(); input!=inEnd; ++input) {
203 // already got type - for example, bitcode
204 if ((*input)->type() == Input::Script ||
205 (*input)->type() == Input::Object ||
206 (*input)->type() == Input::DynObj ||
207 (*input)->type() == Input::Archive)
208 continue;
209
210 MemoryArea *input_memory =
211 memAreaFactory()->produce((*input)->path(), FileHandle::ReadOnly);
212
213 if (input_memory->handler()->isGood()) {
214 (*input)->setMemArea(input_memory);
215 }
216 else {
217 error(diag::err_cannot_open_input) << (*input)->name() << (*input)->path();
218 return;
219 }
220
221 LDContext *input_context =
222 pLDInfo.contextFactory().produce((*input)->path());
223
224 (*input)->setContext(input_context);
225 }
226 }
227
initializeInputTree(const PositionDependentOptions & pPosDepOptions) const228 void SectLinker::initializeInputTree(const PositionDependentOptions &pPosDepOptions) const
229 {
230 if (pPosDepOptions.empty())
231 fatal(diag::err_no_inputs);
232
233 MCLDInfo &info = m_pOption->info();
234 PositionDependentOptions::const_iterator option = pPosDepOptions.begin();
235 if (1 == pPosDepOptions.size() &&
236 ((*option)->type() != PositionDependentOption::INPUT_FILE &&
237 (*option)->type() != PositionDependentOption::NAMESPEC) &&
238 (*option)->type() != PositionDependentOption::BITCODE) {
239 // if we only have one positional options, and the option is
240 // not an input file, then emit error message.
241 fatal(diag::err_no_inputs);
242 }
243
244 // ----- Input tree insertion algorithm ----- //
245 // The type of the previsou node indicates the direction of the current
246 // insertion.
247 //
248 // root : the parent node who being inserted.
249 // mover : the direcion of current movement.
250 //
251 // for each positional options:
252 // insert the options in current root.
253 // calculate the next movement
254
255 // Initialization
256 InputTree::Mover *move = &InputTree::Downward;
257 InputTree::iterator root = info.inputs().root();
258 PositionDependentOptions::const_iterator optionEnd = pPosDepOptions.end();
259 std::stack<InputTree::iterator> returnStack;
260
261 while (option != optionEnd ) {
262
263 switch ((*option)->type()) {
264 /** bitcode **/
265 case PositionDependentOption::BITCODE: {
266
267 const BitcodeOption *bitcode_option =
268 static_cast<const BitcodeOption*>(*option);
269
270 // threat bitcode as an external IR in this version.
271 info.inputs().insert(root, *move,
272 bitcode_option->path()->native(),
273 *(bitcode_option->path()),
274 Input::External);
275
276 info.setBitcode(**root);
277
278 // move root on the new created node.
279 move->move(root);
280
281 // the next file is appended after bitcode file.
282 move = &InputTree::Afterward;
283 break;
284 }
285
286 /** input object file **/
287 case PositionDependentOption::INPUT_FILE: {
288 const InputFileOption *input_file_option =
289 static_cast<const InputFileOption*>(*option);
290
291 info.inputs().insert(root, *move,
292 input_file_option->path()->native(),
293 *(input_file_option->path()));
294
295 // move root on the new created node.
296 move->move(root);
297
298 // the next file is appended after object file.
299 move = &InputTree::Afterward;
300 break;
301 }
302
303 /** -lnamespec **/
304 case PositionDependentOption::NAMESPEC: {
305 sys::fs::Path* path = NULL;
306 const NamespecOption *namespec_option =
307 static_cast<const NamespecOption*>(*option);
308
309 // find out the real path of the namespec.
310 if (info.attrFactory().constraint().isSharedSystem()) {
311 // In the system with shared object support, we can find both archive
312 // and shared object.
313
314 if (info.attrFactory().last().isStatic()) {
315 // with --static, we must search an archive.
316 path = info.options().directories().find(namespec_option->namespec(),
317 Input::Archive);
318 }
319 else {
320 // otherwise, with --Bdynamic, we can find either an archive or a
321 // shared object.
322 path = info.options().directories().find(namespec_option->namespec(),
323 Input::DynObj);
324 }
325 }
326 else {
327 // In the system without shared object support, we only look for an
328 // archive.
329 path = info.options().directories().find(namespec_option->namespec(),
330 Input::Archive);
331 }
332
333 if (NULL == path)
334 fatal(diag::err_cannot_find_namespec) << namespec_option->namespec();
335
336 info.inputs().insert(root, *move,
337 namespec_option->namespec(),
338 *path);
339
340 // iterate root on the new created node.
341 move->move(root);
342
343 // the file after a namespec must be appended afterward.
344 move = &InputTree::Afterward;
345 break;
346 }
347
348 /** start group **/
349 case PositionDependentOption::START_GROUP:
350 info.inputs().enterGroup(root, *move);
351 move->move(root);
352 returnStack.push(root);
353 move = &InputTree::Downward;
354 break;
355 /** end group **/
356 case PositionDependentOption::END_GROUP:
357 root = returnStack.top();
358 returnStack.pop();
359 move = &InputTree::Afterward;
360 break;
361 case PositionDependentOption::WHOLE_ARCHIVE:
362 info.attrFactory().last().setWholeArchive();
363 break;
364 case PositionDependentOption::NO_WHOLE_ARCHIVE:
365 info.attrFactory().last().unsetWholeArchive();
366 break;
367 case PositionDependentOption::AS_NEEDED:
368 info.attrFactory().last().setAsNeeded();
369 break;
370 case PositionDependentOption::NO_AS_NEEDED:
371 info.attrFactory().last().unsetAsNeeded();
372 break;
373 case PositionDependentOption::ADD_NEEDED:
374 info.attrFactory().last().setAddNeeded();
375 break;
376 case PositionDependentOption::NO_ADD_NEEDED:
377 info.attrFactory().last().unsetAddNeeded();
378 break;
379 case PositionDependentOption::BSTATIC:
380 info.attrFactory().last().setStatic();
381 break;
382 case PositionDependentOption::BDYNAMIC:
383 info.attrFactory().last().setDynamic();
384 break;
385 default:
386 fatal(diag::err_cannot_identify_option) << (*option)->position()
387 << (uint32_t)(*option)->type();
388 } // end of switch
389 ++option;
390 } // end of while
391
392 if (!returnStack.empty()) {
393 report_fatal_error("no matched --start-group and --end-group");
394 }
395 }
396
397 //===----------------------------------------------------------------------===//
398 // Non-member functions
CompareOption(const PositionDependentOption * X,const PositionDependentOption * Y)399 static bool CompareOption(const PositionDependentOption* X,
400 const PositionDependentOption* Y)
401 {
402 return (X->position() < Y->position());
403 }
404
405