1 /* 2 * Copyright 2011-2012, 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 "bcinfo/BitcodeTranslator.h" 18 19 #include "bcinfo/BitcodeWrapper.h" 20 21 #include "BitReader_2_7/BitReader_2_7.h" 22 #include "BitReader_3_0/BitReader_3_0.h" 23 24 #include "BitWriter_3_2/ReaderWriter_3_2.h" 25 26 #include "StripUnkAttr/strip_unknown_attributes.h" 27 28 #define LOG_TAG "bcinfo" 29 #include <log/log.h> 30 31 #include "llvm/Bitcode/BitstreamWriter.h" 32 #include "llvm/Bitcode/ReaderWriter.h" 33 #include "llvm/IR/LLVMContext.h" 34 #include "llvm/IR/Module.h" 35 #include "llvm/Support/MemoryBuffer.h" 36 #include "llvm/Support/raw_ostream.h" 37 38 #include <cstdlib> 39 #include <climits> 40 41 namespace bcinfo { 42 43 /** 44 * Define minimum and maximum target API versions. These correspond to the 45 * same API levels used by the standard Android SDK. 46 * 47 * LLVM 2.7 48 * 11 - Honeycomb 49 * 12 - Honeycomb MR1 50 * 13 - Honeycomb MR2 51 * 52 * LLVM 3.0 53 * 14 - Ice Cream Sandwich 54 * 15 - Ice Cream Sandwich MR1 55 * 56 * LLVM 3.1 57 * 16 - Ice Cream Sandwich MR2 58 */ 59 static const unsigned int kMinimumAPIVersion = 11; 60 static const unsigned int kMaximumAPIVersion = RS_VERSION; 61 static const unsigned int kCurrentAPIVersion = 10000; 62 static const unsigned int kDevelopmentAPIVersion = UINT_MAX; 63 64 /** 65 * The minimum version which does not require translation (i.e. is already 66 * compatible with LLVM's default bitcode reader). 67 */ 68 static const unsigned int kMinimumUntranslatedVersion = 16; 69 static const unsigned int kMinimumCompatibleVersion_LLVM_3_0 = 14; 70 static const unsigned int kMinimumCompatibleVersion_LLVM_2_7 = 11; 71 72 73 static void stripUnknownAttributes(llvm::Module *M) { 74 for (llvm::Function &F : *M) 75 slang::stripUnknownAttributes(F); 76 } 77 78 BitcodeTranslator::BitcodeTranslator(const char *bitcode, size_t bitcodeSize, 79 unsigned int version) 80 : mBitcode(bitcode), mBitcodeSize(bitcodeSize), mTranslatedBitcode(nullptr), 81 mTranslatedBitcodeSize(0), mVersion(version) { 82 return; 83 } 84 85 86 BitcodeTranslator::~BitcodeTranslator() { 87 if (mVersion < kMinimumUntranslatedVersion) { 88 // We didn't actually do a translation in the alternate case, so deleting 89 // the bitcode would be improper. 90 delete [] mTranslatedBitcode; 91 } 92 mTranslatedBitcode = nullptr; 93 return; 94 } 95 96 97 bool BitcodeTranslator::translate() { 98 if (!mBitcode || !mBitcodeSize) { 99 ALOGE("Invalid/empty bitcode"); 100 return false; 101 } 102 103 BitcodeWrapper BCWrapper(mBitcode, mBitcodeSize); 104 if (BCWrapper.getTargetAPI() != mVersion) { 105 ALOGE("Bitcode wrapper (%u) and translator (%u) disagree about target API", 106 BCWrapper.getTargetAPI(), mVersion); 107 } 108 109 if ((mVersion != kDevelopmentAPIVersion) && 110 (mVersion != kCurrentAPIVersion) && 111 ((mVersion < kMinimumAPIVersion) || 112 (mVersion > kMaximumAPIVersion))) { 113 ALOGE("Invalid API version: %u is out of range ('%u' - '%u')", mVersion, 114 kMinimumAPIVersion, kMaximumAPIVersion); 115 return false; 116 } 117 118 // We currently don't need to transcode any API version higher than 14 or 119 // the current API version (i.e. 10000) 120 if (mVersion >= kMinimumUntranslatedVersion) { 121 mTranslatedBitcode = mBitcode; 122 mTranslatedBitcodeSize = mBitcodeSize; 123 return true; 124 } 125 126 // Do the actual transcoding by invoking a 2.7-era bitcode reader that can 127 // then write the bitcode back out in a more modern (acceptable) version. 128 std::unique_ptr<llvm::LLVMContext> mContext(new llvm::LLVMContext()); 129 std::unique_ptr<llvm::MemoryBuffer> MEM( 130 llvm::MemoryBuffer::getMemBuffer( 131 llvm::StringRef(mBitcode, mBitcodeSize), "", false)); 132 std::string error; 133 llvm::ErrorOr<llvm::MemoryBufferRef> MBOrErr = MEM->getMemBufferRef(); 134 135 llvm::ErrorOr<llvm::Module *> MOrErr(nullptr); 136 137 if (mVersion >= kMinimumCompatibleVersion_LLVM_3_0) { 138 MOrErr = llvm_3_0::parseBitcodeFile(*MBOrErr, *mContext); 139 } else if (mVersion >= kMinimumCompatibleVersion_LLVM_2_7) { 140 MOrErr = llvm_2_7::parseBitcodeFile(*MBOrErr, *mContext); 141 } else { 142 ALOGE("No compatible bitcode reader for API version %d", mVersion); 143 return false; 144 } 145 146 if (std::error_code EC = MOrErr.getError()) { 147 ALOGE("Could not parse bitcode file"); 148 ALOGE("%s", EC.message().c_str()); 149 return false; 150 } 151 152 // Module ownership is handled by the context, so we don't need to free it. 153 llvm::Module *module = MOrErr.get(); 154 155 stripUnknownAttributes(module); 156 157 std::string Buffer; 158 159 llvm::raw_string_ostream OS(Buffer); 160 // Use the LLVM 3.2 bitcode writer, instead of the top-of-tree version. 161 llvm_3_2::WriteBitcodeToFile(module, OS); 162 OS.flush(); 163 164 AndroidBitcodeWrapper wrapper; 165 size_t actualWrapperLen = writeAndroidBitcodeWrapper( 166 &wrapper, Buffer.size(), kMinimumUntranslatedVersion, 167 BCWrapper.getCompilerVersion(), BCWrapper.getOptimizationLevel()); 168 if (!actualWrapperLen) { 169 ALOGE("Couldn't produce bitcode wrapper!"); 170 return false; 171 } 172 173 mTranslatedBitcodeSize = actualWrapperLen + Buffer.size(); 174 char *c = new char[mTranslatedBitcodeSize]; 175 memcpy(c, &wrapper, actualWrapperLen); 176 memcpy(c + actualWrapperLen, Buffer.c_str(), Buffer.size()); 177 178 mTranslatedBitcode = c; 179 180 return true; 181 } 182 183 } // namespace bcinfo 184