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/InputTree.h>
18 #include <mcld/Linker.h>
19 #include <mcld/IRBuilder.h>
20 #include <mcld/MC/InputBuilder.h>
21 #include <mcld/MC/FileAction.h>
22 #include <mcld/MC/CommandAction.h>
23 #include <mcld/Object/ObjectLinker.h>
24 #include <mcld/Support/CommandLine.h>
25 #include <mcld/Support/FileSystem.h>
26 #include <mcld/Support/MsgHandling.h>
27 #include <mcld/Support/FileHandle.h>
28 #include <mcld/Support/raw_ostream.h>
29 #include <mcld/Support/MemoryArea.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 // MCLinker
190 //===----------------------------------------------------------------------===//
MCLinker(LinkerConfig & pConfig,mcld::Module & pModule,MemoryArea & pOutput)191 MCLinker::MCLinker(LinkerConfig& pConfig,
192 mcld::Module& pModule,
193 MemoryArea& pOutput)
194 : MachineFunctionPass(m_ID),
195 m_Config(pConfig),
196 m_Module(pModule),
197 m_Output(pOutput),
198 m_pBuilder(NULL),
199 m_pLinker(NULL) {
200 }
201
~MCLinker()202 MCLinker::~MCLinker()
203 {
204 delete m_pLinker;
205 delete m_pBuilder;
206 }
207
doInitialization(llvm::Module & pM)208 bool MCLinker::doInitialization(llvm::Module &pM)
209 {
210 // Now, all input arguments are prepared well, send it into ObjectLinker
211 m_pLinker = new Linker();
212
213 if (!m_pLinker->config(m_Config))
214 return false;
215
216 m_pBuilder = new IRBuilder(m_Module, m_Config);
217
218 initializeInputTree(*m_pBuilder);
219
220 return true;
221 }
222
doFinalization(llvm::Module & pM)223 bool MCLinker::doFinalization(llvm::Module &pM)
224 {
225 if (!m_pLinker->link(m_Module, *m_pBuilder))
226 return true;
227
228 if (!m_pLinker->emit(m_Output))
229 return true;
230
231 return false;
232 }
233
runOnMachineFunction(MachineFunction & pF)234 bool MCLinker::runOnMachineFunction(MachineFunction& pF)
235 {
236 // basically, linkers do nothing during function is generated.
237 return false;
238 }
239
initializeInputTree(IRBuilder & pBuilder)240 void MCLinker::initializeInputTree(IRBuilder& pBuilder)
241 {
242 if (0 == ArgInputObjectFiles.size() &&
243 0 == ArgNameSpecList.size() &&
244 !m_Config.bitcode().hasDefined()) {
245 fatal(diag::err_no_inputs);
246 return;
247 }
248
249 size_t num_actions = ArgInputObjectFiles.size() +
250 ArgNameSpecList.size() +
251 ArgWholeArchiveList.size() +
252 ArgNoWholeArchiveList.size() +
253 ArgAsNeededList.size() +
254 ArgNoAsNeededList.size() +
255 ArgAddNeededList.size() +
256 ArgNoAddNeededList.size() +
257 ArgBDynamicList.size() +
258 ArgBStaticList.size() +
259 ArgStartGroupList.size() +
260 ArgEndGroupList.size() +
261 1; // bitcode
262 std::vector<InputAction*> actions;
263 actions.reserve(num_actions);
264
265 // ----- inputs ----- //
266 cl::list<mcld::sys::fs::Path>::iterator input, inBegin, inEnd;
267 inBegin = ArgInputObjectFiles.begin();
268 inEnd = ArgInputObjectFiles.end();
269 for (input = inBegin; input != inEnd; ++input) {
270 unsigned int pos = ArgInputObjectFiles.getPosition(input - inBegin);
271 actions.push_back(new InputFileAction(pos, *input));
272 actions.push_back(new ContextAction(pos));
273 actions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly));
274 }
275
276 // ----- namespecs ----- //
277 cl::list<std::string>::iterator namespec, nsBegin, nsEnd;
278 nsBegin = ArgNameSpecList.begin();
279 nsEnd = ArgNameSpecList.end();
280 for (namespec = nsBegin; namespec != nsEnd; ++namespec) {
281 unsigned int pos = ArgNameSpecList.getPosition(namespec - nsBegin);
282 actions.push_back(new NamespecAction(pos, *namespec,
283 m_Config.options().directories()));
284 actions.push_back(new ContextAction(pos));
285 actions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly));
286 }
287
288 // ----- attributes ----- //
289 /// --whole-archive
290 cl::list<bool>::iterator attr, attrBegin, attrEnd;
291 attrBegin = ArgWholeArchiveList.begin();
292 attrEnd = ArgWholeArchiveList.end();
293 for (attr = attrBegin; attr != attrEnd; ++attr) {
294 unsigned int pos = ArgWholeArchiveList.getPosition(attr - attrBegin);
295 actions.push_back(new WholeArchiveAction(pos));
296 }
297
298 /// --no-whole-archive
299 attrBegin = ArgNoWholeArchiveList.begin();
300 attrEnd = ArgNoWholeArchiveList.end();
301 for (attr = attrBegin; attr != attrEnd; ++attr) {
302 unsigned int pos = ArgNoWholeArchiveList.getPosition(attr - attrBegin);
303 actions.push_back(new NoWholeArchiveAction(pos));
304 }
305
306 /// --as-needed
307 attrBegin = ArgAsNeededList.begin();
308 attrEnd = ArgAsNeededList.end();
309 for (attr = attrBegin; attr != attrEnd; ++attr) {
310 unsigned int pos = ArgAsNeededList.getPosition(attr - attrBegin);
311 actions.push_back(new AsNeededAction(pos));
312 }
313
314 /// --no-as-needed
315 attrBegin = ArgNoAsNeededList.begin();
316 attrEnd = ArgNoAsNeededList.end();
317 for (attr = attrBegin; attr != attrEnd; ++attr) {
318 unsigned int pos = ArgNoAsNeededList.getPosition(attr - attrBegin);
319 actions.push_back(new NoAsNeededAction(pos));
320 }
321
322 /// --add--needed
323 attrBegin = ArgAddNeededList.begin();
324 attrEnd = ArgAddNeededList.end();
325 for (attr = attrBegin; attr != attrEnd; ++attr) {
326 unsigned int pos = ArgAddNeededList.getPosition(attr - attrBegin);
327 actions.push_back(new AddNeededAction(pos));
328 }
329
330 /// --no-add--needed
331 attrBegin = ArgNoAddNeededList.begin();
332 attrEnd = ArgNoAddNeededList.end();
333 for (attr = attrBegin; attr != attrEnd; ++attr) {
334 unsigned int pos = ArgNoAddNeededList.getPosition(attr - attrBegin);
335 actions.push_back(new NoAddNeededAction(pos));
336 }
337
338 /// --Bdynamic
339 attrBegin = ArgBDynamicList.begin();
340 attrEnd = ArgBDynamicList.end();
341 for (attr = attrBegin; attr != attrEnd; ++attr) {
342 unsigned int pos = ArgBDynamicList.getPosition(attr - attrBegin);
343 actions.push_back(new BDynamicAction(pos));
344 }
345
346 /// --Bstatic
347 attrBegin = ArgBStaticList.begin();
348 attrEnd = ArgBStaticList.end();
349 for (attr = attrBegin; attr != attrEnd; ++attr) {
350 unsigned int pos = ArgBStaticList.getPosition(attr - attrBegin);
351 actions.push_back(new BStaticAction(pos));
352 }
353
354 // ----- groups ----- //
355 /// --start-group
356 cl::list<bool>::iterator group, gsBegin, gsEnd;
357 gsBegin = ArgStartGroupList.begin();
358 gsEnd = ArgStartGroupList.end();
359 for (group = gsBegin; group != gsEnd; ++group) {
360 unsigned int pos = ArgStartGroupList.getPosition(group - gsBegin);
361 actions.push_back(new StartGroupAction(pos));
362 }
363
364 /// --end-group
365 gsBegin = ArgEndGroupList.begin();
366 gsEnd = ArgEndGroupList.end();
367 for (group = gsBegin; group != gsEnd; ++group) {
368 unsigned int pos = ArgEndGroupList.getPosition(group - gsBegin);
369 actions.push_back(new EndGroupAction(pos));
370 }
371
372 // ----- bitcode ----- //
373 if (m_Config.bitcode().hasDefined()) {
374 actions.push_back(new BitcodeAction(m_Config.bitcode().getPosition(),
375 m_Config.bitcode().getPath()));
376 }
377
378 // stable sort
379 std::stable_sort(actions.begin(), actions.end(), CompareAction);
380
381 // build up input tree
382 std::vector<InputAction*>::iterator action, actionEnd = actions.end();
383 for (action = actions.begin(); action != actionEnd; ++action) {
384 (*action)->activate(pBuilder.getInputBuilder());
385 delete *action;
386 }
387
388 if (pBuilder.getInputBuilder().isInGroup())
389 report_fatal_error("no matched --start-group and --end-group");
390 }
391
392