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#include "bcinfo/Wrap/bitcode_wrapperer.h"
187cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
197cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines#define LOG_TAG "bcinfo"
207cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines#include <cutils/log.h>
217cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
227cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines#include <stdio.h>
237cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines#include <sys/stat.h>
247cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
257cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesusing std::vector;
267cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
277cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// The number of bytes in a 32 bit integer.
287cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesstatic const uint32_t kWordSize = 4;
297cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
307cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// Number of LLVM-defined fixed fields in the header.
317cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesstatic const uint32_t kLLVMFields = 4;
327cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
337cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// Total number of fixed fields in the header.
347cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesstatic const uint32_t kFixedFields = 7;
357cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
367cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// The magic number that must exist for bitcode wrappers.
377cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesstatic const uint32_t kWrapperMagicNumber = 0x0B17C0DE;
387cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
397cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// The version number associated with a wrapper file.
407cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// Note: llvm currently only allows the value 0. When this changes,
417cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// we should consider making this a command line option.
427cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesstatic const uint32_t kLLVMVersionNumber = 0;
437cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
447cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// Fields defined by Android bitcode header.
457cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesstatic const uint32_t kAndroidHeaderVersion = 0;
467cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesstatic const uint32_t kAndroidTargetAPI = 0;
477cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesstatic const uint32_t kAndroidDefaultCompilerVersion = 0;
487cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesstatic const uint32_t kAndroidDefaultOptimizationLevel = 3;
497cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
507cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// PNaCl bitcode version number.
517cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesstatic const uint32_t kPnaclBitcodeVersion = 0;
527cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
537cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// Max size for variable fields. Currently only used for writing them
547cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines// out to files (the parsing works for arbitrary sizes).
557cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesstatic const size_t kMaxVariableFieldSize = 256;
567cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
577cd4c49d575478b2380f129dcd376a4e5e37939cStephen HinesBitcodeWrapperer::BitcodeWrapperer(WrapperInput* infile, WrapperOutput* outfile)
587cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    : infile_(infile),
597cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      outfile_(outfile),
607cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      buffer_size_(0),
617cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      cursor_(0),
627cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      infile_at_eof_(false),
637cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      infile_bc_offset_(0),
647cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      wrapper_bc_offset_(0),
657cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      wrapper_bc_size_(0),
667cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      android_header_version_(kAndroidHeaderVersion),
677cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      android_target_api_(kAndroidTargetAPI),
687cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      android_compiler_version_(kAndroidDefaultCompilerVersion),
697cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      android_optimization_level_(kAndroidDefaultOptimizationLevel),
707cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      pnacl_bc_version_(0),
717cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      error_(false) {
727cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  buffer_.resize(kBitcodeWrappererBufferSize);
737cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  if (IsInputBitcodeWrapper()) {
747cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    ParseWrapperHeader();
757cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  } else if (IsInputBitcodeFile()) {
767cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    wrapper_bc_offset_ = kWordSize * kFixedFields;
777cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    wrapper_bc_size_ = GetInFileSize();
787cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  } else {
797cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    ALOGE("Error: input file is not a bitcode file.\n");
807cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    error_ = true;
817cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
827cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines}
837cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
847cd4c49d575478b2380f129dcd376a4e5e37939cStephen HinesBitcodeWrapperer::~BitcodeWrapperer() {
857cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  for(size_t i = 0; i < variable_field_data_.size(); i++) {
867cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    delete [] variable_field_data_[i];
877cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
887cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines}
897cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
907cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
917cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesvoid BitcodeWrapperer::ClearBuffer() {
927cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  buffer_size_ = 0;
937cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  cursor_ = 0;
947cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  infile_at_eof_ = false;
957cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines}
967cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
977cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesbool BitcodeWrapperer::Seek(uint32_t pos) {
981ad35fbd78f6965bb59572e1cf6a2223ee767c57Stephen Hines  if (infile_ != NULL && infile_->Seek(pos)) {
997cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    ClearBuffer();
1007cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    return true;
1017cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
1027cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  return false;
1037cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines}
1047cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
1057cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesbool BitcodeWrapperer::CanReadWord() {
1067cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  if (GetBufferUnreadBytes() < kWordSize) {
1077cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    FillBuffer();
1087cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    return GetBufferUnreadBytes() >= kWordSize;
1097cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  } else {
1107cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    return true;
1117cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
1127cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines}
1137cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
1147cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesvoid BitcodeWrapperer::FillBuffer() {
1157cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  if (cursor_ > 0) {
1167cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    // Before filling, move any remaining bytes to the
1177cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    // front of the buffer. This allows us to assume
1187cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    // that after the call to FillBuffer, readable
1197cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    // text is contiguous.
1207cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    if (cursor_ < buffer_size_) {
1217cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      size_t i = 0;
1227cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      while (cursor_ < buffer_size_) {
1237cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines        buffer_[i++] = buffer_[cursor_++];
1247cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      }
1257cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      cursor_ = 0;
1267cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      buffer_size_ = i;
1277cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    }
1287cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  } else {
1297cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    // Assume the buffer contents have been used,
1307cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    // and we want to completely refill it.
1317cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    buffer_size_ = 0;
1327cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
1337cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
1341ad35fbd78f6965bb59572e1cf6a2223ee767c57Stephen Hines  // If we don't have an input, we can't refill the buffer at all.
1351ad35fbd78f6965bb59572e1cf6a2223ee767c57Stephen Hines  if (infile_ == NULL) {
1361ad35fbd78f6965bb59572e1cf6a2223ee767c57Stephen Hines    return;
1371ad35fbd78f6965bb59572e1cf6a2223ee767c57Stephen Hines  }
1381ad35fbd78f6965bb59572e1cf6a2223ee767c57Stephen Hines
1397cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  // Now fill in remaining space.
1407cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  size_t needed = buffer_.size() - buffer_size_;
1417cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
1427cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  while (buffer_.size() > buffer_size_) {
1437cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    int actually_read = infile_->Read(&buffer_[buffer_size_], needed);
1447cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    if (infile_->AtEof()) {
1457cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      infile_at_eof_ = true;
1467cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    }
1477cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    if (actually_read) {
1487cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      buffer_size_ += actually_read;
1497cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      needed -= actually_read;
1507cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    } else if (infile_at_eof_) {
1517cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      break;
1527cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    }
1537cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
1547cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines}
1557cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
1567cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesbool BitcodeWrapperer::ReadWord(uint32_t& word) {
1577cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  if (!CanReadWord()) return false;
1587cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  word = (((uint32_t) BufferLookahead(0)) << 0)
1597cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      | (((uint32_t) BufferLookahead(1)) << 8)
1607cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      | (((uint32_t) BufferLookahead(2)) << 16)
1617cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      | (((uint32_t) BufferLookahead(3)) << 24);
1627cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  cursor_ += kWordSize;
1637cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  return true;
1647cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines}
1657cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
1667cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesbool BitcodeWrapperer::WriteWord(uint32_t value) {
1677cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  uint8_t buffer[kWordSize];
1687cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  buffer[3] = (value >> 24) & 0xFF;
1697cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  buffer[2] = (value >> 16) & 0xFF;
1707cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  buffer[1] = (value >> 8)  & 0xFF;
1717cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  buffer[0] = (value >> 0)  & 0xFF;
1727cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  return outfile_->Write(buffer, kWordSize);
1737cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines}
1747cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
1757cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesbool BitcodeWrapperer::WriteVariableFields() {
1767cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  // This buffer may have to be bigger if we start using the fields
1777cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  // for larger things.
1787cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  uint8_t buffer[kMaxVariableFieldSize];
1797cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  for (vector<BCHeaderField>::iterator it = header_fields_.begin();
1807cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines       it != header_fields_.end(); ++it) {
1817cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    if (!it->Write(buffer, kMaxVariableFieldSize) ||
1827cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines        !outfile_->Write(buffer, it->GetTotalSize())) {
1837cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      return false;
1847cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    }
1857cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
1867cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  return true;
1877cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines}
1887cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
1897cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesbool BitcodeWrapperer::ParseWrapperHeader() {
1907cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  // Make sure LLVM-defined fields have been parsed
1917cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  if (!IsInputBitcodeWrapper()) return false;
1927cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  // Check the android/pnacl fields
1937cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  if (!ReadWord(android_header_version_) ||
1947cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      !ReadWord(android_target_api_) || !ReadWord(pnacl_bc_version_)) {
1957cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    ALOGW("Error: file not long enough to contain header\n");
1967cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    return false;
1977cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
1987cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  if (pnacl_bc_version_ != kPnaclBitcodeVersion) {
1997cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    ALOGW("Error: bad PNaCl Bitcode version\n");
2007cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    return false;
2017cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
2027cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  int field_data_total = wrapper_bc_offset_ - kWordSize * kFixedFields;
2037cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  if (field_data_total > 0) {
2047cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    // Read in the variable fields. We need to allocate space for the data.
2057cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    int field_data_read = 0;
2067cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
2077cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    while (field_data_read < field_data_total) {
2087cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      FillBuffer();
2097cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      size_t buffer_needed = BCHeaderField::GetDataSizeFromSerialized(
2107cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines          &buffer_[cursor_]);
2117cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      if (buffer_needed > buffer_.size()) {
2127cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines        buffer_.resize(buffer_needed +
2137cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines                       sizeof(BCHeaderField::FixedSubfield) * 2);
2147cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines        FillBuffer();
2157cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      }
2167cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      variable_field_data_.push_back(new uint8_t[buffer_needed]);
2177cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
2187cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      BCHeaderField field(BCHeaderField::kInvalid, 0,
2197cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines                          variable_field_data_.back());
2207cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      field.Read(&buffer_[cursor_], buffer_size_);
2217cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      header_fields_.push_back(field);
2227cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      size_t field_size = field.GetTotalSize();
2237cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      cursor_ += field_size;
2247cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      field_data_read += field_size;
2257cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      if (field_data_read > field_data_total) {
2267cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines        // We read too much data, the header is corrupted
2277cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines        ALOGE("Error: raw bitcode offset inconsistent with "
2287cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines              "variable field data\n");
2297cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines        return false;
2307cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      }
2317cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
2327cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      struct IntFieldHelper {
2337cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines        BCHeaderField::FixedSubfield tag;
2347cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines        uint16_t len;
2357cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines        uint32_t val;
2367cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      };
2377cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      IntFieldHelper tempIntField;
2387cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
2397cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      switch (field.getID()) {
2407cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines        case BCHeaderField::kAndroidCompilerVersion:
2417cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines          if (field.Write((uint8_t*)&tempIntField,
2427cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines                          sizeof(tempIntField))) {
2437cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines            android_compiler_version_ = tempIntField.val;
2447cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines          }
2457cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines          break;
2467cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines        case BCHeaderField::kAndroidOptimizationLevel:
2477cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines          if (field.Write((uint8_t*)&tempIntField,
2487cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines                          sizeof(tempIntField))) {
2497cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines            android_optimization_level_ = tempIntField.val;
2507cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines          }
2517cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines          break;
2527cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines        default:
2537cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines          // Ignore other field types for now
2547cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines          break;
2557cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      }
2567cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    }
2577cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    Seek(0);
2587cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
2597cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  return true;
2607cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines}
2617cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
2627cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesbool BitcodeWrapperer::IsInputBitcodeWrapper() {
2637cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  ResetCursor();
2647cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  // First make sure that there are enough words (LLVM header)
2657cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  // to peek at.
2667cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  if (GetBufferUnreadBytes() < kLLVMFields * kWordSize) {
2677cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    FillBuffer();
2687cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    if (GetBufferUnreadBytes() < kLLVMFields * kWordSize) return false;
2697cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
2707cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
2717cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  // Now make sure the magic number is right.
2727cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  uint32_t first_word;
2737cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  if ((!ReadWord(first_word)) ||
2747cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      (kWrapperMagicNumber != first_word)) return false;
2757cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
2767cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  // Make sure the version is right.
2777cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  uint32_t second_word;
2787cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  if ((!ReadWord(second_word)) ||
2797cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      (kLLVMVersionNumber != second_word)) return false;
2807cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
2817cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  // Make sure that the offset and size (for llvm) is defined.
2827cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  uint32_t bc_offset;
2837cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  uint32_t bc_size;
2847cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  if (ReadWord(bc_offset) &&
2857cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      ReadWord(bc_size)) {
2867cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    // Before returning, save the extracted values.
2877cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    wrapper_bc_offset_ = bc_offset;
2887cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    infile_bc_offset_ = bc_offset;
2897cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    wrapper_bc_size_ = bc_size;
2907cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    return true;
2917cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
2927cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  // If reached, unable to read wrapped header.
2937cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  return false;
2947cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines}
2957cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
2967cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesbool BitcodeWrapperer::IsInputBitcodeFile() {
2977cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  ResetCursor();
2987cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  // First make sure that there are four bytes to peek at.
2997cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  if (GetBufferUnreadBytes() < kWordSize) {
3007cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    FillBuffer();
3017cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    if (GetBufferUnreadBytes() < kWordSize) return false;
3027cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
3037cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  // If reached, Check if first 4 bytes match bitcode
3047cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  // file magic number.
3057cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  return (BufferLookahead(0) == 'B') &&
3067cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      (BufferLookahead(1) == 'C') &&
3077cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      (BufferLookahead(2) == 0xc0) &&
3087cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      (BufferLookahead(3) == 0xde);
3097cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines}
3107cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
3117cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesbool BitcodeWrapperer::BufferCopyInToOut(uint32_t size) {
3127cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  while (size > 0) {
3137cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    // Be sure buffer is non-empty before writing.
3147cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    if (0 == buffer_size_) {
3157cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      FillBuffer();
3167cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      if (0 == buffer_size_) {
3177cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines        return false;
3187cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      }
3197cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    }
3207cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    // copy the buffer to the output file.
3217cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    size_t block = (buffer_size_ < size) ? buffer_size_ : size;
3227cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    if (!outfile_->Write(&buffer_[cursor_], block)) return false;
3237cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    size -= block;
3247cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    buffer_size_ = 0;
3257cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
3267cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  // Be sure that there isn't more bytes on the input stream.
3277cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  FillBuffer();
3287cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  return buffer_size_ == 0;
3297cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines}
3307cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
3317cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesvoid BitcodeWrapperer::AddHeaderField(BCHeaderField* field) {
3327cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  header_fields_.push_back(*field);
3337cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  wrapper_bc_offset_ += field->GetTotalSize();
3347cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines}
3357cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
3367cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesbool BitcodeWrapperer::WriteBitcodeWrapperHeader() {
3377cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  return
3387cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      // Note: This writes out the 4 word header required by llvm wrapped
3397cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      // bitcode.
3407cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      WriteWord(kWrapperMagicNumber) &&
3417cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      WriteWord(kLLVMVersionNumber) &&
3427cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      WriteWord(wrapper_bc_offset_) &&
3437cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      WriteWord(wrapper_bc_size_) &&
3447cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      // 2 fixed fields defined by Android
3457cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      WriteWord(android_header_version_) &&
3467cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      WriteWord(android_target_api_) &&
3477cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      // PNaClBitcode version
3487cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      WriteWord(kPnaclBitcodeVersion) &&
3497cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      // Common variable-length fields
3507cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      WriteVariableFields();
3517cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines}
3527cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
3537cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesvoid BitcodeWrapperer::PrintWrapperHeader() {
3547cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  if (error_) {
3557cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    fprintf(stderr, "Error condition exists: the following"
3567cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines            "data may not be reliable\n");
3577cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
3587cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  fprintf(stderr, "Wrapper magic:\t\t%x\n", kWrapperMagicNumber);
3597cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  fprintf(stderr, "LLVM Bitcode version:\t%d\n", kLLVMVersionNumber);
3607cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  fprintf(stderr, "Raw bitcode offset:\t%d\n", wrapper_bc_offset_);
3617cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  fprintf(stderr, "Raw bitcode size:\t%d\n", wrapper_bc_size_);
3627cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  fprintf(stderr, "Android header version:\t%d\n", android_header_version_);
3637cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  fprintf(stderr, "Android target API:\t%d\n", android_target_api_);
3647cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  fprintf(stderr, "PNaCl bitcode version:\t%d\n", kPnaclBitcodeVersion);
3657cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  for (size_t i = 0; i < header_fields_.size(); i++) header_fields_[i].Print();
3667cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines}
3677cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
3687cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesbool BitcodeWrapperer::GenerateWrappedBitcodeFile() {
3697cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  if (!error_ &&
3707cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      WriteBitcodeWrapperHeader() &&
3717cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      Seek(infile_bc_offset_) &&
3727cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      BufferCopyInToOut(wrapper_bc_size_)) {
3737cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    off_t dangling = wrapper_bc_size_ & 3;
3747cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    if (dangling) {
3757cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      return outfile_->Write((const uint8_t*) "\0\0\0\0", 4 - dangling);
3767cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    }
3777cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines    return true;
3787cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  }
3797cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  return false;
3807cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines}
3817cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines
3827cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hinesbool BitcodeWrapperer::GenerateRawBitcodeFile() {
3837cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines  return !error_ && Seek(infile_bc_offset_) &&
3847cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines      BufferCopyInToOut(wrapper_bc_size_);
3857cd4c49d575478b2380f129dcd376a4e5e37939cStephen Hines}
386