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