Home | History | Annotate | Download | only in Wrap
      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 
     78   uint32_t getAndroidHeaderVersion() {
     79     return android_header_version_;
     80   }
     81 
     82   uint32_t getAndroidTargetAPI() {
     83     return android_target_api_;
     84   }
     85 
     86   uint32_t getAndroidCompilerVersion() {
     87     return android_compiler_version_;
     88   }
     89 
     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.
    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.
    138   uint8_t BufferLookahead(int i) { return buffer_[cursor_ + i]; }
    139 
    140   // Returns how many unread bytes are in the buffer.
    141   size_t GetBufferUnreadBytes() { return buffer_size_ - cursor_; }
    142 
    143 
    144   // Backs up the read cursor to the beginning of the input buffer.
    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