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