main.cpp revision affc150dc44fab1911775a49636d0ce85333b634
1affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===- mcld.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//===----------------------------------------------------------------------===// 9affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <stdlib.h> 10affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <string> 11affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 12affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <llvm/ADT/SmallString.h> 13affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <llvm/Support/CommandLine.h> 14affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <llvm/Support/FileSystem.h> 15affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <llvm/Support/Path.h> 16affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <llvm/Support/raw_ostream.h> 17affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <llvm/Support/system_error.h> 18affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 19affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <alone/Config/Config.h> 20affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <alone/Support/LinkerConfig.h> 21affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <alone/Support/Initialization.h> 22affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <alone/Support/TargetLinkerConfigs.h> 23affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <alone/Linker.h> 24affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 25affc150dc44fab1911775a49636d0ce85333b634Zonr Changusing namespace alone; 26affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 27affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===// 28affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// Compiler Options 29affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===// 30affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#ifdef TARGET_BUILD 31affc150dc44fab1911775a49636d0ce85333b634Zonr Changconst std::string OptTargetTripe(DEFAULT_TARGET_TRIPLE_STRING); 32affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#else 33affc150dc44fab1911775a49636d0ce85333b634Zonr Changllvm::cl::opt<std::string> 34affc150dc44fab1911775a49636d0ce85333b634Zonr ChangOptTargetTriple("mtriple", 35affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::desc("Specify the target triple (default: " 36affc150dc44fab1911775a49636d0ce85333b634Zonr Chang DEFAULT_TARGET_TRIPLE_STRING ")"), 37affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::init(DEFAULT_TARGET_TRIPLE_STRING), 38affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::value_desc("triple")); 39affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 40affc150dc44fab1911775a49636d0ce85333b634Zonr Changllvm::cl::alias OptTargetTripleC("C", llvm::cl::NotHidden, 41affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::desc("Alias for -mtriple"), 42affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::aliasopt(OptTargetTriple)); 43affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#endif 44affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 45affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===// 46affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// Command Line Options 47affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// There are four kinds of command line options: 48affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// 1. input, (may be a file, such as -m and /tmp/XXXX.o.) 49affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// 2. scripting options, (represent a subset of link scripting language, such 50affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// as --defsym.) 51affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// 3. and general options. (the rest of options) 52affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===// 53affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// General Options 54affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===// 55affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic llvm::cl::opt<std::string> 56affc150dc44fab1911775a49636d0ce85333b634Zonr ChangOptOutputFilename("o", 57affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::desc("Output filename"), 58affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::value_desc("filename")); 59affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 60affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic llvm::cl::opt<std::string> 61affc150dc44fab1911775a49636d0ce85333b634Zonr ChangOptSysRoot("sysroot", 62affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::desc("Use directory as the location of the sysroot, overriding " 63affc150dc44fab1911775a49636d0ce85333b634Zonr Chang "the configure-time default."), 64affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::value_desc("directory"), 65affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::ValueRequired); 66affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 67affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic llvm::cl::list<std::string> 68affc150dc44fab1911775a49636d0ce85333b634Zonr ChangOptSearchDirList("L", 69affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::ZeroOrMore, 70affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::desc("Add path searchdir to the list of paths that ld will " 71affc150dc44fab1911775a49636d0ce85333b634Zonr Chang "search for archive libraries and ld control scripts."), 72affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::value_desc("searchdir"), 73affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::Prefix); 74affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 75affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic llvm::cl::opt<std::string> 76affc150dc44fab1911775a49636d0ce85333b634Zonr ChangOptSOName("soname", 77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::desc("Set internal name of shared library"), 78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::value_desc("name")); 79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 81affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic llvm::cl::opt<bool> 82affc150dc44fab1911775a49636d0ce85333b634Zonr ChangOptShared("shared", 83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::desc("Create a shared library."), 84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::init(false)); 85affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 86affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic llvm::cl::opt<std::string> 87affc150dc44fab1911775a49636d0ce85333b634Zonr ChangOptDyld("dynamic-linker", 88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::desc("Set the name of the dynamic linker."), 89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::value_desc("Program")); 90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 91affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===// 92affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// Inputs 93affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===// 94affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic llvm::cl::list<std::string> 95affc150dc44fab1911775a49636d0ce85333b634Zonr ChangOptInputObjectFiles(llvm::cl::Positional, 96affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::desc("[input object files]"), 97affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::ZeroOrMore); 98affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 99affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic llvm::cl::list<std::string> 100affc150dc44fab1911775a49636d0ce85333b634Zonr ChangOptNameSpecList("l", 101affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::ZeroOrMore, 102affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::desc("Add the archive or object file specified by " 103affc150dc44fab1911775a49636d0ce85333b634Zonr Chang "namespec to the list of files to link."), 104affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::value_desc("namespec"), 105affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::Prefix); 106affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 107affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===// 108affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// Scripting Options 109affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===// 110affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic llvm::cl::list<std::string> 111affc150dc44fab1911775a49636d0ce85333b634Zonr ChangOptWrapList("wrap", 112affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::ZeroOrMore, 113affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::desc("Use a wrap function fo symbol."), 114affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::value_desc("symbol")); 115affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 116affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===// 117affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// Helper Functions 118affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===// 119affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// Override "mcld -version" 120affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid MCLDVersionPrinter() { 121affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::raw_ostream &os = llvm::outs(); 122affc150dc44fab1911775a49636d0ce85333b634Zonr Chang os << "mcld (The MCLinker Project, http://mclinker.googlecode.com/):\n" 123affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << " Default target: " << DEFAULT_TARGET_TRIPLE_STRING << "\n"; 124affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 125affc150dc44fab1911775a49636d0ce85333b634Zonr Chang os << "\n"; 126affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 127affc150dc44fab1911775a49636d0ce85333b634Zonr Chang os << "LLVM (http://llvm.org/):\n"; 128affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return; 129affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 130affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 131affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#define DEFAULT_OUTPUT_PATH "a.out" 132affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic inline 133affc150dc44fab1911775a49636d0ce85333b634Zonr Changstd::string DetermineOutputFilename(const std::string pOutputPath) 134affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 135affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!pOutputPath.empty()) { 136affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return pOutputPath; 137affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 139affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // User does't specify the value to -o 140affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (OptInputObjectFiles.size() > 1) { 141affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::errs() << "Use " DEFAULT_OUTPUT_PATH " for output file!\n"; 142affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return DEFAULT_OUTPUT_PATH; 143affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 144affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 145affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // There's only one input file 146affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const std::string &input_path = OptInputObjectFiles[0]; 147affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::SmallString<200> output_path(input_path); 148affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 149affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::error_code err = llvm::sys::fs::make_absolute(output_path); 150affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (llvm::errc::success != err) { 151affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::errs() << "Failed to determine the absolute path of `" << input_path 152affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << "'! (detail: " << err.message() << ")\n"; 153affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return ""; 154affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 155affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 156affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::sys::path::remove_filename(output_path); 157affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::sys::path::append(output_path, "a.out"); 158affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 159affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return output_path.c_str(); 160affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 161affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 162affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic inline 163affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool ConfigLinker(Linker &pLinker, const std::string &pOutputFilename) 164affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 165affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LinkerConfig* config = NULL; 166affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 167affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#ifdef TARGET_BUILD 168affc150dc44fab1911775a49636d0ce85333b634Zonr Chang config = new (std::nothrow) DefaultLinkerConfig(); 169affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#else 170affc150dc44fab1911775a49636d0ce85333b634Zonr Chang config = new (std::nothrow) LinkerConfig(OptTargetTriple); 171affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#endif 172affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (config == NULL) { 173affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::errs() << "Out of memory when create the linker configuration!\n"; 174affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 175affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 176affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 177affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Setup the configuration accroding to the value of command line options. 178affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 1. set up soname 179affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!OptSOName.empty()) 180affc150dc44fab1911775a49636d0ce85333b634Zonr Chang config->setSOName(OptSOName); 181affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 182affc150dc44fab1911775a49636d0ce85333b634Zonr Chang config->setSOName(pOutputFilename); 183affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 184affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 2. if given, set up sysroot 185affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!OptSysRoot.empty()) 186affc150dc44fab1911775a49636d0ce85333b634Zonr Chang config->setSysRoot(OptSysRoot); 187affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 188affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 3. if given, set up dynamic linker path. 189affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!OptDyld.empty()) 190affc150dc44fab1911775a49636d0ce85333b634Zonr Chang config->setDyld(OptDyld); 191affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 192affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 4. if given, set up wrapped symbols 193affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::list<std::string>::iterator wrap, wEnd = OptWrapList.end(); 194affc150dc44fab1911775a49636d0ce85333b634Zonr Chang for (wrap = OptWrapList.begin(); wrap != wEnd; ++wrap) 195affc150dc44fab1911775a49636d0ce85333b634Zonr Chang config->addWrap(*wrap); 196affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 197affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // 5. if given, set up search directories 198affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::list<std::string>::iterator sdir, sdirEnd = OptSearchDirList.end(); 199affc150dc44fab1911775a49636d0ce85333b634Zonr Chang for (sdir = OptSearchDirList.begin(); sdir != sdirEnd; ++sdir) 200affc150dc44fab1911775a49636d0ce85333b634Zonr Chang config->addSearchDir(*sdir); 201affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 202affc150dc44fab1911775a49636d0ce85333b634Zonr Chang Linker::ErrorCode result = pLinker.config(*config); 203affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 204affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (Linker::kSuccess != result) { 205affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::errs() << "Failed to configure the linker! (detail: " 206affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << Linker::GetErrorString(result) << ")\n"; 207affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 208affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 209affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 210affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 211affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 212affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 213affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic inline 214affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool PrepareInputOutput(Linker& pLinker, const std::string &pOutputPath) 215affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 216affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- set output ----- // 217affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: In MCLinker, we have to set up output before setting up inputs. 218affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // This constraint is wired, and we should break this constraint. 219affc150dc44fab1911775a49636d0ce85333b634Zonr Chang Linker::ErrorCode result = pLinker.setOutput(pOutputPath); 220affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 221affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (Linker::kSuccess != result) { 222affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::errs() << "Failed to open the output file! (detail: " 223affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pOutputPath << ": " 224affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << Linker::GetErrorString(result) << ")\n"; 225affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 226affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 227affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 228affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ----- set inputs ----- // 229affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::list<std::string>::iterator fileIt = OptInputObjectFiles.begin(); 230affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::list<std::string>::iterator libIt = OptNameSpecList.begin(); 231affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 232affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::list<std::string>::iterator fileBegin = OptInputObjectFiles.begin(); 233affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::list<std::string>::iterator libBegin = OptNameSpecList.begin(); 234affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::list<std::string>::iterator fileEnd = OptInputObjectFiles.end(); 235affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::list<std::string>::iterator libEnd = OptNameSpecList.end(); 236affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 237affc150dc44fab1911775a49636d0ce85333b634Zonr Chang unsigned libPos = 0, filePos = 0; 238affc150dc44fab1911775a49636d0ce85333b634Zonr Chang while (true) { 239affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (libIt != libEnd) 240affc150dc44fab1911775a49636d0ce85333b634Zonr Chang libPos = OptNameSpecList.getPosition(libIt - libBegin); 241affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 242affc150dc44fab1911775a49636d0ce85333b634Zonr Chang libPos = 0; 243affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 244affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (fileIt != fileEnd) 245affc150dc44fab1911775a49636d0ce85333b634Zonr Chang filePos = OptInputObjectFiles.getPosition(fileIt - fileBegin); 246affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 247affc150dc44fab1911775a49636d0ce85333b634Zonr Chang filePos = 0; 248affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 249affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if ( filePos != 0 && (libPos == 0 || filePos < libPos) ) { 250affc150dc44fab1911775a49636d0ce85333b634Zonr Chang result = pLinker.addObject(*fileIt); 251affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (Linker::kSuccess != result) { 252affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::errs() << "Failed to open the input file! (detail: " 253affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << *fileIt << ": " 254affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << Linker::GetErrorString(result) << ")\n"; 255affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 256affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 257affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ++fileIt; 258affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 259affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else if ( libPos != 0 && (filePos == 0 || libPos < filePos) ) { 260affc150dc44fab1911775a49636d0ce85333b634Zonr Chang result = pLinker.addNameSpec(*libIt); 261affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (Linker::kSuccess != result) { 262affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::errs() << "Failed to open the namespec! (detail: " 263affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << *libIt << ": " 264affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << Linker::GetErrorString(result) << ")\n"; 265affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 266affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 267affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ++libIt; 268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 269affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 270affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 271affc150dc44fab1911775a49636d0ce85333b634Zonr Chang break; // we're done with the list 272affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 273affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 274affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 275affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 276affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 277affc150dc44fab1911775a49636d0ce85333b634Zonr Changstatic inline 278affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool LinkFiles(Linker& pLinker) { 279affc150dc44fab1911775a49636d0ce85333b634Zonr Chang Linker::ErrorCode result = pLinker.link(); 280affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (Linker::kSuccess != result) { 281affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::errs() << "Failed to linking! (detail: " 282affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << Linker::GetErrorString(result) << "\n"; 283affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return false; 284affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 285affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 286affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 288affc150dc44fab1911775a49636d0ce85333b634Zonr Changint main(int argc, char* argv[]) 289affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 290affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::SetVersionPrinter(MCLDVersionPrinter); 291affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::cl::ParseCommandLineOptions(argc, argv); 292affc150dc44fab1911775a49636d0ce85333b634Zonr Chang init::Initialize(); 293affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 294affc150dc44fab1911775a49636d0ce85333b634Zonr Chang std::string OutputFilename = DetermineOutputFilename(OptOutputFilename); 295affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (OutputFilename.empty()) { 296affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return EXIT_FAILURE; 297affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 298affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 299affc150dc44fab1911775a49636d0ce85333b634Zonr Chang Linker linker; 300affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!ConfigLinker(linker, OutputFilename)) { 301affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return EXIT_FAILURE; 302affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 303affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 304affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!PrepareInputOutput(linker, OutputFilename)) { 305affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return EXIT_FAILURE; 306affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 307affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 308affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!LinkFiles(linker)) { 309affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return EXIT_FAILURE; 310affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 311affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return EXIT_SUCCESS; 312affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 313affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 314