BitcodeTranslator.cpp revision 881cda4f5b793a1e7f7d33cf4a31efc3fdbba4fd
1932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines/*
27cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * Copyright 2011-2012, 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
197cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines#include "bcinfo/BitcodeWrapper.h"
207cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
21932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include "BitReader_2_7/BitReader_2_7.h"
22c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien#include "BitReader_3_0/BitReader_3_0.h"
23932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
248dbca8e957dab1db77dffbe10c14c54d4b439be6Stephen Hines#include "BitWriter_3_2/ReaderWriter_3_2.h"
258dbca8e957dab1db77dffbe10c14c54d4b439be6Stephen Hines
26932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#define LOG_TAG "bcinfo"
27932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <cutils/log.h>
28932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
29932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include "llvm/ADT/OwningPtr.h"
30932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include "llvm/Bitcode/BitstreamWriter.h"
31932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include "llvm/Bitcode/ReaderWriter.h"
32b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include "llvm/IR/LLVMContext.h"
33b730e239619a546d93e5926ea92d698ab77ec7f6Stephen Hines#include "llvm/IR/Module.h"
34932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include "llvm/Support/MemoryBuffer.h"
35c73b5214fa71ef6e3378fa121bb8b6312d2e6d3bShih-wei Liao#include "llvm/Support/raw_ostream.h"
36932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
37932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <cstdlib>
38881cda4f5b793a1e7f7d33cf4a31efc3fdbba4fdChris Wailes#include <climits>
39932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
40932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesnamespace bcinfo {
41932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
42932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines/**
43932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * Define minimum and maximum target API versions. These correspond to the
44932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * same API levels used by the standard Android SDK.
45932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines *
46c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien * LLVM 2.7
47c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien *  11 - Honeycomb
48c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien *  12 - Honeycomb MR1
49c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien *  13 - Honeycomb MR2
50c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien *
51c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien * LLVM 3.0
52c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien *  14 - Ice Cream Sandwich
53c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien *  15 - Ice Cream Sandwich MR1
54c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien *
55c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien * LLVM 3.1
56c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien *  16 - Ice Cream Sandwich MR2
57932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines */
58881cda4f5b793a1e7f7d33cf4a31efc3fdbba4fdChris Wailesstatic const unsigned int kMinimumAPIVersion     = 11;
59881cda4f5b793a1e7f7d33cf4a31efc3fdbba4fdChris Wailesstatic const unsigned int kMaximumAPIVersion     = RS_VERSION;
60881cda4f5b793a1e7f7d33cf4a31efc3fdbba4fdChris Wailesstatic const unsigned int kCurrentAPIVersion     = 10000;
61881cda4f5b793a1e7f7d33cf4a31efc3fdbba4fdChris Wailesstatic const unsigned int kDevelopmentAPIVersion = UINT_MAX;
62932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
63932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines/**
64932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * The minimum version which does not require translation (i.e. is already
65932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * compatible with LLVM's default bitcode reader).
66932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines */
67c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chienstatic const unsigned int kMinimumUntranslatedVersion = 16;
68c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chienstatic const unsigned int kMinimumCompatibleVersion_LLVM_3_0 = 14;
69c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chienstatic const unsigned int kMinimumCompatibleVersion_LLVM_2_7 = 11;
70932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
71932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
72932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen HinesBitcodeTranslator::BitcodeTranslator(const char *bitcode, size_t bitcodeSize,
73932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines                                     unsigned int version)
74932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    : mBitcode(bitcode), mBitcodeSize(bitcodeSize), mTranslatedBitcode(NULL),
75932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      mTranslatedBitcodeSize(0), mVersion(version) {
76932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return;
77932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
78932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
79932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
80932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen HinesBitcodeTranslator::~BitcodeTranslator() {
81932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (mVersion < kMinimumUntranslatedVersion) {
82932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    // We didn't actually do a translation in the alternate case, so deleting
83932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    // the bitcode would be improper.
84932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    delete [] mTranslatedBitcode;
85932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
86932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mTranslatedBitcode = NULL;
87932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return;
88932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
89932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
90932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
91932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesbool BitcodeTranslator::translate() {
92932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!mBitcode || !mBitcodeSize) {
9310c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block    ALOGE("Invalid/empty bitcode");
94932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return false;
95932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
96932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
977cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  BitcodeWrapper BCWrapper(mBitcode, mBitcodeSize);
987cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  if (BCWrapper.getTargetAPI() != mVersion) {
997cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    ALOGE("Bitcode wrapper (%u) and translator (%u) disagree about target API",
1007cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines          BCWrapper.getTargetAPI(), mVersion);
1017cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
1027cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
103881cda4f5b793a1e7f7d33cf4a31efc3fdbba4fdChris Wailes  if ((mVersion != kDevelopmentAPIVersion) &&
104881cda4f5b793a1e7f7d33cf4a31efc3fdbba4fdChris Wailes      (mVersion != kCurrentAPIVersion)     &&
105881cda4f5b793a1e7f7d33cf4a31efc3fdbba4fdChris Wailes       ((mVersion < kMinimumAPIVersion) ||
106881cda4f5b793a1e7f7d33cf4a31efc3fdbba4fdChris Wailes        (mVersion > kMaximumAPIVersion))) {
10710c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block    ALOGE("Invalid API version: %u is out of range ('%u' - '%u')", mVersion,
108932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines         kMinimumAPIVersion, kMaximumAPIVersion);
109932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return false;
110932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
111932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
112932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  // We currently don't need to transcode any API version higher than 14 or
113932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  // the current API version (i.e. 10000)
114932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (mVersion >= kMinimumUntranslatedVersion) {
115932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    mTranslatedBitcode = mBitcode;
116932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    mTranslatedBitcodeSize = mBitcodeSize;
117932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return true;
118932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
119932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
120932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  // Do the actual transcoding by invoking a 2.7-era bitcode reader that can
121932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  // then write the bitcode back out in a more modern (acceptable) version.
122932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  llvm::OwningPtr<llvm::LLVMContext> mContext(new llvm::LLVMContext());
123932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  llvm::OwningPtr<llvm::MemoryBuffer> MEM(
124932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    llvm::MemoryBuffer::getMemBuffer(
125e708ffe612f4566bea20334d2c9dac34db508e6eStephen Hines      llvm::StringRef(mBitcode, mBitcodeSize), "", false));
126932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  std::string error;
127932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
128932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  // Module ownership is handled by the context, so we don't need to free it.
129c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien  llvm::Module *module = NULL;
130c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien
131c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien  if (mVersion >= kMinimumCompatibleVersion_LLVM_3_0) {
132c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien    module = llvm_3_0::ParseBitcodeFile(MEM.get(), *mContext, &error);
133c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien  } else if (mVersion >= kMinimumCompatibleVersion_LLVM_2_7) {
134c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien    module = llvm_2_7::ParseBitcodeFile(MEM.get(), *mContext, &error);
135c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien  } else {
13610c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block    ALOGE("No compatible bitcode reader for API version %d", mVersion);
137c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien    return false;
138c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien  }
139c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien
140932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!module) {
14110c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block    ALOGE("Could not parse bitcode file");
14210c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block    ALOGE("%s", error.c_str());
143932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return false;
144932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
145932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
146c73b5214fa71ef6e3378fa121bb8b6312d2e6d3bShih-wei Liao  std::string Buffer;
147c73b5214fa71ef6e3378fa121bb8b6312d2e6d3bShih-wei Liao
148c73b5214fa71ef6e3378fa121bb8b6312d2e6d3bShih-wei Liao  llvm::raw_string_ostream OS(Buffer);
1498dbca8e957dab1db77dffbe10c14c54d4b439be6Stephen Hines  // Use the LLVM 3.2 bitcode writer, instead of the top-of-tree version.
1508dbca8e957dab1db77dffbe10c14c54d4b439be6Stephen Hines  llvm_3_2::WriteBitcodeToFile(module, OS);
151c73b5214fa71ef6e3378fa121bb8b6312d2e6d3bShih-wei Liao  OS.flush();
152932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
1537cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  AndroidBitcodeWrapper wrapper;
1547cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  size_t actualWrapperLen = writeAndroidBitcodeWrapper(
1557cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      &wrapper, Buffer.size(), BCWrapper.getTargetAPI(),
1567cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      BCWrapper.getCompilerVersion(), BCWrapper.getOptimizationLevel());
1577cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  if (!actualWrapperLen) {
1587cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    ALOGE("Couldn't produce bitcode wrapper!");
1597cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    return false;
1607cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
1617cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
1627cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  mTranslatedBitcodeSize = actualWrapperLen + Buffer.size();
1637cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  char *c = new char[mTranslatedBitcodeSize];
1647cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  memcpy(c, &wrapper, actualWrapperLen);
165e9c850f5d85f3aa31b6e841478ea52e82d76c261Stephen Hines  memcpy(c + actualWrapperLen, Buffer.c_str(), Buffer.size());
166932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
167932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mTranslatedBitcode = c;
168932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
169932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return true;
170932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
171932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
172932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}  // namespace bcinfo
173