// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. #if !defined(DART_PRECOMPILED_RUNTIME) #include "vm/kernel_binary.h" #include "platform/globals.h" #include "vm/compiler/frontend/kernel_to_il.h" #include "vm/flags.h" #include "vm/growable_array.h" #include "vm/kernel.h" #include "vm/os.h" namespace dart { namespace kernel { Program* Program::ReadFrom(Reader* reader, bool take_buffer_ownership) { uint32_t magic = reader->ReadUInt32(); if (magic != kMagicProgramFile) FATAL("Invalid magic identifier"); uint32_t formatVersion = reader->ReadUInt32(); if (formatVersion != kBinaryFormatVersion) { FATAL2("Invalid kernel binary format version (found %u, expected %u)", formatVersion, kBinaryFormatVersion); } Program* program = new Program(); program->kernel_data_ = reader->buffer(); program->kernel_data_size_ = reader->size(); program->buffer_ownership_ = take_buffer_ownership; // Dill files can be concatenated (e.g. cat a.dill b.dill > c.dill). Find out // if this dill contains more than one program. int subprogram_count = 0; reader->set_offset(reader->size() - 4); while (reader->offset() > 0) { intptr_t size = reader->ReadUInt32(); intptr_t start = reader->offset() - size; if (start < 0) { FATAL("Invalid kernel binary: Indicated size is invalid."); } ++subprogram_count; if (subprogram_count > 1) break; reader->set_offset(start - 4); } program->single_program_ = subprogram_count == 1; // Read backwards at the end. program->library_count_ = reader->ReadFromIndexNoReset( reader->size_, LibraryCountFieldCountFromEnd, 1, 0); program->source_table_offset_ = reader->ReadFromIndexNoReset( reader->size_, LibraryCountFieldCountFromEnd + 1 + program->library_count_ + 1 + SourceTableFieldCountFromFirstLibraryOffset, 1, 0); program->name_table_offset_ = reader->ReadUInt32(); program->string_table_offset_ = reader->ReadUInt32(); program->constant_table_offset_ = reader->ReadUInt32(); program->main_method_reference_ = NameIndex(reader->ReadUInt32() - 1); return program; } } // namespace kernel kernel::Program* ReadPrecompiledKernelFromBuffer(const uint8_t* buffer, intptr_t buffer_length) { kernel::Reader reader(buffer, buffer_length); return kernel::Program::ReadFrom(&reader); } } // namespace dart #endif // !defined(DART_PRECOMPILED_RUNTIME)