BitcodeTranslator.cpp revision c73b5214fa71ef6e3378fa121bb8b6312d2e6d3b
1932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines/* 2932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * Copyright 2011, The Android Open Source Project 3932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * 4932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * Licensed under the Apache License, Version 2.0 (the "License"); 5932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * you may not use this file except in compliance with the License. 6932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * You may obtain a copy of the License at 7932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * 8932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * http://www.apache.org/licenses/LICENSE-2.0 9932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * 10932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * Unless required by applicable law or agreed to in writing, software 11932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * distributed under the License is distributed on an "AS IS" BASIS, 12932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * See the License for the specific language governing permissions and 14932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * limitations under the License. 15932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines */ 16932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 17932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include "bcinfo/BitcodeTranslator.h" 18932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 19932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include "BitReader_2_7/BitReader_2_7.h" 20c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien#include "BitReader_3_0/BitReader_3_0.h" 21932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 22932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#define LOG_TAG "bcinfo" 23932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <cutils/log.h> 24932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 25932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include "llvm/ADT/OwningPtr.h" 26932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include "llvm/Bitcode/BitstreamWriter.h" 27932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include "llvm/Bitcode/ReaderWriter.h" 28932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include "llvm/LLVMContext.h" 29932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include "llvm/Module.h" 30932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include "llvm/Support/MemoryBuffer.h" 31c73b5214fa71ef6e3378fa121bb8b6312d2e6d3bShih-wei Liao#include "llvm/Support/raw_ostream.h" 32932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 33932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <cstdlib> 34932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 35932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesnamespace bcinfo { 36932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 37932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines/** 38932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * Define minimum and maximum target API versions. These correspond to the 39932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * same API levels used by the standard Android SDK. 40932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * 41c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien * LLVM 2.7 42c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien * 11 - Honeycomb 43c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien * 12 - Honeycomb MR1 44c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien * 13 - Honeycomb MR2 45c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien * 46c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien * LLVM 3.0 47c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien * 14 - Ice Cream Sandwich 48c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien * 15 - Ice Cream Sandwich MR1 49c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien * 50c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien * LLVM 3.1 51c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien * 16 - Ice Cream Sandwich MR2 52932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines */ 53932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic const unsigned int kMinimumAPIVersion = 11; 54932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic const unsigned int kMaximumAPIVersion = BCINFO_API_VERSION; 55932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic const unsigned int kCurrentAPIVersion = 10000; 56932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 57932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines/** 58932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * The minimum version which does not require translation (i.e. is already 59932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * compatible with LLVM's default bitcode reader). 60932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines */ 61c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chienstatic const unsigned int kMinimumUntranslatedVersion = 16; 62c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chienstatic const unsigned int kMinimumCompatibleVersion_LLVM_3_0 = 14; 63c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chienstatic const unsigned int kMinimumCompatibleVersion_LLVM_2_7 = 11; 64932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 65932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 66932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen HinesBitcodeTranslator::BitcodeTranslator(const char *bitcode, size_t bitcodeSize, 67932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines unsigned int version) 68932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines : mBitcode(bitcode), mBitcodeSize(bitcodeSize), mTranslatedBitcode(NULL), 69932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines mTranslatedBitcodeSize(0), mVersion(version) { 70932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return; 71932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines} 72932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 73932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 74932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen HinesBitcodeTranslator::~BitcodeTranslator() { 75932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (mVersion < kMinimumUntranslatedVersion) { 76932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines // We didn't actually do a translation in the alternate case, so deleting 77932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines // the bitcode would be improper. 78932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines delete [] mTranslatedBitcode; 79932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 80932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines mTranslatedBitcode = NULL; 81932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return; 82932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines} 83932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 84932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 85932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesbool BitcodeTranslator::translate() { 86932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (!mBitcode || !mBitcodeSize) { 8710c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block ALOGE("Invalid/empty bitcode"); 88932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return false; 89932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 90932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 91932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if ((mVersion != kCurrentAPIVersion) && 92932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines ((mVersion < kMinimumAPIVersion) || 93932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines (mVersion > kMaximumAPIVersion))) { 9410c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block ALOGE("Invalid API version: %u is out of range ('%u' - '%u')", mVersion, 95932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines kMinimumAPIVersion, kMaximumAPIVersion); 96932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return false; 97932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 98932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 99932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines // We currently don't need to transcode any API version higher than 14 or 100932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines // the current API version (i.e. 10000) 101932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (mVersion >= kMinimumUntranslatedVersion) { 102932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines mTranslatedBitcode = mBitcode; 103932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines mTranslatedBitcodeSize = mBitcodeSize; 104932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return true; 105932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 106932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 107932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines // Do the actual transcoding by invoking a 2.7-era bitcode reader that can 108932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines // then write the bitcode back out in a more modern (acceptable) version. 109932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines llvm::OwningPtr<llvm::LLVMContext> mContext(new llvm::LLVMContext()); 110932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines llvm::OwningPtr<llvm::MemoryBuffer> MEM( 111932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines llvm::MemoryBuffer::getMemBuffer( 112932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines llvm::StringRef(mBitcode, mBitcodeSize))); 113932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines std::string error; 114932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 115932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines // Module ownership is handled by the context, so we don't need to free it. 116c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien llvm::Module *module = NULL; 117c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien 118c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien if (mVersion >= kMinimumCompatibleVersion_LLVM_3_0) { 119c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien module = llvm_3_0::ParseBitcodeFile(MEM.get(), *mContext, &error); 120c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien } else if (mVersion >= kMinimumCompatibleVersion_LLVM_2_7) { 121c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien module = llvm_2_7::ParseBitcodeFile(MEM.get(), *mContext, &error); 122c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien } else { 12310c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block ALOGE("No compatible bitcode reader for API version %d", mVersion); 124c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien return false; 125c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien } 126c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien 127932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines if (!module) { 12810c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block ALOGE("Could not parse bitcode file"); 12910c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block ALOGE("%s", error.c_str()); 130932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return false; 131932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines } 132932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 133c73b5214fa71ef6e3378fa121bb8b6312d2e6d3bShih-wei Liao std::string Buffer; 134c73b5214fa71ef6e3378fa121bb8b6312d2e6d3bShih-wei Liao 135c73b5214fa71ef6e3378fa121bb8b6312d2e6d3bShih-wei Liao llvm::raw_string_ostream OS(Buffer); 136c73b5214fa71ef6e3378fa121bb8b6312d2e6d3bShih-wei Liao llvm::WriteBitcodeToFile(module, OS); 137c73b5214fa71ef6e3378fa121bb8b6312d2e6d3bShih-wei Liao OS.flush(); 138932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 139932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines char *c = new char[Buffer.size()]; 140c73b5214fa71ef6e3378fa121bb8b6312d2e6d3bShih-wei Liao memcpy(c, Buffer.c_str(), Buffer.size()); 141932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 142932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines mTranslatedBitcode = c; 143932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines mTranslatedBitcodeSize = Buffer.size(); 144932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 145932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines return true; 146932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines} 147932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 148932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines} // namespace bcinfo 149932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines 150