1 //===- MCLinker.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 MCLinker class.
11 //
12 //===----------------------------------------------------------------------===//
13 #include <mcld/CodeGen/MCLinker.h>
14
15 #include <mcld/Module.h>
16 #include <mcld/LinkerConfig.h>
17 #include <mcld/LinkerScript.h>
18 #include <mcld/InputTree.h>
19 #include <mcld/Linker.h>
20 #include <mcld/IRBuilder.h>
21 #include <mcld/MC/InputBuilder.h>
22 #include <mcld/MC/FileAction.h>
23 #include <mcld/MC/CommandAction.h>
24 #include <mcld/Object/ObjectLinker.h>
25 #include <mcld/Support/CommandLine.h>
26 #include <mcld/Support/FileSystem.h>
27 #include <mcld/Support/MsgHandling.h>
28 #include <mcld/Support/FileHandle.h>
29 #include <mcld/Support/raw_ostream.h>
30
31 #include <llvm/IR/Module.h>
32 #include <llvm/Support/CommandLine.h>
33
34 #include <algorithm>
35 #include <vector>
36 #include <string>
37
38 using namespace mcld;
39 using namespace llvm;
40
41 char MCLinker::m_ID = 0;
42
43 //===----------------------------------------------------------------------===//
44 // Help Functions
45 //===----------------------------------------------------------------------===//
CompareAction(const InputAction * X,const InputAction * Y)46 static inline bool CompareAction(const InputAction* X, const InputAction* Y)
47 {
48 return (X->position() < Y->position());
49 }
50
51 //===----------------------------------------------------------------------===//
52 // Positional Options
53 // There are four kinds of positional options:
54 // 1. Inputs, object files, such as /tmp/XXXX.o
55 // 2. Namespecs, short names of libraries. A namespec may refer to an archive
56 // or a shared library. For example, -lm.
57 // 3. Attributes of inputs. Attributes describe inputs appears after them.
58 // For example, --as-needed and --whole-archive.
59 // 4. Groups. A Group is a set of archives. Linkers repeatedly read archives
60 // in groups until there is no new undefined symbols.
61 // 5. Bitcode. Bitcode is a kind of object files. MCLinker compiles it to
62 // object file first, then link it as a object file. (Bitcode is recorded
63 // in BitcodeOption, not be read by LLVM Command Line library.)
64 //===----------------------------------------------------------------------===//
65 // Inputs
66 //===----------------------------------------------------------------------===//
67 static cl::list<mcld::sys::fs::Path>
68 ArgInputObjectFiles(cl::Positional,
69 cl::desc("[input object files]"),
70 cl::ZeroOrMore);
71
72 //===----------------------------------------------------------------------===//
73 // Namespecs
74 //===----------------------------------------------------------------------===//
75 static cl::list<std::string>
76 ArgNameSpecList("l",
77 cl::ZeroOrMore,
78 cl::desc("Add the archive or object file specified by namespec to "
79 "the list of files to link."),
80 cl::value_desc("namespec"),
81 cl::Prefix);
82
83 static cl::alias
84 ArgNameSpecListAlias("library",
85 cl::desc("alias for -l"),
86 cl::aliasopt(ArgNameSpecList));
87
88 //===----------------------------------------------------------------------===//
89 // Attributes
90 //===----------------------------------------------------------------------===//
91 static cl::list<bool>
92 ArgWholeArchiveList("whole-archive",
93 cl::ValueDisallowed,
94 cl::desc("For each archive mentioned on the command line after "
95 "the --whole-archive option, include all object files "
96 "in the archive."));
97
98 static cl::list<bool>
99 ArgNoWholeArchiveList("no-whole-archive",
100 cl::ValueDisallowed,
101 cl::desc("Turn off the effect of the --whole-archive option for "
102 "subsequent archive files."));
103
104 static cl::list<bool>
105 ArgAsNeededList("as-needed",
106 cl::ValueDisallowed,
107 cl::desc("This option affects ELF DT_NEEDED tags for dynamic "
108 "libraries mentioned on the command line after the "
109 "--as-needed option."));
110
111 static cl::list<bool>
112 ArgNoAsNeededList("no-as-needed",
113 cl::ValueDisallowed,
114 cl::desc("Turn off the effect of the --as-needed option for "
115 "subsequent dynamic libraries"));
116
117 static cl::list<bool>
118 ArgAddNeededList("add-needed",
119 cl::ValueDisallowed,
120 cl::desc("--add-needed causes DT_NEEDED tags are always "
121 "emitted for those libraries from DT_NEEDED tags. "
122 "This is the default behavior."));
123
124 static cl::list<bool>
125 ArgNoAddNeededList("no-add-needed",
126 cl::ValueDisallowed,
127 cl::desc("--no-add-needed causes DT_NEEDED tags will never be "
128 "emitted for those libraries from DT_NEEDED tags"));
129
130 static cl::list<bool>
131 ArgBDynamicList("Bdynamic",
132 cl::ValueDisallowed,
133 cl::desc("Link against dynamic library"));
134
135 static cl::alias
136 ArgBDynamicListAlias1("dy",
137 cl::desc("alias for --Bdynamic"),
138 cl::aliasopt(ArgBDynamicList));
139
140 static cl::alias
141 ArgBDynamicListAlias2("call_shared",
142 cl::desc("alias for --Bdynamic"),
143 cl::aliasopt(ArgBDynamicList));
144
145 static cl::list<bool>
146 ArgBStaticList("Bstatic",
147 cl::ValueDisallowed,
148 cl::desc("Link against static library"));
149
150 static cl::alias
151 ArgBStaticListAlias1("dn",
152 cl::desc("alias for --Bstatic"),
153 cl::aliasopt(ArgBStaticList));
154
155 static cl::alias
156 ArgBStaticListAlias2("static",
157 cl::desc("alias for --Bstatic"),
158 cl::aliasopt(ArgBStaticList));
159
160 static cl::alias
161 ArgBStaticListAlias3("non_shared",
162 cl::desc("alias for --Bstatic"),
163 cl::aliasopt(ArgBStaticList));
164
165 //===----------------------------------------------------------------------===//
166 // Groups
167 //===----------------------------------------------------------------------===//
168 static cl::list<bool>
169 ArgStartGroupList("start-group",
170 cl::ValueDisallowed,
171 cl::desc("start to record a group of archives"));
172
173 static cl::alias
174 ArgStartGroupListAlias("(",
175 cl::desc("alias for --start-group"),
176 cl::aliasopt(ArgStartGroupList));
177
178 static cl::list<bool>
179 ArgEndGroupList("end-group",
180 cl::ValueDisallowed,
181 cl::desc("stop recording a group of archives"));
182
183 static cl::alias
184 ArgEndGroupListAlias(")",
185 cl::desc("alias for --end-group"),
186 cl::aliasopt(ArgEndGroupList));
187
188 //===----------------------------------------------------------------------===//
189 // --defsym
190 //===----------------------------------------------------------------------===//
191 static cl::list<std::string>
192 ArgDefSymList("defsym",
193 cl::ZeroOrMore,
194 cl::desc("Define a symbol"),
195 cl::value_desc("symbol=expression"));
196
197 //===----------------------------------------------------------------------===//
198 // MCLinker
199 //===----------------------------------------------------------------------===//
MCLinker(LinkerConfig & pConfig,mcld::Module & pModule,FileHandle & pFileHandle)200 MCLinker::MCLinker(LinkerConfig& pConfig,
201 mcld::Module& pModule,
202 FileHandle& pFileHandle)
203 : MachineFunctionPass(m_ID),
204 m_Config(pConfig),
205 m_Module(pModule),
206 m_FileHandle(pFileHandle),
207 m_pBuilder(NULL),
208 m_pLinker(NULL) {
209 }
210
~MCLinker()211 MCLinker::~MCLinker()
212 {
213 delete m_pLinker;
214 delete m_pBuilder;
215 }
216
doInitialization(llvm::Module & pM)217 bool MCLinker::doInitialization(llvm::Module &pM)
218 {
219 // Now, all input arguments are prepared well, send it into ObjectLinker
220 m_pLinker = new Linker();
221
222 if (!m_pLinker->emulate(m_Module.getScript(), m_Config))
223 return false;
224
225 m_pBuilder = new IRBuilder(m_Module, m_Config);
226
227 initializeInputTree(*m_pBuilder);
228
229 return true;
230 }
231
doFinalization(llvm::Module & pM)232 bool MCLinker::doFinalization(llvm::Module &pM)
233 {
234 if (!m_pLinker->link(m_Module, *m_pBuilder))
235 return true;
236
237 if (!m_pLinker->emit(m_Module, m_FileHandle.handler()))
238 return true;
239
240 return false;
241 }
242
runOnMachineFunction(MachineFunction & pF)243 bool MCLinker::runOnMachineFunction(MachineFunction& pF)
244 {
245 // basically, linkers do nothing during function is generated.
246 return false;
247 }
248
initializeInputTree(IRBuilder & pBuilder)249 void MCLinker::initializeInputTree(IRBuilder& pBuilder)
250 {
251 if (0 == ArgInputObjectFiles.size() &&
252 0 == ArgNameSpecList.size() &&
253 !m_Config.bitcode().hasDefined()) {
254 fatal(diag::err_no_inputs);
255 return;
256 }
257
258 size_t num_actions = ArgInputObjectFiles.size() +
259 ArgNameSpecList.size() +
260 ArgWholeArchiveList.size() +
261 ArgNoWholeArchiveList.size() +
262 ArgAsNeededList.size() +
263 ArgNoAsNeededList.size() +
264 ArgAddNeededList.size() +
265 ArgNoAddNeededList.size() +
266 ArgBDynamicList.size() +
267 ArgBStaticList.size() +
268 ArgStartGroupList.size() +
269 ArgEndGroupList.size() +
270 ArgDefSymList.size() +
271 1; // bitcode
272 std::vector<InputAction*> actions;
273 actions.reserve(num_actions);
274
275 // ----- scripts ----- //
276 /// -T
277 if (!m_Config.options().getScriptList().empty()) {
278 GeneralOptions::const_script_iterator ii, ie = m_Config.options().script_end();
279 for (ii = m_Config.options().script_begin(); ii != ie; ++ii) {
280 actions.push_back(new ScriptAction(0x0,
281 *ii,
282 ScriptFile::LDScript,
283 m_Module.getScript().directories()));
284 actions.push_back(new ContextAction(0x0));
285 actions.push_back(new MemoryAreaAction(0x0, FileHandle::ReadOnly));
286 }
287 }
288
289 /// --defsym
290 cl::list<std::string>::iterator defsym, dsBegin, dsEnd;
291 dsBegin = ArgDefSymList.begin();
292 dsEnd = ArgDefSymList.end();
293 for (defsym = dsBegin; defsym != dsEnd; ++defsym) {
294 unsigned int pos = ArgDefSymList.getPosition(defsym - dsBegin);
295 actions.push_back(new DefSymAction(pos, *defsym));
296 }
297
298 // ----- inputs ----- //
299 cl::list<mcld::sys::fs::Path>::iterator input, inBegin, inEnd;
300 inBegin = ArgInputObjectFiles.begin();
301 inEnd = ArgInputObjectFiles.end();
302 for (input = inBegin; input != inEnd; ++input) {
303 unsigned int pos = ArgInputObjectFiles.getPosition(input - inBegin);
304 actions.push_back(new InputFileAction(pos, *input));
305 actions.push_back(new ContextAction(pos));
306 actions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly));
307 }
308
309 // ----- namespecs ----- //
310 cl::list<std::string>::iterator namespec, nsBegin, nsEnd;
311 nsBegin = ArgNameSpecList.begin();
312 nsEnd = ArgNameSpecList.end();
313 for (namespec = nsBegin; namespec != nsEnd; ++namespec) {
314 unsigned int pos = ArgNameSpecList.getPosition(namespec - nsBegin);
315 actions.push_back(new NamespecAction(pos, *namespec,
316 m_Module.getScript().directories()));
317 actions.push_back(new ContextAction(pos));
318 actions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly));
319 }
320
321 // ----- attributes ----- //
322 /// --whole-archive
323 cl::list<bool>::iterator attr, attrBegin, attrEnd;
324 attrBegin = ArgWholeArchiveList.begin();
325 attrEnd = ArgWholeArchiveList.end();
326 for (attr = attrBegin; attr != attrEnd; ++attr) {
327 unsigned int pos = ArgWholeArchiveList.getPosition(attr - attrBegin);
328 actions.push_back(new WholeArchiveAction(pos));
329 }
330
331 /// --no-whole-archive
332 attrBegin = ArgNoWholeArchiveList.begin();
333 attrEnd = ArgNoWholeArchiveList.end();
334 for (attr = attrBegin; attr != attrEnd; ++attr) {
335 unsigned int pos = ArgNoWholeArchiveList.getPosition(attr - attrBegin);
336 actions.push_back(new NoWholeArchiveAction(pos));
337 }
338
339 /// --as-needed
340 attrBegin = ArgAsNeededList.begin();
341 attrEnd = ArgAsNeededList.end();
342 for (attr = attrBegin; attr != attrEnd; ++attr) {
343 unsigned int pos = ArgAsNeededList.getPosition(attr - attrBegin);
344 actions.push_back(new AsNeededAction(pos));
345 }
346
347 /// --no-as-needed
348 attrBegin = ArgNoAsNeededList.begin();
349 attrEnd = ArgNoAsNeededList.end();
350 for (attr = attrBegin; attr != attrEnd; ++attr) {
351 unsigned int pos = ArgNoAsNeededList.getPosition(attr - attrBegin);
352 actions.push_back(new NoAsNeededAction(pos));
353 }
354
355 /// --add--needed
356 attrBegin = ArgAddNeededList.begin();
357 attrEnd = ArgAddNeededList.end();
358 for (attr = attrBegin; attr != attrEnd; ++attr) {
359 unsigned int pos = ArgAddNeededList.getPosition(attr - attrBegin);
360 actions.push_back(new AddNeededAction(pos));
361 }
362
363 /// --no-add--needed
364 attrBegin = ArgNoAddNeededList.begin();
365 attrEnd = ArgNoAddNeededList.end();
366 for (attr = attrBegin; attr != attrEnd; ++attr) {
367 unsigned int pos = ArgNoAddNeededList.getPosition(attr - attrBegin);
368 actions.push_back(new NoAddNeededAction(pos));
369 }
370
371 /// --Bdynamic
372 attrBegin = ArgBDynamicList.begin();
373 attrEnd = ArgBDynamicList.end();
374 for (attr = attrBegin; attr != attrEnd; ++attr) {
375 unsigned int pos = ArgBDynamicList.getPosition(attr - attrBegin);
376 actions.push_back(new BDynamicAction(pos));
377 }
378
379 /// --Bstatic
380 attrBegin = ArgBStaticList.begin();
381 attrEnd = ArgBStaticList.end();
382 for (attr = attrBegin; attr != attrEnd; ++attr) {
383 unsigned int pos = ArgBStaticList.getPosition(attr - attrBegin);
384 actions.push_back(new BStaticAction(pos));
385 }
386
387 // ----- groups ----- //
388 /// --start-group
389 cl::list<bool>::iterator group, gsBegin, gsEnd;
390 gsBegin = ArgStartGroupList.begin();
391 gsEnd = ArgStartGroupList.end();
392 for (group = gsBegin; group != gsEnd; ++group) {
393 unsigned int pos = ArgStartGroupList.getPosition(group - gsBegin);
394 actions.push_back(new StartGroupAction(pos));
395 }
396
397 /// --end-group
398 gsBegin = ArgEndGroupList.begin();
399 gsEnd = ArgEndGroupList.end();
400 for (group = gsBegin; group != gsEnd; ++group) {
401 unsigned int pos = ArgEndGroupList.getPosition(group - gsBegin);
402 actions.push_back(new EndGroupAction(pos));
403 }
404
405 // ----- bitcode ----- //
406 if (m_Config.bitcode().hasDefined()) {
407 actions.push_back(new BitcodeAction(m_Config.bitcode().getPosition(),
408 m_Config.bitcode().getPath()));
409 }
410
411 // stable sort
412 std::stable_sort(actions.begin(), actions.end(), CompareAction);
413
414 // build up input tree
415 std::vector<InputAction*>::iterator action, actionEnd = actions.end();
416 for (action = actions.begin(); action != actionEnd; ++action) {
417 (*action)->activate(pBuilder.getInputBuilder());
418 delete *action;
419 }
420
421 if (pBuilder.getInputBuilder().isInGroup())
422 report_fatal_error("no matched --start-group and --end-group");
423 }
424
425