10164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines/*
27cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * Copyright 2011-2012, The Android Open Source Project
30164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines *
40164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines * Licensed under the Apache License, Version 2.0 (the "License");
50164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines * you may not use this file except in compliance with the License.
60164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines * You may obtain a copy of the License at
70164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines *
80164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines *     http://www.apache.org/licenses/LICENSE-2.0
90164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines *
100164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines * Unless required by applicable law or agreed to in writing, software
110164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines * distributed under the License is distributed on an "AS IS" BASIS,
120164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines * See the License for the specific language governing permissions and
140164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines * limitations under the License.
150164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines */
160164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines
170164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines#ifndef __ANDROID_BCINFO_BITCODEWRAPPER_H__
180164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines#define __ANDROID_BCINFO_BITCODEWRAPPER_H__
190164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines
207cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines#include "bcinfo/Wrap/BCHeaderField.h"
217cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
220164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines#include <cstddef>
230164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines#include <stdint.h>
240164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines
250164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hinesnamespace bcinfo {
260164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines
277cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesstruct AndroidBitcodeWrapper {
280164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  uint32_t Magic;
290164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  uint32_t Version;
300164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  uint32_t BitcodeOffset;
310164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  uint32_t BitcodeSize;
320164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  uint32_t HeaderVersion;
330164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  uint32_t TargetAPI;
347cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  uint32_t PNaClVersion;
357cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  uint16_t CompilerVersionTag;
367cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  uint16_t CompilerVersionLen;
377cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  uint32_t CompilerVersion;
387cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  uint16_t OptimizationLevelTag;
397cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  uint16_t OptimizationLevelLen;
407cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  uint32_t OptimizationLevel;
410164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines};
420164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines
430164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hinesenum BCFileType {
440164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  BC_NOT_BC = 0,
450164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  BC_WRAPPER = 1,
460164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  BC_RAW = 2
470164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines};
480164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines
490164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hinesclass BitcodeWrapper {
500164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines private:
510164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  enum BCFileType mFileType;
520164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  const char *mBitcode;
530164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  size_t mBitcodeSize;
540164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines
557cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  uint32_t mHeaderVersion;
567cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  uint32_t mTargetAPI;
577cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  uint32_t mCompilerVersion;
587cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  uint32_t mOptimizationLevel;
590164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines
600164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines public:
610164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  /**
620164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines   * Reads wrapper information from \p bitcode.
630164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines   *
640164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines   * \param bitcode - input bitcode string.
650164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines   * \param bitcodeSize - length of \p bitcode string (in bytes).
660164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines   */
670164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  BitcodeWrapper(const char *bitcode, size_t bitcodeSize);
680164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines
690164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  ~BitcodeWrapper();
700164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines
710164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  /**
727cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines   * Attempt to unwrap the target bitcode. This function is \deprecated.
730164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines   *
740164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines   * \return true on success and false if an error occurred.
750164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines   */
760164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  bool unwrap();
770164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines
780164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  /**
790164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines   * \return type of bitcode file.
800164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines   */
810164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  enum BCFileType getBCFileType() const {
820164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines    return mFileType;
830164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  }
840164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines
850164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  /**
867cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines   * \return header version of bitcode wrapper.
870164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines   */
880164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  uint32_t getHeaderVersion() const {
897cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    return mHeaderVersion;
900164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  }
910164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines
920164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  /**
937cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines   * \return target API version for this bitcode.
940164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines   */
950164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  uint32_t getTargetAPI() const {
967cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    return mTargetAPI;
977cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
987cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
997cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  /**
1007cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines   * \return compiler version that generated this bitcode.
1017cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines   */
1027cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  uint32_t getCompilerVersion() const {
1037cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    return mCompilerVersion;
1047cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
1057cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
1067cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  /**
1077cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines   * \return compiler optimization level for this bitcode.
1087cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines   */
1097cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  uint32_t getOptimizationLevel() const {
1107cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    return mOptimizationLevel;
1110164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines  }
1127cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
1130164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines};
1140164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines
1157cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines/**
1167cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * Helper function to emit just the bitcode wrapper returning the number of
1177cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * bytes that were written.
1187cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines *
1197cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * \param wrapper - where to write header information into.
1207cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * \param bitcodeSize - size of bitcode in bytes.
1217cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * \param targetAPI - target API version for this bitcode.
1227cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * \param compilerVersion - compiler version that generated this bitcode.
1237cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * \param optimizationLevel - compiler optimization level for this bitcode.
1247cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines *
1257cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * \return number of wrapper bytes written into the \p buffer.
1267cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines */
1277cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesstatic inline size_t writeAndroidBitcodeWrapper(AndroidBitcodeWrapper *wrapper,
1287cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    size_t bitcodeSize, uint32_t targetAPI, uint32_t compilerVersion,
1297cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    uint32_t optimizationLevel) {
1307cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  if (!wrapper) {
1317cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    return 0;
1327cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
1337cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
1347cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  wrapper->Magic = 0x0B17C0DE;
1357cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  wrapper->Version = 0;
1367cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  wrapper->BitcodeOffset = sizeof(*wrapper);
1377cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  wrapper->BitcodeSize = bitcodeSize;
1387cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  wrapper->HeaderVersion = 0;
1397cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  wrapper->TargetAPI = targetAPI;
1407cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  wrapper->PNaClVersion = 0;
1417cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  wrapper->CompilerVersionTag = BCHeaderField::kAndroidCompilerVersion;
1427cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  wrapper->CompilerVersionLen = 4;
1437cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  wrapper->CompilerVersion = compilerVersion;
1447cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  wrapper->OptimizationLevelTag = BCHeaderField::kAndroidOptimizationLevel;
1457cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  wrapper->OptimizationLevelLen = 4;
1467cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  wrapper->OptimizationLevel = optimizationLevel;
1477cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
1487cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  return sizeof(*wrapper);
1497cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines}
1507cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
1510164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines}  // namespace bcinfo
1520164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines
1530164f4647511a71f5b495a3bef156e3ac4e6c6b3Stephen Hines#endif  // __ANDROID_BCINFO_BITCODEWRAPPER_H__
154