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#ifndef __ANDROID_BCINFO_BITCODEWRAPPER_H__
18#define __ANDROID_BCINFO_BITCODEWRAPPER_H__
19
20#include "bcinfo/Wrap/BCHeaderField.h"
21
22#include <cstddef>
23#include <stdint.h>
24
25namespace bcinfo {
26
27struct AndroidBitcodeWrapper {
28  uint32_t Magic;
29  uint32_t Version;
30  uint32_t BitcodeOffset;
31  uint32_t BitcodeSize;
32  uint32_t HeaderVersion;
33  uint32_t TargetAPI;
34  uint32_t PNaClVersion;
35  uint16_t CompilerVersionTag;
36  uint16_t CompilerVersionLen;
37  uint32_t CompilerVersion;
38  uint16_t OptimizationLevelTag;
39  uint16_t OptimizationLevelLen;
40  uint32_t OptimizationLevel;
41};
42
43enum BCFileType {
44  BC_NOT_BC = 0,
45  BC_WRAPPER = 1,
46  BC_RAW = 2
47};
48
49class BitcodeWrapper {
50 private:
51  enum BCFileType mFileType;
52  const char *mBitcode;
53  size_t mBitcodeSize;
54
55  uint32_t mHeaderVersion;
56  uint32_t mTargetAPI;
57  uint32_t mCompilerVersion;
58  uint32_t mOptimizationLevel;
59
60 public:
61  /**
62   * Reads wrapper information from \p bitcode.
63   *
64   * \param bitcode - input bitcode string.
65   * \param bitcodeSize - length of \p bitcode string (in bytes).
66   */
67  BitcodeWrapper(const char *bitcode, size_t bitcodeSize);
68
69  ~BitcodeWrapper();
70
71  /**
72   * Attempt to unwrap the target bitcode. This function is \deprecated.
73   *
74   * \return true on success and false if an error occurred.
75   */
76  bool unwrap();
77
78  /**
79   * \return type of bitcode file.
80   */
81  enum BCFileType getBCFileType() const {
82    return mFileType;
83  }
84
85  /**
86   * \return header version of bitcode wrapper.
87   */
88  uint32_t getHeaderVersion() const {
89    return mHeaderVersion;
90  }
91
92  /**
93   * \return target API version for this bitcode.
94   */
95  uint32_t getTargetAPI() const {
96    return mTargetAPI;
97  }
98
99  /**
100   * \return compiler version that generated this bitcode.
101   */
102  uint32_t getCompilerVersion() const {
103    return mCompilerVersion;
104  }
105
106  /**
107   * \return compiler optimization level for this bitcode.
108   */
109  uint32_t getOptimizationLevel() const {
110    return mOptimizationLevel;
111  }
112
113};
114
115/**
116 * Helper function to emit just the bitcode wrapper returning the number of
117 * bytes that were written.
118 *
119 * \param wrapper - where to write header information into.
120 * \param bitcodeSize - size of bitcode in bytes.
121 * \param targetAPI - target API version for this bitcode.
122 * \param compilerVersion - compiler version that generated this bitcode.
123 * \param optimizationLevel - compiler optimization level for this bitcode.
124 *
125 * \return number of wrapper bytes written into the \p buffer.
126 */
127static inline size_t writeAndroidBitcodeWrapper(AndroidBitcodeWrapper *wrapper,
128    size_t bitcodeSize, uint32_t targetAPI, uint32_t compilerVersion,
129    uint32_t optimizationLevel) {
130  if (!wrapper) {
131    return 0;
132  }
133
134  wrapper->Magic = 0x0B17C0DE;
135  wrapper->Version = 0;
136  wrapper->BitcodeOffset = sizeof(*wrapper);
137  wrapper->BitcodeSize = bitcodeSize;
138  wrapper->HeaderVersion = 0;
139  wrapper->TargetAPI = targetAPI;
140  wrapper->PNaClVersion = 0;
141  wrapper->CompilerVersionTag = BCHeaderField::kAndroidCompilerVersion;
142  wrapper->CompilerVersionLen = 4;
143  wrapper->CompilerVersion = compilerVersion;
144  wrapper->OptimizationLevelTag = BCHeaderField::kAndroidOptimizationLevel;
145  wrapper->OptimizationLevelLen = 4;
146  wrapper->OptimizationLevel = optimizationLevel;
147
148  return sizeof(*wrapper);
149}
150
151}  // namespace bcinfo
152
153#endif  // __ANDROID_BCINFO_BITCODEWRAPPER_H__
154