• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
23 using namespace alone;
24 
LinkerConfig(const std::string & pTriple)25 LinkerConfig::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 
~LinkerConfig()34 LinkerConfig::~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 
initializeTarget()49 bool 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 
initializeLDInfo()61 bool 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 
initializeDiagnostic()72 bool 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 
setShared(bool pEnable)83 void LinkerConfig::setShared(bool pEnable) {
84   mShared = pEnable;
85   return;
86 }
87 
setBsymbolic(bool pEnable)88 void LinkerConfig::setBsymbolic(bool pEnable) {
89   mLDInfo->options().setBsymbolic(pEnable);
90   return;
91 }
92 
setSOName(const std::string & pSOName)93 void LinkerConfig::setSOName(const std::string &pSOName) {
94   mSOName = pSOName;
95   return;
96 }
97 
setDyld(const std::string & pDyld)98 void LinkerConfig::setDyld(const std::string &pDyld) {
99   mLDInfo->options().setDyld(pDyld);
100   return;
101 }
102 
setSysRoot(const std::string & pSysRoot)103 void LinkerConfig::setSysRoot(const std::string &pSysRoot) {
104   mLDInfo->options().setSysroot(mcld::sys::fs::Path(pSysRoot));
105   return;
106 }
107 
addWrap(const std::string & pWrapSymbol)108 void 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 
addPortable(const std::string & pPortableSymbol)135 void 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 
addSearchDir(const std::string & pDirPath)163 void 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