MCLinker.cpp revision f33f6de54db174aa679a4b6d1e040d37e95541c0
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
38using namespace mcld;
39using namespace llvm;
40
41char MCLinker::m_ID = 0;
42
43//===----------------------------------------------------------------------===//
44// Help Functions
45//===----------------------------------------------------------------------===//
46static 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//===----------------------------------------------------------------------===//
67static cl::list<mcld::sys::fs::Path>
68ArgInputObjectFiles(cl::Positional,
69                    cl::desc("[input object files]"),
70                    cl::ZeroOrMore);
71
72//===----------------------------------------------------------------------===//
73// Namespecs
74//===----------------------------------------------------------------------===//
75static cl::list<std::string>
76ArgNameSpecList("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
83static cl::alias
84ArgNameSpecListAlias("library",
85                 cl::desc("alias for -l"),
86                 cl::aliasopt(ArgNameSpecList));
87
88//===----------------------------------------------------------------------===//
89// Attributes
90//===----------------------------------------------------------------------===//
91static cl::list<bool>
92ArgWholeArchiveList("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
98static cl::list<bool>
99ArgNoWholeArchiveList("no-whole-archive",
100               cl::ValueDisallowed,
101               cl::desc("Turn off the effect of the --whole-archive option for "
102                        "subsequent archive files."));
103
104static cl::list<bool>
105ArgAsNeededList("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
111static cl::list<bool>
112ArgNoAsNeededList("no-as-needed",
113               cl::ValueDisallowed,
114               cl::desc("Turn off the effect of the --as-needed option for "
115                        "subsequent dynamic libraries"));
116
117static cl::list<bool>
118ArgAddNeededList("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
124static cl::list<bool>
125ArgNoAddNeededList("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
130static cl::list<bool>
131ArgBDynamicList("Bdynamic",
132                cl::ValueDisallowed,
133                cl::desc("Link against dynamic library"));
134
135static cl::alias
136ArgBDynamicListAlias1("dy",
137                cl::desc("alias for --Bdynamic"),
138                cl::aliasopt(ArgBDynamicList));
139
140static cl::alias
141ArgBDynamicListAlias2("call_shared",
142                cl::desc("alias for --Bdynamic"),
143                cl::aliasopt(ArgBDynamicList));
144
145static cl::list<bool>
146ArgBStaticList("Bstatic",
147                cl::ValueDisallowed,
148                cl::desc("Link against static library"));
149
150static cl::alias
151ArgBStaticListAlias1("dn",
152                cl::desc("alias for --Bstatic"),
153                cl::aliasopt(ArgBStaticList));
154
155static cl::alias
156ArgBStaticListAlias2("static",
157                cl::desc("alias for --Bstatic"),
158                cl::aliasopt(ArgBStaticList));
159
160static cl::alias
161ArgBStaticListAlias3("non_shared",
162                cl::desc("alias for --Bstatic"),
163                cl::aliasopt(ArgBStaticList));
164
165//===----------------------------------------------------------------------===//
166// Groups
167//===----------------------------------------------------------------------===//
168static cl::list<bool>
169ArgStartGroupList("start-group",
170                  cl::ValueDisallowed,
171                  cl::desc("start to record a group of archives"));
172
173static cl::alias
174ArgStartGroupListAlias("(",
175                       cl::desc("alias for --start-group"),
176                       cl::aliasopt(ArgStartGroupList));
177
178static cl::list<bool>
179ArgEndGroupList("end-group",
180                cl::ValueDisallowed,
181                cl::desc("stop recording a group of archives"));
182
183static cl::alias
184ArgEndGroupListAlias(")",
185                     cl::desc("alias for --end-group"),
186                     cl::aliasopt(ArgEndGroupList));
187
188//===----------------------------------------------------------------------===//
189// --defsym
190//===----------------------------------------------------------------------===//
191static cl::list<std::string>
192ArgDefSymList("defsym",
193              cl::ZeroOrMore,
194              cl::desc("Define a symbol"),
195              cl::value_desc("symbol=expression"));
196
197//===----------------------------------------------------------------------===//
198// MCLinker
199//===----------------------------------------------------------------------===//
200MCLinker::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
211MCLinker::~MCLinker()
212{
213  delete m_pLinker;
214  delete m_pBuilder;
215}
216
217bool 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
232bool 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
243bool MCLinker::runOnMachineFunction(MachineFunction& pF)
244{
245  // basically, linkers do nothing during function is generated.
246  return false;
247}
248
249void 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