1 /* 2 * Copyright 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 // Define utility class to wrap/unwrap bitcode files. Does wrapping/unwrapping 18 // in such a way that the wrappered bitcode file is still a bitcode file. 19 20 #ifndef LLVM_WRAP_BITCODE_WRAPPERER_H__ 21 #define LLVM_WRAP_BITCODE_WRAPPERER_H__ 22 23 #include <stdint.h> 24 #include <stddef.h> 25 #include <vector> 26 27 #include "bcinfo/Wrap/support_macros.h" 28 #include "bcinfo/Wrap/BCHeaderField.h" 29 #include "bcinfo/Wrap/wrapper_input.h" 30 #include "bcinfo/Wrap/wrapper_output.h" 31 32 // The bitcode wrapper header is the following 7 fixed 4-byte fields: 33 // 1) 0B17C0DE - The magic number expected by llvm for wrapped bitcodes 34 // 2) Version # 0 - The current version of wrapped bitcode files 35 // 3) (raw) bitcode offset 36 // 4) (raw) bitcode size 37 // 5) Android header version 38 // 6) Android target API 39 // 7) PNaCl Bitcode version 40 // plus 0 or more variable-length fields (consisting of ID, length, data) 41 42 // Initial buffer size. It is expanded if needed to hold large variable-size 43 // fields. 44 static const size_t kBitcodeWrappererBufferSize = 1024; 45 46 // Support class for outputting a wrapped bitcode file from a raw bitcode 47 // file (and optionally additional header fields), or for outputting a raw 48 // bitcode file from a wrapped one. 49 class BitcodeWrapperer { 50 public: 51 // Create a bitcode wrapperer using the following 52 // input and output files. 53 BitcodeWrapperer(WrapperInput* infile, WrapperOutput* outfile); 54 55 // Returns true if the input file begins with a bitcode 56 // wrapper magic number. As a side effect, _wrapper_ fields are set. 57 bool IsInputBitcodeWrapper(); 58 59 // Returns true if the input file begins with a bitcode 60 // file magic number. 61 bool IsInputBitcodeFile(); 62 63 // Add a variable-length field to the header. The caller is responsible 64 // for freeing the data pointed to by the BCHeaderField. 65 void AddHeaderField(BCHeaderField* field); 66 67 // Generate a wrapped bitcode file from the input bitcode file 68 // and the current header data. Return true on success. 69 bool GenerateWrappedBitcodeFile(); 70 71 // Unwrap the wrapped bitcode file, to the corresponding 72 // outfile. Return true on success. 73 bool GenerateRawBitcodeFile(); 74 75 // Print current wrapper header fields to stderr for debugging. 76 void PrintWrapperHeader(); 77 getAndroidHeaderVersion()78 uint32_t getAndroidHeaderVersion() { 79 return android_header_version_; 80 } 81 getAndroidTargetAPI()82 uint32_t getAndroidTargetAPI() { 83 return android_target_api_; 84 } 85 getAndroidCompilerVersion()86 uint32_t getAndroidCompilerVersion() { 87 return android_compiler_version_; 88 } 89 getAndroidOptimizationLevel()90 uint32_t getAndroidOptimizationLevel() { 91 return android_optimization_level_; 92 } 93 94 ~BitcodeWrapperer(); 95 96 private: 97 DISALLOW_CLASS_COPY_AND_ASSIGN(BitcodeWrapperer); 98 99 // Refills the buffer with more bytes. Does this in a way 100 // such that it is maximally filled. 101 void FillBuffer(); 102 103 // Returns the number of bytes in infile. GetInFileSize()104 off_t GetInFileSize() { 105 if (infile_ != nullptr) { 106 return infile_->Size(); 107 } else { 108 return 0; 109 } 110 } 111 112 // Returns the offset of bitcode (i.e. the size of the wrapper header) 113 // if the output file were to be written now. 114 size_t BitcodeOffset(); 115 116 // Returns true if we can read a word. If necessary, fills the buffer 117 // with enough characters so that there are at least a 32-bit value 118 // in the buffer. Returns false if there isn't a 32-bit value 119 // to read from the input file. 120 bool CanReadWord(); 121 122 // Read a (32-bit) word from the input. Return true 123 // if able to read the word. 124 bool ReadWord(uint32_t& word); 125 126 // Write a (32-bit) word to the output. Return true if successful 127 bool WriteWord(uint32_t word); 128 129 // Write all variable-sized header fields to the output. Return true 130 // if successful. 131 bool WriteVariableFields(); 132 133 // Parse the bitcode wrapper header in the infile, if any. Return true 134 // if successful. 135 bool ParseWrapperHeader(); 136 137 // Returns the i-th character in front of the cursor in the buffer. BufferLookahead(int i)138 uint8_t BufferLookahead(int i) { return buffer_[cursor_ + i]; } 139 140 // Returns how many unread bytes are in the buffer. GetBufferUnreadBytes()141 size_t GetBufferUnreadBytes() { return buffer_size_ - cursor_; } 142 143 144 // Backs up the read cursor to the beginning of the input buffer. ResetCursor()145 void ResetCursor() { 146 cursor_ = 0; 147 } 148 149 // Generates the header sequence for the wrapped bitcode being 150 // generated. 151 bool WriteBitcodeWrapperHeader(); 152 153 // Copies size bytes of infile to outfile, using the buffer. 154 bool BufferCopyInToOut(uint32_t size); 155 156 // Discards the old infile and replaces it with the given file. 157 void ReplaceInFile(WrapperInput* new_infile); 158 159 // Discards the old outfile and replaces it with the given file. 160 void ReplaceOutFile(WrapperOutput* new_outfile); 161 162 // Moves to the given position in the input file. Returns false 163 // if unsuccessful. 164 bool Seek(uint32_t pos); 165 166 // Clear the buffer of all contents. 167 void ClearBuffer(); 168 169 // The input file being processed. Can be either 170 // a bitcode file, a wrappered bitcode file, or a secondary 171 // file to be wrapped. 172 WrapperInput* infile_; 173 174 // The output file being generated. Can be either 175 // a bitcode file, a wrappered bitcode file, or a secondary 176 // unwrapped file. 177 WrapperOutput* outfile_; 178 179 // A buffer of bytes read from the input file. 180 std::vector<uint8_t> buffer_; 181 182 // The number of bytes that were read from the input file 183 // into the buffer. 184 size_t buffer_size_; 185 186 // The index to the current read point within the buffer. 187 size_t cursor_; 188 189 // True when eof of input is reached. 190 bool infile_at_eof_; 191 192 // The 32-bit value defining the offset of the raw bitcode in the input file. 193 uint32_t infile_bc_offset_; 194 195 // The 32-bit value defining the generated offset of the wrapped bitcode. 196 // This value changes as new fields are added with AddHeaderField 197 uint32_t wrapper_bc_offset_; 198 199 // The 32-bit value defining the size of the raw wrapped bitcode. 200 uint32_t wrapper_bc_size_; 201 202 // Android header version and target API 203 uint32_t android_header_version_; 204 uint32_t android_target_api_; 205 uint32_t android_compiler_version_; 206 uint32_t android_optimization_level_; 207 208 // PNaCl bitcode version 209 uint32_t pnacl_bc_version_; 210 211 // Vector of variable header fields 212 std::vector<BCHeaderField> header_fields_; 213 // If any bufferdata from header fields is owned, it is stored here and 214 // freed on destruction. 215 std::vector<uint8_t*> variable_field_data_; 216 217 // True if there was an error condition (e.g. the file is not bitcode) 218 bool error_; 219 }; 220 221 #endif // LLVM_WRAP_BITCODE_WRAPPERER_H__ 222