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