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