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