• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <sstream>
18 #include "Abcc_host.h"
19 using namespace abcc;
20 
21 bool kVerbose = false;
22 
HostBitcodeCompiler(const std::string & abi,const std::string & sysroot,const std::string & toolchain_bin,const std::string & input,const std::string & output,const std::string & working_dir,const std::string & platform,const bool savetemps,bool bit32)23 HostBitcodeCompiler::HostBitcodeCompiler(const std::string &abi, const std::string &sysroot, const std::string &toolchain_bin,
24                                          const std::string &input, const std::string &output, const std::string &working_dir,
25                                          const std::string &platform, const bool savetemps, bool bit32)
26   : BitcodeCompiler(abi, sysroot, working_dir, savetemps), mIn(input), mOut(output),
27     mNDKDir(""), mPlatform(platform), mToolchainBinPath(toolchain_bin) {
28   initRuntimePath();
29 }
30 
HostBitcodeCompiler(const std::string & abi,const std::string & sysroot,const std::string & ndk_dir,const std::string & toolchain_bin,const std::string & input,const std::string & output,const std::string & working_dir,const std::string & platform,const bool savetemps,bool bit32)31 HostBitcodeCompiler::HostBitcodeCompiler(const std::string &abi, const std::string &sysroot, const std::string &ndk_dir, const std::string &toolchain_bin,
32                                          const std::string &input, const std::string &output, const std::string &working_dir,
33                                          const std::string &platform, const bool savetemps, bool bit32)
34   : BitcodeCompiler(abi, sysroot, working_dir, savetemps), mIn(input), mOut(output),
35     mNDKDir(ndk_dir), mPlatform(platform), mToolchainBinPath(toolchain_bin) {
36   initRuntimePath();
37 }
38 
initRuntimePath()39 void HostBitcodeCompiler::initRuntimePath() {
40   mRuntimePath.clear();
41 
42   mRuntimePath.insert(std::make_pair("gabi++_static", getGAbixxPath() + "/libgabi++_static.a"));
43   mRuntimePath.insert(std::make_pair("gabi++_shared", getGAbixxPath() + "/libgabi++_shared.so"));
44   mRuntimePath.insert(std::make_pair("compiler_rt_static", getCompilerRTPath() + "/libcompiler_rt_static.a"));
45   mRuntimePath.insert(std::make_pair("portable", getLibPortablePath() + "/libportable.a"));
46   mRuntimePath.insert(std::make_pair("portable.wrap", getLibPortablePath() + "/libportable.wrap"));
47   mRuntimePath.insert(std::make_pair("gccunwind", getGCCUnwindPath() + "/libgccunwind.a"));
48 }
49 
getRuntimePath(const std::string & libname)50 const std::string HostBitcodeCompiler::getRuntimePath(const std::string &libname) {
51   if (mRuntimePath.count(libname)) {
52     return mRuntimePath.find(libname)->second;
53   }
54   return "";
55 }
56 
parseLDFlags(BitcodeInfo & info,const std::string & orig_str)57 int HostBitcodeCompiler::parseLDFlags(BitcodeInfo &info, const std::string &orig_str) {
58   // Follow traditional clang/gcc use, add -lgccunwind (-lgcc) before local libs
59   info.mLDLocalLibsStr += " " + getRuntimePath("gccunwind");
60 
61   std::stringstream ss(orig_str);
62   std::string str;
63   while (ss >> str) {
64     if (str.find("--sysroot") != std::string::npos) {
65       continue;
66     }
67     if (str == "-o") {
68       ss >> str;
69       continue;
70     }
71     if (str == "-soname") {
72       ss >> str;
73       info.mSOName = str;
74       continue;
75     }
76     if (str == "-shared") {
77       info.mShared = true;
78       info.mOutPath += ".so";
79       continue;
80     }
81 
82     if (str.size() > 2 &&
83         str.substr(str.size() - 2) == ".a") {
84       if (str.size() > 6 &&
85           str.substr(0, /*leng*/6) == "./obj/") {
86         info.mLDLocalLibsStr += " " + str;
87       } else {
88         info.mLDLibs.push_back(str);
89         info.mLDLibsStr += " " + str;
90       }
91       continue;
92     }
93     if (str.size() > 3 &&
94         str.substr(str.size() - 3) == ".so") {
95       if (str.size() > 6 &&
96           str.substr(0, /*leng*/6) == "./obj/") {
97         info.mLDLocalLibsStr += " " + str;
98       } else {
99         info.mLDLibs.push_back(str);
100         info.mLDLibsStr += " " + str;
101       }
102       continue;
103     }
104 
105     // Parse -lxxx
106     if (str.size() > 2 &&
107         str.substr(0, 2) == "-l") {
108       std::string runtime_path = getRuntimePath(str.substr(2));
109       if (!runtime_path.empty()) {
110         info.mLDLibsStr += " " + runtime_path;
111       }
112       else {
113         info.mLDLibs.push_back(str.substr(2));
114         info.mLDLibsStr += " " + str;
115       }
116       continue;
117     }
118 
119     // Some other flags, like --no-undefined, -z now, -z noexecstack, ...
120     info.mLDFlags += str + " ";
121   } // while
122 
123   size_t first_dash_l = info.mLDLibsStr.find(" -l");
124   if (first_dash_l == 0u) {
125     info.mLDLibsStr += " " + getRuntimePath("gccunwind");
126   } else if (first_dash_l == std::string::npos) {
127     info.mLDLibsStr = getRuntimePath("gccunwind") + info.mLDLibsStr;
128   } else {
129     info.mLDLibsStr = info.mLDLibsStr.substr(0, first_dash_l)
130                       + " " + getRuntimePath("gccunwind")
131                       + info.mLDLibsStr.substr(first_dash_l,
132                                                info.mLDLibsStr.size() - first_dash_l);
133   }
134   return 0;
135 }
136 
getBitcodeFiles()137 void HostBitcodeCompiler::getBitcodeFiles() {
138   BitcodeInfo bcinfo(mIn);
139   if (bcinfo.readWrapper(*this) != 0) {
140     LOGE("Cannot read wrapper for bitcode %s", mIn.c_str());
141     mRet = RET_FAIL_PREPARE_BITCODE;
142     return;
143   }
144 
145   bcinfo.mOutPath = mOut;
146   mBitcodeFiles.push_back(bcinfo);
147 }
148 
prepareToolchain()149 void HostBitcodeCompiler::prepareToolchain() {
150   std::string cmd;
151   // le32-none-ndk-translate
152   if (mAbi == TargetAbi::ARM64_V8A || mAbi == TargetAbi::X86_64 ||
153       mAbi == TargetAbi::MIPS64)
154     cmd = getToolchainBinPath() + "/le64-none-ndk-translate";
155   else
156     cmd = getToolchainBinPath() + "/le32-none-ndk-translate";
157   mExecutableToolsPath[(unsigned)CMD_TRANSLATE] = cmd;
158 
159   // llc
160   cmd = getToolchainBinPath() + "/llc";
161   mExecutableToolsPath[(unsigned)CMD_COMPILE] = cmd;
162 
163   // ld.mcld
164   cmd = getToolchainBinPath() + "/ld.mcld";
165   if (mAbi == TargetAbi::MIPS64) {
166     cmd = getToolchainBinPath() + "/../../../../mips64el-linux-android-4.8/prebuilt/linux-x86/bin/mips64el-linux-android-ld";
167   }
168 
169   if (mAbi == TargetAbi::X86_64) {
170     cmd += " -L" + mSysroot + "/usr/lib64";
171   } else {
172     cmd += " -L" + mSysroot + "/usr/lib";
173   }
174   mExecutableToolsPath[(unsigned)CMD_LINK] = cmd;
175 
176   cmd = " @" + getRuntimePath("portable.wrap") + " " + getRuntimePath("portable");
177   cmd += " " + getRuntimePath("compiler_rt_static");
178   cmd += " " + getRuntimePath("gccunwind");
179   cmd += " -ldl";
180   mExecutableToolsPath[(unsigned)CMD_LINK_RUNTIME] = cmd;
181 }
182 
copyRuntime(const BitcodeInfo & info)183 void HostBitcodeCompiler::copyRuntime(const BitcodeInfo &info) {
184 }
185 
removeIntermediateFile(const std::string & path)186 void HostBitcodeCompiler::removeIntermediateFile(const std::string &path) {
187   if (!kVerbose)
188     runCmd(std::string("rm -f ") + path);
189 }
190 
getToolchainBinPath() const191 const std::string HostBitcodeCompiler::getToolchainBinPath() const {
192   return mToolchainBinPath;
193 }
194 
getCompilerRTPath() const195 const std::string HostBitcodeCompiler::getCompilerRTPath() const {
196   if (!mNDKDir.empty())
197     return std::string(mNDKDir) + "/sources/android/compiler-rt/libs/" + (const char*)mAbi;
198   else
199     return mSysroot + "/usr/lib";
200 }
201 
getGAbixxPath() const202 const std::string HostBitcodeCompiler::getGAbixxPath() const {
203   if (!mNDKDir.empty())
204     return std::string(mNDKDir) + "/sources/cxx-stl/gabi++/libs/" + (const char*)mAbi;
205   else
206     return mSysroot + "/usr/lib";
207 }
208 
getLibPortablePath() const209 const std::string HostBitcodeCompiler::getLibPortablePath() const {
210   if (!mNDKDir.empty())
211     return std::string(mNDKDir) + "/sources/android/libportable/libs/" + (const char*)mAbi;
212   else
213     return mSysroot + "/usr/lib";
214 }
215 
getGCCUnwindPath() const216 const std::string HostBitcodeCompiler::getGCCUnwindPath() const {
217   if (!mNDKDir.empty())
218     return std::string(mNDKDir) + "/sources/android/gccunwind/libs/" + (const char*)mAbi;
219   else
220     return mSysroot + "/usr/lib";
221 }
222