Home | History | Annotate | Download | only in Wrap
      1 /*
      2  * Copyright 2012, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #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 
     26 using std::vector;
     27 
     28 // The number of bytes in a 32 bit integer.
     29 static const uint32_t kWordSize = 4;
     30 
     31 // Number of LLVM-defined fixed fields in the header.
     32 static const uint32_t kLLVMFields = 4;
     33 
     34 // Total number of fixed fields in the header.
     35 static const uint32_t kFixedFields = 7;
     36 
     37 // The magic number that must exist for bitcode wrappers.
     38 static 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.
     43 static const uint32_t kLLVMVersionNumber = 0;
     44 
     45 // Fields defined by Android bitcode header.
     46 static const uint32_t kAndroidHeaderVersion = 0;
     47 static const uint32_t kAndroidTargetAPI = 0;
     48 static const uint32_t kAndroidDefaultCompilerVersion = 0;
     49 static const uint32_t kAndroidDefaultOptimizationLevel = 3;
     50 
     51 // PNaCl bitcode version number.
     52 static 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).
     56 static const size_t kMaxVariableFieldSize = 256;
     57 
     58 BitcodeWrapperer::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 
     85 BitcodeWrapperer::~BitcodeWrapperer() {
     86   for(size_t i = 0; i < variable_field_data_.size(); i++) {
     87     delete [] variable_field_data_[i];
     88   }
     89 }
     90 
     91 
     92 void BitcodeWrapperer::ClearBuffer() {
     93   buffer_size_ = 0;
     94   cursor_ = 0;
     95   infile_at_eof_ = false;
     96 }
     97 
     98 bool BitcodeWrapperer::Seek(uint32_t pos) {
     99   if (infile_ != nullptr && infile_->Seek(pos)) {
    100     ClearBuffer();
    101     return true;
    102   }
    103   return false;
    104 }
    105 
    106 bool BitcodeWrapperer::CanReadWord() {
    107   if (GetBufferUnreadBytes() < kWordSize) {
    108     FillBuffer();
    109     return GetBufferUnreadBytes() >= kWordSize;
    110   } else {
    111     return true;
    112   }
    113 }
    114 
    115 void 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 
    157 bool 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 
    167 bool 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 
    176 bool 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 
    190 bool 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 
    263 bool 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 
    297 bool 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 
    312 bool 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 
    332 void BitcodeWrapperer::AddHeaderField(BCHeaderField* field) {
    333   header_fields_.push_back(*field);
    334   wrapper_bc_offset_ += field->GetTotalSize();
    335 }
    336 
    337 bool 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 
    354 void 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 
    369 bool 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 
    383 bool BitcodeWrapperer::GenerateRawBitcodeFile() {
    384   return !error_ && Seek(infile_bc_offset_) &&
    385       BufferCopyInToOut(wrapper_bc_size_);
    386 }
    387