BitcodeTranslator.cpp revision 10c1412e6cb35cfc90abb5e36ba1340a8c55f44e
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"
31932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
32932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines#include <cstdlib>
33932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
34932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesnamespace bcinfo {
35932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
36932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines/**
37932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * Define minimum and maximum target API versions. These correspond to the
38932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * same API levels used by the standard Android SDK.
39932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines *
40c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien * LLVM 2.7
41c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien *  11 - Honeycomb
42c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien *  12 - Honeycomb MR1
43c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien *  13 - Honeycomb MR2
44c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien *
45c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien * LLVM 3.0
46c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien *  14 - Ice Cream Sandwich
47c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien *  15 - Ice Cream Sandwich MR1
48c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien *
49c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien * LLVM 3.1
50c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien *  16 - Ice Cream Sandwich MR2
51932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines */
52932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic const unsigned int kMinimumAPIVersion = 11;
53932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic const unsigned int kMaximumAPIVersion = BCINFO_API_VERSION;
54932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesstatic const unsigned int kCurrentAPIVersion = 10000;
55932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
56932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines/**
57932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * The minimum version which does not require translation (i.e. is already
58932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines * compatible with LLVM's default bitcode reader).
59932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines */
60c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chienstatic const unsigned int kMinimumUntranslatedVersion = 16;
61c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chienstatic const unsigned int kMinimumCompatibleVersion_LLVM_3_0 = 14;
62c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chienstatic const unsigned int kMinimumCompatibleVersion_LLVM_2_7 = 11;
63932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
64932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
65932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen HinesBitcodeTranslator::BitcodeTranslator(const char *bitcode, size_t bitcodeSize,
66932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines                                     unsigned int version)
67932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    : mBitcode(bitcode), mBitcodeSize(bitcodeSize), mTranslatedBitcode(NULL),
68932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      mTranslatedBitcodeSize(0), mVersion(version) {
69932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return;
70932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
71932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
72932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
73932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen HinesBitcodeTranslator::~BitcodeTranslator() {
74932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (mVersion < kMinimumUntranslatedVersion) {
75932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    // We didn't actually do a translation in the alternate case, so deleting
76932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    // the bitcode would be improper.
77932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    delete [] mTranslatedBitcode;
78932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
79932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mTranslatedBitcode = NULL;
80932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return;
81932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
82932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
83932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
84932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hinesbool BitcodeTranslator::translate() {
85932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!mBitcode || !mBitcodeSize) {
8610c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block    ALOGE("Invalid/empty bitcode");
87932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return false;
88932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
89932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
90932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if ((mVersion != kCurrentAPIVersion) &&
91932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      ((mVersion < kMinimumAPIVersion) ||
92932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines       (mVersion > kMaximumAPIVersion))) {
9310c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block    ALOGE("Invalid API version: %u is out of range ('%u' - '%u')", mVersion,
94932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines         kMinimumAPIVersion, kMaximumAPIVersion);
95932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return false;
96932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
97932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
98932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  // We currently don't need to transcode any API version higher than 14 or
99932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  // the current API version (i.e. 10000)
100932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (mVersion >= kMinimumUntranslatedVersion) {
101932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    mTranslatedBitcode = mBitcode;
102932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    mTranslatedBitcodeSize = mBitcodeSize;
103932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return true;
104932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
105932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
106932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  // Do the actual transcoding by invoking a 2.7-era bitcode reader that can
107932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  // then write the bitcode back out in a more modern (acceptable) version.
108932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  llvm::OwningPtr<llvm::LLVMContext> mContext(new llvm::LLVMContext());
109932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  llvm::OwningPtr<llvm::MemoryBuffer> MEM(
110932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    llvm::MemoryBuffer::getMemBuffer(
111932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines      llvm::StringRef(mBitcode, mBitcodeSize)));
112932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  std::string error;
113932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
114932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  // Module ownership is handled by the context, so we don't need to free it.
115c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien  llvm::Module *module = NULL;
116c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien
117c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien  if (mVersion >= kMinimumCompatibleVersion_LLVM_3_0) {
118c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien    module = llvm_3_0::ParseBitcodeFile(MEM.get(), *mContext, &error);
119c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien  } else if (mVersion >= kMinimumCompatibleVersion_LLVM_2_7) {
120c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien    module = llvm_2_7::ParseBitcodeFile(MEM.get(), *mContext, &error);
121c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien  } else {
12210c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block    ALOGE("No compatible bitcode reader for API version %d", mVersion);
123c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien    return false;
124c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien  }
125c7d67a701663191bcdab2416c11b69fae16d49fbLogan Chien
126932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  if (!module) {
12710c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block    ALOGE("Could not parse bitcode file");
12810c1412e6cb35cfc90abb5e36ba1340a8c55f44eSteve Block    ALOGE("%s", error.c_str());
129932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines    return false;
130932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  }
131932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
132932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  std::vector<unsigned char> Buffer;
133932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  llvm::BitstreamWriter Stream(Buffer);
134932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  Buffer.reserve(mBitcodeSize);
135932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  llvm::WriteBitcodeToStream(module, Stream);
136932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
137932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  char *c = new char[Buffer.size()];
138932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  memcpy(c, &Buffer.front(), Buffer.size());
139932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
140932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mTranslatedBitcode = c;
141932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  mTranslatedBitcodeSize = Buffer.size();
142932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
143932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines  return true;
144932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}
145932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
146932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines}  // namespace bcinfo
147932bc6e35bcef7adff05d890a9dcc7212426fb6aStephen Hines
148