1//===- LinkerConfig.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 10#include "alone/Support/LinkerConfig.h" 11#include "alone/Support/Log.h" 12 13#include <llvm/Support/Signals.h> 14 15#include <mcld/MC/MCLDInfo.h> 16#include <mcld/MC/MCLDFile.h> 17#include <mcld/MC/MCLDDirectory.h> 18#include <mcld/LD/TextDiagnosticPrinter.h> 19#include <mcld/Support/Path.h> 20#include <mcld/Support/MsgHandling.h> 21#include <mcld/Support/raw_ostream.h> 22 23using namespace alone; 24 25LinkerConfig::LinkerConfig(const std::string &pTriple) 26 : mTriple(pTriple), mShared(false), mSOName(), mTarget(NULL), mLDInfo(NULL), 27 mDiagLineInfo(NULL), mDiagPrinter(NULL) { 28 29 initializeTarget(); 30 initializeLDInfo(); 31 initializeDiagnostic(); 32} 33 34LinkerConfig::~LinkerConfig() { 35 delete mLDInfo; 36 37 if (mDiagPrinter->getNumErrors() != 0) { 38 // If here, the program failed ungracefully. Run the interrupt handlers to 39 // ensure any other cleanups (e.g., files that registered by 40 // RemoveFileOnSignal(...)) getting done before exit. 41 llvm::sys::RunInterruptHandlers(); 42 } 43 mDiagPrinter->finish(); 44 45 delete mDiagLineInfo; 46 delete mDiagPrinter; 47} 48 49bool LinkerConfig::initializeTarget() { 50 std::string error; 51 mTarget = mcld::TargetRegistry::lookupTarget(mTriple, error); 52 if (NULL != mTarget) { 53 return true; 54 } else { 55 ALOGE("Cannot initialize mcld::Target for given triple '%s'! (%s)\n", 56 mTriple.c_str(), error.c_str()); 57 return false; 58 } 59} 60 61bool LinkerConfig::initializeLDInfo() { 62 if (NULL != mLDInfo) { 63 ALOGE("Cannot initialize mcld::MCLDInfo for given triple '%s!\n", 64 mTriple.c_str()); 65 return false; 66 } 67 68 mLDInfo = new mcld::MCLDInfo(getTriple(), 1, 32); 69 return true; 70} 71 72bool LinkerConfig::initializeDiagnostic() { 73 // Set up MsgHandler. 74 mDiagLineInfo = mTarget->createDiagnosticLineInfo(*mTarget, mTriple); 75 76 mDiagPrinter = new mcld::TextDiagnosticPrinter(mcld::errs(), *mLDInfo); 77 78 mcld::InitializeDiagnosticEngine(*mLDInfo, mDiagLineInfo, mDiagPrinter); 79 80 return true; 81} 82 83void LinkerConfig::setShared(bool pEnable) { 84 mShared = pEnable; 85 return; 86} 87 88void LinkerConfig::setBsymbolic(bool pEnable) { 89 mLDInfo->options().setBsymbolic(pEnable); 90 return; 91} 92 93void LinkerConfig::setSOName(const std::string &pSOName) { 94 mSOName = pSOName; 95 return; 96} 97 98void LinkerConfig::setDyld(const std::string &pDyld) { 99 mLDInfo->options().setDyld(pDyld); 100 return; 101} 102 103void LinkerConfig::setSysRoot(const std::string &pSysRoot) { 104 mLDInfo->options().setSysroot(mcld::sys::fs::Path(pSysRoot)); 105 return; 106} 107 108void LinkerConfig::addWrap(const std::string &pWrapSymbol) { 109 bool exist = false; 110 111 // Add wname -> __wrap_wname. 112 mcld::StringEntry<llvm::StringRef>* to_wrap = 113 mLDInfo->scripts().renameMap().insert(pWrapSymbol, exist); 114 115 std::string to_wrap_str = "__wrap_" + pWrapSymbol; 116 to_wrap->setValue(to_wrap_str); 117 118 if (exist) { 119 mcld::warning(mcld::diag::rewrap) << pWrapSymbol << to_wrap_str; 120 } 121 122 // Add __real_wname -> wname. 123 std::string from_real_str = "__real_" + pWrapSymbol; 124 mcld::StringEntry<llvm::StringRef>* from_real = 125 mLDInfo->scripts().renameMap().insert(from_real_str, exist); 126 from_real->setValue(pWrapSymbol); 127 128 if (exist) { 129 mcld::warning(mcld::diag::rewrap) << pWrapSymbol << from_real_str; 130 } 131 132 return; 133} 134 135void LinkerConfig::addPortable(const std::string &pPortableSymbol) { 136 bool exist = false; 137 138 // Add pname -> pname_portable. 139 mcld::StringEntry<llvm::StringRef>* to_port = 140 mLDInfo->scripts().renameMap().insert(pPortableSymbol, exist); 141 142 std::string to_port_str = pPortableSymbol + "_portable"; 143 to_port->setValue(to_port_str); 144 145 if (exist) { 146 mcld::warning(mcld::diag::rewrap) << pPortableSymbol << to_port_str; 147} 148 149 // Add __real_pname -> pname. 150 std::string from_real_str = "__real_" + pPortableSymbol; 151 mcld::StringEntry<llvm::StringRef>* from_real = 152 mLDInfo->scripts().renameMap().insert(from_real_str, exist); 153 154 from_real->setValue(pPortableSymbol); 155 156 if (exist) { 157 mcld::warning(mcld::diag::rewrap) << pPortableSymbol << from_real_str; 158 } 159 160 return; 161} 162 163void LinkerConfig::addSearchDir(const std::string &pDirPath) { 164 // SearchDirs will remove the created MCLDDirectory. 165 mcld::MCLDDirectory* sd = new mcld::MCLDDirectory(pDirPath); 166 167 if (sd->isInSysroot()) { 168 sd->setSysroot(mLDInfo->options().sysroot()); 169 } 170 171 if (exists(sd->path()) && is_directory(sd->path())) { 172 mLDInfo->options().directories().add(*sd); 173 } else { 174 mcld::warning(mcld::diag::warn_cannot_open_search_dir) << sd->name(); 175 } 176 177 return; 178} 179