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#include "bcinfo/Wrap/bitcode_wrapperer.h" 18 19#define LOG_TAG "bcinfo" 20 21#include <stdio.h> 22#include <sys/stat.h> 23 24#include <log/log.h> 25 26using std::vector; 27 28// The number of bytes in a 32 bit integer. 29static const uint32_t kWordSize = 4; 30 31// Number of LLVM-defined fixed fields in the header. 32static const uint32_t kLLVMFields = 4; 33 34// Total number of fixed fields in the header. 35static const uint32_t kFixedFields = 7; 36 37// The magic number that must exist for bitcode wrappers. 38static const uint32_t kWrapperMagicNumber = 0x0B17C0DE; 39 40// The version number associated with a wrapper file. 41// Note: llvm currently only allows the value 0. When this changes, 42// we should consider making this a command line option. 43static const uint32_t kLLVMVersionNumber = 0; 44 45// Fields defined by Android bitcode header. 46static const uint32_t kAndroidHeaderVersion = 0; 47static const uint32_t kAndroidTargetAPI = 0; 48static const uint32_t kAndroidDefaultCompilerVersion = 0; 49static const uint32_t kAndroidDefaultOptimizationLevel = 3; 50 51// PNaCl bitcode version number. 52static const uint32_t kPnaclBitcodeVersion = 0; 53 54// Max size for variable fields. Currently only used for writing them 55// out to files (the parsing works for arbitrary sizes). 56static const size_t kMaxVariableFieldSize = 256; 57 58BitcodeWrapperer::BitcodeWrapperer(WrapperInput* infile, WrapperOutput* outfile) 59 : infile_(infile), 60 outfile_(outfile), 61 buffer_size_(0), 62 cursor_(0), 63 infile_at_eof_(false), 64 infile_bc_offset_(0), 65 wrapper_bc_offset_(0), 66 wrapper_bc_size_(0), 67 android_header_version_(kAndroidHeaderVersion), 68 android_target_api_(kAndroidTargetAPI), 69 android_compiler_version_(kAndroidDefaultCompilerVersion), 70 android_optimization_level_(kAndroidDefaultOptimizationLevel), 71 pnacl_bc_version_(0), 72 error_(false) { 73 buffer_.resize(kBitcodeWrappererBufferSize); 74 if (IsInputBitcodeWrapper()) { 75 ParseWrapperHeader(); 76 } else if (IsInputBitcodeFile()) { 77 wrapper_bc_offset_ = kWordSize * kFixedFields; 78 wrapper_bc_size_ = GetInFileSize(); 79 } else { 80 ALOGE("Error: input file is not a bitcode file.\n"); 81 error_ = true; 82 } 83} 84 85BitcodeWrapperer::~BitcodeWrapperer() { 86 for(size_t i = 0; i < variable_field_data_.size(); i++) { 87 delete [] variable_field_data_[i]; 88 } 89} 90 91 92void BitcodeWrapperer::ClearBuffer() { 93 buffer_size_ = 0; 94 cursor_ = 0; 95 infile_at_eof_ = false; 96} 97 98bool BitcodeWrapperer::Seek(uint32_t pos) { 99 if (infile_ != nullptr && infile_->Seek(pos)) { 100 ClearBuffer(); 101 return true; 102 } 103 return false; 104} 105 106bool BitcodeWrapperer::CanReadWord() { 107 if (GetBufferUnreadBytes() < kWordSize) { 108 FillBuffer(); 109 return GetBufferUnreadBytes() >= kWordSize; 110 } else { 111 return true; 112 } 113} 114 115void BitcodeWrapperer::FillBuffer() { 116 if (cursor_ > 0) { 117 // Before filling, move any remaining bytes to the 118 // front of the buffer. This allows us to assume 119 // that after the call to FillBuffer, readable 120 // text is contiguous. 121 if (cursor_ < buffer_size_) { 122 size_t i = 0; 123 while (cursor_ < buffer_size_) { 124 buffer_[i++] = buffer_[cursor_++]; 125 } 126 cursor_ = 0; 127 buffer_size_ = i; 128 } 129 } else { 130 // Assume the buffer contents have been used, 131 // and we want to completely refill it. 132 buffer_size_ = 0; 133 } 134 135 // If we don't have an input, we can't refill the buffer at all. 136 if (infile_ == nullptr) { 137 return; 138 } 139 140 // Now fill in remaining space. 141 size_t needed = buffer_.size() - buffer_size_; 142 143 while (buffer_.size() > buffer_size_) { 144 int actually_read = infile_->Read(&buffer_[buffer_size_], needed); 145 if (infile_->AtEof()) { 146 infile_at_eof_ = true; 147 } 148 if (actually_read) { 149 buffer_size_ += actually_read; 150 needed -= actually_read; 151 } else if (infile_at_eof_) { 152 break; 153 } 154 } 155} 156 157bool BitcodeWrapperer::ReadWord(uint32_t& word) { 158 if (!CanReadWord()) return false; 159 word = (((uint32_t) BufferLookahead(0)) << 0) 160 | (((uint32_t) BufferLookahead(1)) << 8) 161 | (((uint32_t) BufferLookahead(2)) << 16) 162 | (((uint32_t) BufferLookahead(3)) << 24); 163 cursor_ += kWordSize; 164 return true; 165} 166 167bool BitcodeWrapperer::WriteWord(uint32_t value) { 168 uint8_t buffer[kWordSize]; 169 buffer[3] = (value >> 24) & 0xFF; 170 buffer[2] = (value >> 16) & 0xFF; 171 buffer[1] = (value >> 8) & 0xFF; 172 buffer[0] = (value >> 0) & 0xFF; 173 return outfile_->Write(buffer, kWordSize); 174} 175 176bool BitcodeWrapperer::WriteVariableFields() { 177 // This buffer may have to be bigger if we start using the fields 178 // for larger things. 179 uint8_t buffer[kMaxVariableFieldSize]; 180 for (vector<BCHeaderField>::iterator it = header_fields_.begin(); 181 it != header_fields_.end(); ++it) { 182 if (!it->Write(buffer, kMaxVariableFieldSize) || 183 !outfile_->Write(buffer, it->GetTotalSize())) { 184 return false; 185 } 186 } 187 return true; 188} 189 190bool BitcodeWrapperer::ParseWrapperHeader() { 191 // Make sure LLVM-defined fields have been parsed 192 if (!IsInputBitcodeWrapper()) return false; 193 // Check the android/pnacl fields 194 if (!ReadWord(android_header_version_) || 195 !ReadWord(android_target_api_) || !ReadWord(pnacl_bc_version_)) { 196 ALOGW("Error: file not long enough to contain header\n"); 197 return false; 198 } 199 if (pnacl_bc_version_ != kPnaclBitcodeVersion) { 200 ALOGW("Error: bad PNaCl Bitcode version\n"); 201 return false; 202 } 203 int field_data_total = wrapper_bc_offset_ - kWordSize * kFixedFields; 204 if (field_data_total > 0) { 205 // Read in the variable fields. We need to allocate space for the data. 206 int field_data_read = 0; 207 208 while (field_data_read < field_data_total) { 209 FillBuffer(); 210 size_t buffer_needed = BCHeaderField::GetDataSizeFromSerialized( 211 &buffer_[cursor_]); 212 if (buffer_needed > buffer_.size()) { 213 buffer_.resize(buffer_needed + 214 sizeof(BCHeaderField::FixedSubfield) * 2); 215 FillBuffer(); 216 } 217 variable_field_data_.push_back(new uint8_t[buffer_needed]); 218 219 BCHeaderField field(BCHeaderField::kInvalid, 0, 220 variable_field_data_.back()); 221 field.Read(&buffer_[cursor_], buffer_size_); 222 header_fields_.push_back(field); 223 size_t field_size = field.GetTotalSize(); 224 cursor_ += field_size; 225 field_data_read += field_size; 226 if (field_data_read > field_data_total) { 227 // We read too much data, the header is corrupted 228 ALOGE("Error: raw bitcode offset inconsistent with " 229 "variable field data\n"); 230 return false; 231 } 232 233 struct IntFieldHelper { 234 BCHeaderField::FixedSubfield tag; 235 uint16_t len; 236 uint32_t val; 237 }; 238 IntFieldHelper tempIntField; 239 240 switch (field.getID()) { 241 case BCHeaderField::kAndroidCompilerVersion: 242 if (field.Write((uint8_t*)&tempIntField, 243 sizeof(tempIntField))) { 244 android_compiler_version_ = tempIntField.val; 245 } 246 break; 247 case BCHeaderField::kAndroidOptimizationLevel: 248 if (field.Write((uint8_t*)&tempIntField, 249 sizeof(tempIntField))) { 250 android_optimization_level_ = tempIntField.val; 251 } 252 break; 253 default: 254 // Ignore other field types for now 255 break; 256 } 257 } 258 Seek(0); 259 } 260 return true; 261} 262 263bool BitcodeWrapperer::IsInputBitcodeWrapper() { 264 ResetCursor(); 265 // First make sure that there are enough words (LLVM header) 266 // to peek at. 267 if (GetBufferUnreadBytes() < kLLVMFields * kWordSize) { 268 FillBuffer(); 269 if (GetBufferUnreadBytes() < kLLVMFields * kWordSize) return false; 270 } 271 272 // Now make sure the magic number is right. 273 uint32_t first_word; 274 if ((!ReadWord(first_word)) || 275 (kWrapperMagicNumber != first_word)) return false; 276 277 // Make sure the version is right. 278 uint32_t second_word; 279 if ((!ReadWord(second_word)) || 280 (kLLVMVersionNumber != second_word)) return false; 281 282 // Make sure that the offset and size (for llvm) is defined. 283 uint32_t bc_offset; 284 uint32_t bc_size; 285 if (ReadWord(bc_offset) && 286 ReadWord(bc_size)) { 287 // Before returning, save the extracted values. 288 wrapper_bc_offset_ = bc_offset; 289 infile_bc_offset_ = bc_offset; 290 wrapper_bc_size_ = bc_size; 291 return true; 292 } 293 // If reached, unable to read wrapped header. 294 return false; 295} 296 297bool BitcodeWrapperer::IsInputBitcodeFile() { 298 ResetCursor(); 299 // First make sure that there are four bytes to peek at. 300 if (GetBufferUnreadBytes() < kWordSize) { 301 FillBuffer(); 302 if (GetBufferUnreadBytes() < kWordSize) return false; 303 } 304 // If reached, Check if first 4 bytes match bitcode 305 // file magic number. 306 return (BufferLookahead(0) == 'B') && 307 (BufferLookahead(1) == 'C') && 308 (BufferLookahead(2) == 0xc0) && 309 (BufferLookahead(3) == 0xde); 310} 311 312bool BitcodeWrapperer::BufferCopyInToOut(uint32_t size) { 313 while (size > 0) { 314 // Be sure buffer is non-empty before writing. 315 if (0 == buffer_size_) { 316 FillBuffer(); 317 if (0 == buffer_size_) { 318 return false; 319 } 320 } 321 // copy the buffer to the output file. 322 size_t block = (buffer_size_ < size) ? buffer_size_ : size; 323 if (!outfile_->Write(&buffer_[cursor_], block)) return false; 324 size -= block; 325 buffer_size_ = 0; 326 } 327 // Be sure that there isn't more bytes on the input stream. 328 FillBuffer(); 329 return buffer_size_ == 0; 330} 331 332void BitcodeWrapperer::AddHeaderField(BCHeaderField* field) { 333 header_fields_.push_back(*field); 334 wrapper_bc_offset_ += field->GetTotalSize(); 335} 336 337bool BitcodeWrapperer::WriteBitcodeWrapperHeader() { 338 return 339 // Note: This writes out the 4 word header required by llvm wrapped 340 // bitcode. 341 WriteWord(kWrapperMagicNumber) && 342 WriteWord(kLLVMVersionNumber) && 343 WriteWord(wrapper_bc_offset_) && 344 WriteWord(wrapper_bc_size_) && 345 // 2 fixed fields defined by Android 346 WriteWord(android_header_version_) && 347 WriteWord(android_target_api_) && 348 // PNaClBitcode version 349 WriteWord(kPnaclBitcodeVersion) && 350 // Common variable-length fields 351 WriteVariableFields(); 352} 353 354void BitcodeWrapperer::PrintWrapperHeader() { 355 if (error_) { 356 fprintf(stderr, "Error condition exists: the following" 357 "data may not be reliable\n"); 358 } 359 fprintf(stderr, "Wrapper magic:\t\t%x\n", kWrapperMagicNumber); 360 fprintf(stderr, "LLVM Bitcode version:\t%d\n", kLLVMVersionNumber); 361 fprintf(stderr, "Raw bitcode offset:\t%d\n", wrapper_bc_offset_); 362 fprintf(stderr, "Raw bitcode size:\t%d\n", wrapper_bc_size_); 363 fprintf(stderr, "Android header version:\t%d\n", android_header_version_); 364 fprintf(stderr, "Android target API:\t%d\n", android_target_api_); 365 fprintf(stderr, "PNaCl bitcode version:\t%d\n", kPnaclBitcodeVersion); 366 for (size_t i = 0; i < header_fields_.size(); i++) header_fields_[i].Print(); 367} 368 369bool BitcodeWrapperer::GenerateWrappedBitcodeFile() { 370 if (!error_ && 371 WriteBitcodeWrapperHeader() && 372 Seek(infile_bc_offset_) && 373 BufferCopyInToOut(wrapper_bc_size_)) { 374 off_t dangling = wrapper_bc_size_ & 3; 375 if (dangling) { 376 return outfile_->Write((const uint8_t*) "\0\0\0\0", 4 - dangling); 377 } 378 return true; 379 } 380 return false; 381} 382 383bool BitcodeWrapperer::GenerateRawBitcodeFile() { 384 return !error_ && Seek(infile_bc_offset_) && 385 BufferCopyInToOut(wrapper_bc_size_); 386} 387