1533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines//===- main.cpp -----------------------------------------------------------===//
2affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//
3affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//                     The MCLinker Project
4affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//
5affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// This file is distributed under the University of Illinois Open Source
6affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// License. See LICENSE.TXT for details.
7affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//
8affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===//
9533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <mcld/PreferenceOptions.h>
10533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <mcld/TripleOptions.h>
11533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <mcld/DynamicSectionOptions.h>
12533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <mcld/OutputFormatOptions.h>
13533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <mcld/SearchPathOptions.h>
14533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <mcld/OptimizationOptions.h>
15533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <mcld/SymbolOptions.h>
16533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <mcld/TargetControlOptions.h>
17533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <mcld/ScriptOptions.h>
18533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <mcld/PositionalOptions.h>
19533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
2087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Module.h>
21533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <mcld/Environment.h>
2287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LinkerConfig.h>
2387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/LinkerScript.h>
24533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <mcld/Linker.h>
25533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <mcld/IRBuilder.h>
26533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <mcld/MC/InputAction.h>
2787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Support/raw_ostream.h>
28533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <mcld/Support/MsgHandling.h>
2987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/ManagedStatic.h>
3087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/Signals.h>
31533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <string>
32533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines#include <cassert>
33533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
34533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines/// configure linker
35533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hinesstatic inline bool ConfigLinker(int pArgc,
36533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines                                char* pArgv[],
37533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines                                const char* pName,
38533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines                                mcld::Module& pModule,
39533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines                                mcld::LinkerScript& pScript,
40533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines                                mcld::LinkerConfig& pConfig,
41533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines                                mcld::IRBuilder& pBuilder,
42533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines                                std::vector<mcld::InputAction*>& pInputActions)
4387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
44533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  mcld::PreferenceOptions     preference;
45533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  mcld::TripleOptions         triple;
46533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  mcld::DynamicSectionOptions dynamic_section;
47533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  mcld::OutputFormatOptions   output_format;
48533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  mcld::SearchPathOptions     search_path;
49533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  mcld::OptimizationOptions   optimization;
50533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  mcld::SymbolOptions         symbol;
51533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  mcld::TargetControlOptions  target_control;
52533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  mcld::ScriptOptions         script;
53533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  mcld::PositionalOptions     positional;
5487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
55533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::cl::ParseCommandLineOptions(pArgc, pArgv, pName);
5687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
57533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  if (!preference.parse(pConfig))
58533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    return false;
5987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
60533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  if (!triple.parse(pArgc, pArgv, pConfig))
61533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    return false;
6287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
63533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  if (!dynamic_section.parse(pConfig, pScript))
64533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    return false;
6587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
66533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  if (!output_format.parse(pModule, pConfig))
67533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    return false;
6887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
69533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  if (!search_path.parse(pConfig, pScript))
70533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    return false;
7187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
72533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  if (!optimization.parse(pConfig))
73533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    return false;
7487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
75533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  if (!symbol.parse(pConfig))
76533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    return false;
7787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
78533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  if (!target_control.parse(pConfig))
79533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    return false;
8087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
81533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  if (!script.parse(pScript))
82533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    return false;
8387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
84533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  if (!positional.parse(pInputActions, pConfig, pScript))
85533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    return false;
8687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
87533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  if (pConfig.options().soname().empty())
88533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    pConfig.options().setSOName(pModule.name());
8987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
90533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  return true;
9187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
92affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
93533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hinesstatic
94533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hinesinline bool InitializeInputs(mcld::IRBuilder& pBuilder,
95533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines                             std::vector<mcld::InputAction*>& pInputActions)
9687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
97533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  for (std::vector<mcld::InputAction*>::iterator action = pInputActions.begin(),
98533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    actionEnd = pInputActions.end(); action != actionEnd; ++action) {
99533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    assert(*action != NULL);
100533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    (*action)->activate(pBuilder.getInputBuilder());
101533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    delete *action;
102cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  }
103cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
104533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  if (pBuilder.getInputBuilder().isInGroup()) {
105533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    mcld::fatal(mcld::diag::fatal_forbid_nest_group);
106533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    return false;
107cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  }
108affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
109affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return true;
110affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
111affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
11287f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesint main(int argc, char* argv[])
11387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines{
114533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::sys::PrintStackTraceOnErrorSignal();
115533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  llvm::llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
116533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  mcld::Initialize();
117533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
118533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  mcld::LinkerScript script;
119533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  mcld::LinkerConfig config;
120533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  mcld::Module module(script);
121533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  mcld::IRBuilder builder(module, config);
122533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  std::vector<mcld::InputAction*> input_actions;
123533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines
124533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  if (!ConfigLinker(argc, argv, "MCLinker\n", module, script, config, builder,
125533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines                    input_actions)) {
126533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    mcld::errs() << argv[0]
127533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines                 << ": failed to process linker options from command line!\n";
12887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return 1;
12987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
130cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
131533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  mcld::Linker linker;
132533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  if (!linker.emulate(script, config)) {
133533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    mcld::errs() << argv[0]
134533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines                 << ": failed to emulate target!\n";
13587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return 1;
13687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
13787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
138533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  // FIXME: is it possible to have a lightweight MCLinker pass?
139533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  if (!InitializeInputs(builder, input_actions)) {
140533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    mcld::errs() << argv[0]
141533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines                 << ": failed to initialize input tree!\n";
14287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return 1;
143affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
144affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
145533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  if (!linker.link(module, builder)) {
146533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    mcld::errs() << argv[0]
147533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines                 << ": failed to link objects!\n";
14887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return 1;
149affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
150affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
151533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  if (!linker.emit(module, module.name())) {
152533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines    mcld::errs() << argv[0]
153533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines                 << ": failed to emit output!\n";
15487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return 1;
155affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
156affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
157533eae20118036f425f27bf0536ef0ccbb090b65Stephen Hines  mcld::Finalize();
158affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
15987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return 0;
16087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
161