17cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines/* 27cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * Copyright 2012, The Android Open Source Project 37cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * 47cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * Licensed under the Apache License, Version 2.0 (the "License"); 57cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * you may not use this file except in compliance with the License. 67cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * You may obtain a copy of the License at 77cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * 87cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * http://www.apache.org/licenses/LICENSE-2.0 97cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * 107cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * Unless required by applicable law or agreed to in writing, software 117cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * distributed under the License is distributed on an "AS IS" BASIS, 127cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * See the License for the specific language governing permissions and 147cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines * limitations under the License. 157cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines */ 167cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 177cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// Define utility class to wrap/unwrap bitcode files. Does wrapping/unwrapping 187cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// in such a way that the wrappered bitcode file is still a bitcode file. 197cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 207cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines#ifndef LLVM_WRAP_BITCODE_WRAPPERER_H__ 217cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines#define LLVM_WRAP_BITCODE_WRAPPERER_H__ 227cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 237cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines#include <stdint.h> 247cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines#include <stddef.h> 257cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines#include <vector> 267cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 277cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines#include "bcinfo/Wrap/support_macros.h" 287cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines#include "bcinfo/Wrap/BCHeaderField.h" 297cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines#include "bcinfo/Wrap/wrapper_input.h" 307cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines#include "bcinfo/Wrap/wrapper_output.h" 317cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 327cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// The bitcode wrapper header is the following 7 fixed 4-byte fields: 337cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// 1) 0B17C0DE - The magic number expected by llvm for wrapped bitcodes 347cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// 2) Version # 0 - The current version of wrapped bitcode files 357cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// 3) (raw) bitcode offset 367cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// 4) (raw) bitcode size 377cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// 5) Android header version 387cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// 6) Android target API 397cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// 7) PNaCl Bitcode version 407cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// plus 0 or more variable-length fields (consisting of ID, length, data) 417cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 427cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// Initial buffer size. It is expanded if needed to hold large variable-size 437cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// fields. 447cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesstatic const size_t kBitcodeWrappererBufferSize = 1024; 457cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 467cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// Support class for outputting a wrapped bitcode file from a raw bitcode 477cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// file (and optionally additional header fields), or for outputting a raw 487cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// bitcode file from a wrapped one. 497cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesclass BitcodeWrapperer { 507cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines public: 517cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Create a bitcode wrapperer using the following 527cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // input and output files. 537cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines BitcodeWrapperer(WrapperInput* infile, WrapperOutput* outfile); 547cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 557cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Returns true if the input file begins with a bitcode 567cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // wrapper magic number. As a side effect, _wrapper_ fields are set. 577cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines bool IsInputBitcodeWrapper(); 587cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 597cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Returns true if the input file begins with a bitcode 607cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // file magic number. 617cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines bool IsInputBitcodeFile(); 627cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 637cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Add a variable-length field to the header. The caller is responsible 647cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // for freeing the data pointed to by the BCHeaderField. 657cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines void AddHeaderField(BCHeaderField* field); 667cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 677cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Generate a wrapped bitcode file from the input bitcode file 687cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // and the current header data. Return true on success. 697cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines bool GenerateWrappedBitcodeFile(); 707cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 717cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Unwrap the wrapped bitcode file, to the corresponding 727cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // outfile. Return true on success. 737cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines bool GenerateRawBitcodeFile(); 747cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 757cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Print current wrapper header fields to stderr for debugging. 767cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines void PrintWrapperHeader(); 777cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 787cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines uint32_t getAndroidHeaderVersion() { 797cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines return android_header_version_; 807cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines } 817cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 827cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines uint32_t getAndroidTargetAPI() { 837cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines return android_target_api_; 847cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines } 857cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 867cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines uint32_t getAndroidCompilerVersion() { 877cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines return android_compiler_version_; 887cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines } 897cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 907cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines uint32_t getAndroidOptimizationLevel() { 917cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines return android_optimization_level_; 927cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines } 937cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 947cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines ~BitcodeWrapperer(); 957cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 967cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines private: 977cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines DISALLOW_CLASS_COPY_AND_ASSIGN(BitcodeWrapperer); 987cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 997cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Refills the buffer with more bytes. Does this in a way 1007cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // such that it is maximally filled. 1017cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines void FillBuffer(); 1027cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1037cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Returns the number of bytes in infile. 1041ad35fbd78f6965bb59572e1cf6a2223ee767c57Stephen Hines off_t GetInFileSize() { 1051ad35fbd78f6965bb59572e1cf6a2223ee767c57Stephen Hines if (infile_ != NULL) { 1061ad35fbd78f6965bb59572e1cf6a2223ee767c57Stephen Hines return infile_->Size(); 1071ad35fbd78f6965bb59572e1cf6a2223ee767c57Stephen Hines } else { 1081ad35fbd78f6965bb59572e1cf6a2223ee767c57Stephen Hines return 0; 1091ad35fbd78f6965bb59572e1cf6a2223ee767c57Stephen Hines } 1101ad35fbd78f6965bb59572e1cf6a2223ee767c57Stephen Hines } 1117cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1127cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Returns the offset of bitcode (i.e. the size of the wrapper header) 1137cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // if the output file were to be written now. 1147cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines size_t BitcodeOffset(); 1157cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1167cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Returns true if we can read a word. If necessary, fills the buffer 1177cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // with enough characters so that there are at least a 32-bit value 1187cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // in the buffer. Returns false if there isn't a 32-bit value 1197cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // to read from the input file. 1207cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines bool CanReadWord(); 1217cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1227cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Read a (32-bit) word from the input. Return true 1237cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // if able to read the word. 1247cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines bool ReadWord(uint32_t& word); 1257cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1267cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Write a (32-bit) word to the output. Return true if successful 1277cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines bool WriteWord(uint32_t word); 1287cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1297cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Write all variable-sized header fields to the output. Return true 1307cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // if successful. 1317cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines bool WriteVariableFields(); 1327cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1337cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Parse the bitcode wrapper header in the infile, if any. Return true 1347cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // if successful. 1357cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines bool ParseWrapperHeader(); 1367cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1377cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Returns the i-th character in front of the cursor in the buffer. 1387cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines uint8_t BufferLookahead(int i) { return buffer_[cursor_ + i]; } 1397cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1407cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Returns how many unread bytes are in the buffer. 1417cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines size_t GetBufferUnreadBytes() { return buffer_size_ - cursor_; } 1427cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1437cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1447cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Backs up the read cursor to the beginning of the input buffer. 1457cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines void ResetCursor() { 1467cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines cursor_ = 0; 1477cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines } 1487cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1497cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Generates the header sequence for the wrapped bitcode being 1507cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // generated. 1517cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines bool WriteBitcodeWrapperHeader(); 1527cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1537cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Copies size bytes of infile to outfile, using the buffer. 1547cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines bool BufferCopyInToOut(uint32_t size); 1557cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1567cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Discards the old infile and replaces it with the given file. 1577cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines void ReplaceInFile(WrapperInput* new_infile); 1587cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1597cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Discards the old outfile and replaces it with the given file. 1607cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines void ReplaceOutFile(WrapperOutput* new_outfile); 1617cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1627cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Moves to the given position in the input file. Returns false 1637cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // if unsuccessful. 1647cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines bool Seek(uint32_t pos); 1657cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1667cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Clear the buffer of all contents. 1677cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines void ClearBuffer(); 1687cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1697cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // The input file being processed. Can be either 1707cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // a bitcode file, a wrappered bitcode file, or a secondary 1717cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // file to be wrapped. 1727cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines WrapperInput* infile_; 1737cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1747cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // The output file being generated. Can be either 1757cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // a bitcode file, a wrappered bitcode file, or a secondary 1767cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // unwrapped file. 1777cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines WrapperOutput* outfile_; 1787cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1797cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // A buffer of bytes read from the input file. 1807cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines std::vector<uint8_t> buffer_; 1817cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1827cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // The number of bytes that were read from the input file 1837cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // into the buffer. 1847cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines size_t buffer_size_; 1857cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1867cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // The index to the current read point within the buffer. 1877cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines size_t cursor_; 1887cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1897cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // True when eof of input is reached. 1907cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines bool infile_at_eof_; 1917cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1927cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // The 32-bit value defining the offset of the raw bitcode in the input file. 1937cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines uint32_t infile_bc_offset_; 1947cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1957cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // The 32-bit value defining the generated offset of the wrapped bitcode. 1967cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // This value changes as new fields are added with AddHeaderField 1977cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines uint32_t wrapper_bc_offset_; 1987cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 1997cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // The 32-bit value defining the size of the raw wrapped bitcode. 2007cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines uint32_t wrapper_bc_size_; 2017cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 2027cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Android header version and target API 2037cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines uint32_t android_header_version_; 2047cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines uint32_t android_target_api_; 2057cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines uint32_t android_compiler_version_; 2067cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines uint32_t android_optimization_level_; 2077cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 2087cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // PNaCl bitcode version 2097cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines uint32_t pnacl_bc_version_; 2107cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 2117cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // Vector of variable header fields 2127cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines std::vector<BCHeaderField> header_fields_; 2137cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // If any bufferdata from header fields is owned, it is stored here and 2147cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // freed on destruction. 2157cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines std::vector<uint8_t*> variable_field_data_; 2167cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 2177cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines // True if there was an error condition (e.g. the file is not bitcode) 2187cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines bool error_; 2197cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines}; 2207cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines 2217cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines#endif // LLVM_WRAP_BITCODE_WRAPPERER_H__ 222