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