• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- main.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 #include <mcld/PreferenceOptions.h>
10 #include <mcld/TripleOptions.h>
11 #include <mcld/DynamicSectionOptions.h>
12 #include <mcld/OutputFormatOptions.h>
13 #include <mcld/SearchPathOptions.h>
14 #include <mcld/OptimizationOptions.h>
15 #include <mcld/SymbolOptions.h>
16 #include <mcld/TargetControlOptions.h>
17 #include <mcld/ScriptOptions.h>
18 #include <mcld/PositionalOptions.h>
19 
20 #include <mcld/Module.h>
21 #include <mcld/Environment.h>
22 #include <mcld/LinkerConfig.h>
23 #include <mcld/LinkerScript.h>
24 #include <mcld/Linker.h>
25 #include <mcld/IRBuilder.h>
26 #include <mcld/MC/InputAction.h>
27 #include <mcld/Support/raw_ostream.h>
28 #include <mcld/Support/MsgHandling.h>
29 #include <llvm/Support/ManagedStatic.h>
30 #include <llvm/Support/Signals.h>
31 #include <string>
32 #include <cassert>
33 
34 /// configure linker
ConfigLinker(int pArgc,char * pArgv[],const char * pName,mcld::Module & pModule,mcld::LinkerScript & pScript,mcld::LinkerConfig & pConfig,mcld::IRBuilder & pBuilder,std::vector<mcld::InputAction * > & pInputActions)35 static inline bool ConfigLinker(int pArgc,
36                                 char* pArgv[],
37                                 const char* pName,
38                                 mcld::Module& pModule,
39                                 mcld::LinkerScript& pScript,
40                                 mcld::LinkerConfig& pConfig,
41                                 mcld::IRBuilder& pBuilder,
42                                 std::vector<mcld::InputAction*>& pInputActions)
43 {
44   mcld::PreferenceOptions     preference;
45   mcld::TripleOptions         triple;
46   mcld::DynamicSectionOptions dynamic_section;
47   mcld::OutputFormatOptions   output_format;
48   mcld::SearchPathOptions     search_path;
49   mcld::OptimizationOptions   optimization;
50   mcld::SymbolOptions         symbol;
51   mcld::TargetControlOptions  target_control;
52   mcld::ScriptOptions         script;
53   mcld::PositionalOptions     positional;
54 
55   llvm::cl::ParseCommandLineOptions(pArgc, pArgv, pName);
56 
57   if (!preference.parse(pConfig))
58     return false;
59 
60   if (!triple.parse(pArgc, pArgv, pConfig))
61     return false;
62 
63   if (!dynamic_section.parse(pConfig, pScript))
64     return false;
65 
66   if (!output_format.parse(pModule, pConfig))
67     return false;
68 
69   if (!search_path.parse(pConfig, pScript))
70     return false;
71 
72   if (!optimization.parse(pConfig))
73     return false;
74 
75   if (!symbol.parse(pConfig))
76     return false;
77 
78   if (!target_control.parse(pConfig))
79     return false;
80 
81   if (!script.parse(pScript))
82     return false;
83 
84   if (!positional.parse(pInputActions, pConfig, pScript))
85     return false;
86 
87   if (pConfig.options().soname().empty())
88     pConfig.options().setSOName(pModule.name());
89 
90   return true;
91 }
92 
93 static
InitializeInputs(mcld::IRBuilder & pBuilder,std::vector<mcld::InputAction * > & pInputActions)94 inline bool InitializeInputs(mcld::IRBuilder& pBuilder,
95                              std::vector<mcld::InputAction*>& pInputActions)
96 {
97   for (std::vector<mcld::InputAction*>::iterator action = pInputActions.begin(),
98     actionEnd = pInputActions.end(); action != actionEnd; ++action) {
99     assert(*action != NULL);
100     (*action)->activate(pBuilder.getInputBuilder());
101     delete *action;
102   }
103 
104   if (pBuilder.getInputBuilder().isInGroup()) {
105     mcld::fatal(mcld::diag::fatal_forbid_nest_group);
106     return false;
107   }
108 
109   return true;
110 }
111 
main(int argc,char * argv[])112 int main(int argc, char* argv[])
113 {
114   llvm::sys::PrintStackTraceOnErrorSignal();
115   llvm::llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
116   mcld::Initialize();
117 
118   mcld::LinkerScript script;
119   mcld::LinkerConfig config;
120   mcld::Module module(script);
121   mcld::IRBuilder builder(module, config);
122   std::vector<mcld::InputAction*> input_actions;
123 
124   if (!ConfigLinker(argc, argv, "MCLinker\n", module, script, config, builder,
125                     input_actions)) {
126     mcld::errs() << argv[0]
127                  << ": failed to process linker options from command line!\n";
128     return 1;
129   }
130 
131   mcld::Linker linker;
132   if (!linker.emulate(script, config)) {
133     mcld::errs() << argv[0]
134                  << ": failed to emulate target!\n";
135     return 1;
136   }
137 
138   // FIXME: is it possible to have a lightweight MCLinker pass?
139   if (!InitializeInputs(builder, input_actions)) {
140     mcld::errs() << argv[0]
141                  << ": failed to initialize input tree!\n";
142     return 1;
143   }
144 
145   if (!linker.link(module, builder)) {
146     mcld::errs() << argv[0]
147                  << ": failed to link objects!\n";
148     return 1;
149   }
150 
151   if (!linker.emit(module, module.name())) {
152     mcld::errs() << argv[0]
153                  << ": failed to emit output!\n";
154     return 1;
155   }
156 
157   mcld::Finalize();
158 
159   return 0;
160 }
161