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