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
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// MCLinker
190//===----------------------------------------------------------------------===//
191MCLinker::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
202MCLinker::~MCLinker()
203{
204  delete m_pLinker;
205  delete m_pBuilder;
206}
207
208bool 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->emulate(m_Module.getScript(), 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
223bool 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
234bool MCLinker::runOnMachineFunction(MachineFunction& pF)
235{
236  // basically, linkers do nothing during function is generated.
237  return false;
238}
239
240void 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  mcld::Module& module = pBuilder.getModule();
281  for (namespec = nsBegin; namespec != nsEnd; ++namespec) {
282    unsigned int pos = ArgNameSpecList.getPosition(namespec - nsBegin);
283    actions.push_back(new NamespecAction(pos, *namespec,
284                                         module.getScript().directories()));
285    actions.push_back(new ContextAction(pos));
286    actions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly));
287  }
288
289  // -----  attributes  ----- //
290  /// --whole-archive
291  cl::list<bool>::iterator attr, attrBegin, attrEnd;
292  attrBegin = ArgWholeArchiveList.begin();
293  attrEnd   = ArgWholeArchiveList.end();
294  for (attr = attrBegin; attr != attrEnd; ++attr) {
295    unsigned int pos = ArgWholeArchiveList.getPosition(attr - attrBegin);
296    actions.push_back(new WholeArchiveAction(pos));
297  }
298
299  /// --no-whole-archive
300  attrBegin = ArgNoWholeArchiveList.begin();
301  attrEnd   = ArgNoWholeArchiveList.end();
302  for (attr = attrBegin; attr != attrEnd; ++attr) {
303    unsigned int pos = ArgNoWholeArchiveList.getPosition(attr - attrBegin);
304    actions.push_back(new NoWholeArchiveAction(pos));
305  }
306
307  /// --as-needed
308  attrBegin = ArgAsNeededList.begin();
309  attrEnd   = ArgAsNeededList.end();
310  for (attr = attrBegin; attr != attrEnd; ++attr) {
311    unsigned int pos = ArgAsNeededList.getPosition(attr - attrBegin);
312    actions.push_back(new AsNeededAction(pos));
313  }
314
315  /// --no-as-needed
316  attrBegin = ArgNoAsNeededList.begin();
317  attrEnd   = ArgNoAsNeededList.end();
318  for (attr = attrBegin; attr != attrEnd; ++attr) {
319    unsigned int pos = ArgNoAsNeededList.getPosition(attr - attrBegin);
320    actions.push_back(new NoAsNeededAction(pos));
321  }
322
323  /// --add--needed
324  attrBegin = ArgAddNeededList.begin();
325  attrEnd   = ArgAddNeededList.end();
326  for (attr = attrBegin; attr != attrEnd; ++attr) {
327    unsigned int pos = ArgAddNeededList.getPosition(attr - attrBegin);
328    actions.push_back(new AddNeededAction(pos));
329  }
330
331  /// --no-add--needed
332  attrBegin = ArgNoAddNeededList.begin();
333  attrEnd   = ArgNoAddNeededList.end();
334  for (attr = attrBegin; attr != attrEnd; ++attr) {
335    unsigned int pos = ArgNoAddNeededList.getPosition(attr - attrBegin);
336    actions.push_back(new NoAddNeededAction(pos));
337  }
338
339  /// --Bdynamic
340  attrBegin = ArgBDynamicList.begin();
341  attrEnd   = ArgBDynamicList.end();
342  for (attr = attrBegin; attr != attrEnd; ++attr) {
343    unsigned int pos = ArgBDynamicList.getPosition(attr - attrBegin);
344    actions.push_back(new BDynamicAction(pos));
345  }
346
347  /// --Bstatic
348  attrBegin = ArgBStaticList.begin();
349  attrEnd   = ArgBStaticList.end();
350  for (attr = attrBegin; attr != attrEnd; ++attr) {
351    unsigned int pos = ArgBStaticList.getPosition(attr - attrBegin);
352    actions.push_back(new BStaticAction(pos));
353  }
354
355  // -----  groups  ----- //
356  /// --start-group
357  cl::list<bool>::iterator group, gsBegin, gsEnd;
358  gsBegin = ArgStartGroupList.begin();
359  gsEnd   = ArgStartGroupList.end();
360  for (group = gsBegin; group != gsEnd; ++group) {
361    unsigned int pos = ArgStartGroupList.getPosition(group - gsBegin);
362    actions.push_back(new StartGroupAction(pos));
363  }
364
365  /// --end-group
366  gsBegin = ArgEndGroupList.begin();
367  gsEnd   = ArgEndGroupList.end();
368  for (group = gsBegin; group != gsEnd; ++group) {
369    unsigned int pos = ArgEndGroupList.getPosition(group - gsBegin);
370    actions.push_back(new EndGroupAction(pos));
371  }
372
373  // -----  bitcode  ----- //
374  if (m_Config.bitcode().hasDefined()) {
375    actions.push_back(new BitcodeAction(m_Config.bitcode().getPosition(),
376                                        m_Config.bitcode().getPath()));
377  }
378
379  // stable sort
380  std::stable_sort(actions.begin(), actions.end(), CompareAction);
381
382  // build up input tree
383  std::vector<InputAction*>::iterator action, actionEnd = actions.end();
384  for (action = actions.begin(); action != actionEnd; ++action) {
385    (*action)->activate(pBuilder.getInputBuilder());
386    delete *action;
387  }
388
389  if (pBuilder.getInputBuilder().isInGroup())
390    report_fatal_error("no matched --start-group and --end-group");
391}
392
393