• 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 #ifndef ABCC_ABCC_H
18 #define ABCC_ABCC_H
19 
20 #include <list>
21 #include <map>
22 #include <string>
23 #include <vector>
24 
25 namespace abcc {
26 
27 enum ReturnCode {
28   RET_OK,
29   RET_FAIL_RUN_CMD,
30   RET_FAIL_UNSUPPORT_ABI,
31   RET_FAIL_PREPARE_BITCODE,
32   RET_FAIL_PREPARE_TOOL,
33   RET_FAIL_CLEANUP,
34   RET_FAIL_TRANSLATE,
35   RET_FAIL_COMPILE,
36   RET_FAIL_LINK
37 };
38 
39 enum Command {
40   CMD_TRANSLATE = 0,
41   CMD_COMPILE,
42   CMD_LINK,
43   CMD_LINK_RUNTIME
44 };
45 
46 class TargetAbi {
47 public:
48   enum Abi {
49     ARMEABI = 0,
50     ARMEABI_V7A,
51     X86,
52     MIPS,
53     ARM64_V8A,
54     X86_64,
55     MIPS64
56   };
57 
58 private:
59   Abi mAbi;
60 
61 public:
62   TargetAbi(const std::string &abi);
63   operator int() const { return (int)mAbi; }
64   operator const char*() const {
65     if (mAbi == ARMEABI)  return "armeabi";
66     if (mAbi == ARMEABI_V7A)  return "armeabi-v7a";
67     if (mAbi == X86)  return "x86";
68     if (mAbi == MIPS)  return "mips";
69     if (mAbi == ARM64_V8A)  return "arm64-v8a";
70     if (mAbi == X86_64)  return "x86_64";
71     if (mAbi == MIPS64)  return "mips64";
72     return 0;
73   }
getArch()74   const char* getArch() const {
75     if (mAbi == ARMEABI || mAbi == ARMEABI_V7A)  return "arm";
76     if (mAbi == X86)  return "x86";
77     if (mAbi == MIPS) return "mips";
78     if (mAbi == ARM64_V8A)  return "arm64";
79     if (mAbi == X86_64)  return "x86_64";
80     if (mAbi == MIPS64)  return "mips64";
81     return 0;
82   }
83 };
84 
85 struct TargetAttributes {
86   const char *mArch;
87   const char *mTriple;
88   const char *mLinkEmulation;
89   const char *mBaseCFlags;
90   const char *mBaseLDFlags;
91 };
92 
93 const TargetAttributes kGlobalTargetAttrs[] = {
94   {"arm", "armv5te-linux-androideabi", "armelf_linux_eabi", "-arm-enable-ehabi -arm-enable-ehabi-descriptors -float-abi=soft", "-dynamic-linker /system/bin/linker"},
95 #ifdef FORCE_ARM
96   {"arm", "armv7-linux-androideabi", "armelf_linux_eabi", "-arm-enable-ehabi -arm-enable-ehabi-descriptors -float-abi=soft", "-dynamic-linker /system/bin/linker"},
97 #else
98   {"arm", "thumbv7-linux-androideabi", "armelf_linux_eabi", "-arm-enable-ehabi -arm-enable-ehabi-descriptors -float-abi=soft", "-dynamic-linker /system/bin/linker"},
99 #endif
100   {"x86", "i686-linux-android", "elf_i386", "-disable-fp-elim -force-align-stack -mattr=-ssse3,-sse41,-sse42,-sse4a,-popcnt -x86-force-gv-stack-cookie", "-dynamic-linker /system/bin/linker"},
101   {"mips", "mipsel-linux-android", "elf32ltsmip", "-float-abi=hard", "-dynamic-linker /system/bin/linker"},
102   {"arm64", "aarch64-linux-android", "aarch64linux", "", "-dynamic-linker /system/bin/linker64"},
103   {"x86_64", "x86_64-linux-android", "elf_x86_64", "-disable-fp-elim -force-align-stack -mattr=+sse3 -x86-force-gv-stack-cookie", "-dynamic-linker /system/bin/linker64"},
104   {"mips64", "mips64el-linux-android", "elf64ltsmip", "", "-dynamic-linker /system/bin/linker64"},
105 };
106 
107 // Used when computing mutual dependency
108 class BitcodeCompiler;
109 class BitcodeInfo;
110 typedef std::map<std::string/*soname*/, BitcodeInfo> SONameMap;
111 
112 class BitcodeInfo {
113 public:
BitcodeInfo()114   BitcodeInfo() {}  // Only for stl use
115   BitcodeInfo(const std::string &bc);
116   int readWrapper(BitcodeCompiler &);
117   static void dropExternalLDLibs(SONameMap &map);
118 
119   bool mShared;
120   int mOptimizationLevel;
121   std::string mBCPath;
122   std::string mTargetBCPath;
123   std::string mObjPath;
124   std::string mOutPath;
125   std::string mSOName;
126   std::string mLDFlags; // --no-undefined, ...
127   std::string mLDLocalLibsStr;  // i.e.: ./obj/local/.../libxxx.a
128   std::list<std::string> mLDLibs;  // -lxxx, will be removed one-by-one until empty
129   std::string mLDLibsStr; // Immutable once read in
130 
131 public:
132   static int transferBytesToNumLe(const unsigned char *buffer, size_t n);
133 };
134 
135 
136 class BitcodeCompiler {
137 protected:
138   TargetAbi mAbi;
139   std::string mSysroot;
140   std::string mWorkingDir;
141 
142   // Target-independent, but global
143   std::string mGlobalCFlags;
144   std::string mGlobalLDFlags;
145   std::string mGlobalLDLibs;
146 
147   ReturnCode mRet;
148   std::vector<BitcodeInfo> mBitcodeFiles;
149   SONameMap mSonameMap;
150   std::string mExecutableToolsPath[(unsigned)CMD_LINK_RUNTIME+1];
151 
152 public:
153   BitcodeCompiler(const std::string &abi, const std::string &sysroot, const std::string &working_dir, const bool savetemps);
154   virtual ~BitcodeCompiler();
returnCode()155   const ReturnCode returnCode() const { return mRet; }
cleanupPre()156   virtual void cleanupPre() {}
cleanupPost()157   virtual void cleanupPost() {}
prepare()158   void prepare() {
159     prepareBitcodes();
160     if (returnCode() != RET_OK)
161       return;
162 
163     prepareToolchain();
164     if (returnCode() != RET_OK)
165       return;
166   }
execute()167   void execute() {
168     translate();
169     if (returnCode() != RET_OK)
170       return;
171 
172     compile();
173     if (returnCode() != RET_OK)
174       return;
175 
176     link();
177     if (returnCode() != RET_OK)
178       return;
179   }
180 
181 private:
182   bool mSaveTemps;
183 
184   void prepareBitcodes();
185   void createSONameMapping();
186   virtual void getBitcodeFiles() = 0;
187   virtual void prepareToolchain() = 0;
188   virtual void copyRuntime(const BitcodeInfo &info) = 0;
189   virtual void removeIntermediateFile(const std::string &path) = 0;
190   void translate();
191   void compile();
192   void link();
193 
194 public:
195   virtual int parseLDFlags(BitcodeInfo &info, const std::string &str) = 0;
196 
197 protected:
198   void runCmd(std::string cmd, bool dump = false);
199 };
200 
201 } // namespace abcc
202 
203 // FIXME: We use LOGV, LOGE in Abcc.cpp, how to prevent this anti dependency?
204 #if ON_DEVICE
205 #include "Abcc_device.h"
206 #else
207 #include "Abcc_host.h"
208 #endif
209 
210 #endif
211