summaryrefslogtreecommitdiff
path: root/compiler/oat_writer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/oat_writer.cc')
-rw-r--r--compiler/oat_writer.cc58
1 files changed, 46 insertions, 12 deletions
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index 153aff40dc..bebd5f5ae2 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -300,6 +300,7 @@ OatWriter::OatWriter(bool compiling_boot_image, TimingLogger* timings, ProfileCo
oat_data_offset_(0u),
oat_header_(nullptr),
size_vdex_header_(0),
+ size_vdex_checksums_(0),
size_dex_file_alignment_(0),
size_executable_offset_alignment_(0),
size_oat_header_(0),
@@ -409,10 +410,11 @@ bool OatWriter::AddVdexDexFilesSource(const VdexFile& vdex_file,
CreateTypeLookupTable create_type_lookup_table) {
DCHECK(write_state_ == WriteState::kAddingDexFileSources);
const uint8_t* current_dex_data = nullptr;
- for (size_t i = 0; ; ++i) {
+ for (size_t i = 0; i < vdex_file.GetHeader().GetNumberOfDexFiles(); ++i) {
current_dex_data = vdex_file.GetNextDexFileData(current_dex_data);
if (current_dex_data == nullptr) {
- break;
+ LOG(ERROR) << "Unexpected number of dex files in vdex " << location;
+ return false;
}
if (!DexFile::IsMagicValid(current_dex_data)) {
LOG(ERROR) << "Invalid magic in vdex file created from " << location;
@@ -424,7 +426,14 @@ bool OatWriter::AddVdexDexFilesSource(const VdexFile& vdex_file,
oat_dex_files_.emplace_back(full_location,
DexFileSource(current_dex_data),
create_type_lookup_table);
+ oat_dex_files_.back().dex_file_location_checksum_ = vdex_file.GetLocationChecksum(i);
}
+
+ if (vdex_file.GetNextDexFileData(current_dex_data) != nullptr) {
+ LOG(ERROR) << "Unexpected number of dex files in vdex " << location;
+ return false;
+ }
+
if (oat_dex_files_.empty()) {
LOG(ERROR) << "No dex files in vdex file created from " << location;
return false;
@@ -488,8 +497,8 @@ bool OatWriter::WriteAndOpenDexFiles(
// Initialize VDEX and OAT headers.
if (kIsVdexEnabled) {
- size_vdex_header_ = sizeof(VdexFile::Header);
- vdex_size_ = size_vdex_header_;
+ // Reserve space for Vdex header and checksums.
+ vdex_size_ = sizeof(VdexFile::Header) + oat_dex_files_.size() * sizeof(VdexFile::VdexChecksum);
}
size_t oat_data_offset = InitOatHeader(instruction_set,
instruction_set_features,
@@ -793,7 +802,7 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor {
// Update quick method header.
DCHECK_LT(method_offsets_index_, oat_class->method_headers_.size());
OatQuickMethodHeader* method_header = &oat_class->method_headers_[method_offsets_index_];
- uint32_t vmap_table_offset = method_header->vmap_table_offset_;
+ uint32_t vmap_table_offset = method_header->GetVmapTableOffset();
// The code offset was 0 when the mapping/vmap table offset was set, so it's set
// to 0-offset and we need to adjust it by code_offset.
uint32_t code_offset = quick_code_offset - thumb_offset;
@@ -935,7 +944,7 @@ class OatWriter::InitMapMethodVisitor : public OatDexMethodVisitor {
// If vdex is enabled, we only emit the stack map of compiled code. The quickening info will
// be in the vdex file.
if (!compiled_method->GetQuickCode().empty() || !kIsVdexEnabled) {
- DCHECK_EQ(oat_class->method_headers_[method_offsets_index_].vmap_table_offset_, 0u);
+ DCHECK_EQ(oat_class->method_headers_[method_offsets_index_].GetVmapTableOffset(), 0u);
ArrayRef<const uint8_t> map = compiled_method->GetVmapTable();
uint32_t map_size = map.size() * sizeof(map[0]);
@@ -949,7 +958,7 @@ class OatWriter::InitMapMethodVisitor : public OatDexMethodVisitor {
});
// Code offset is not initialized yet, so set the map offset to 0u-offset.
DCHECK_EQ(oat_class->method_offsets_[method_offsets_index_].code_offset_, 0u);
- oat_class->method_headers_[method_offsets_index_].vmap_table_offset_ = 0u - offset;
+ oat_class->method_headers_[method_offsets_index_].SetVmapTableOffset(0u - offset);
}
}
++method_offsets_index_;
@@ -1406,7 +1415,7 @@ class OatWriter::WriteMapMethodVisitor : public OatDexMethodVisitor {
size_t file_offset = file_offset_;
OutputStream* out = out_;
- uint32_t map_offset = oat_class->method_headers_[method_offsets_index_].vmap_table_offset_;
+ uint32_t map_offset = oat_class->method_headers_[method_offsets_index_].GetVmapTableOffset();
uint32_t code_offset = oat_class->method_offsets_[method_offsets_index_].code_offset_;
++method_offsets_index_;
@@ -1837,6 +1846,7 @@ bool OatWriter::WriteCode(OutputStream* out) {
size_total += (x);
DO_STAT(size_vdex_header_);
+ DO_STAT(size_vdex_checksums_);
DO_STAT(size_dex_file_alignment_);
DO_STAT(size_executable_offset_alignment_);
DO_STAT(size_oat_header_);
@@ -2383,6 +2393,7 @@ bool OatWriter::WriteDexFile(OutputStream* out,
// Update dex file size and resize class offsets in the OatDexFile.
// Note: For raw data, the checksum is passed directly to AddRawDexFileSource().
+ // Note: For vdex, the checksum is copied from the existing vdex file.
oat_dex_file->dex_file_size_ = header->file_size_;
oat_dex_file->class_offsets_.resize(header->class_defs_size_);
return true;
@@ -2592,11 +2603,31 @@ bool OatWriter::WriteTypeLookupTables(
return true;
}
-bool OatWriter::WriteVdexHeader(OutputStream* vdex_out) {
+bool OatWriter::WriteChecksumsAndVdexHeader(OutputStream* vdex_out) {
if (!kIsVdexEnabled) {
return true;
}
- off_t actual_offset = vdex_out->Seek(0, kSeekSet);
+ // Write checksums
+ off_t actual_offset = vdex_out->Seek(sizeof(VdexFile::Header), kSeekSet);
+ if (actual_offset != sizeof(VdexFile::Header)) {
+ PLOG(ERROR) << "Failed to seek to the checksum location of vdex file. Actual: " << actual_offset
+ << " File: " << vdex_out->GetLocation();
+ return false;
+ }
+
+ for (size_t i = 0, size = oat_dex_files_.size(); i != size; ++i) {
+ OatDexFile* oat_dex_file = &oat_dex_files_[i];
+ if (!vdex_out->WriteFully(
+ &oat_dex_file->dex_file_location_checksum_, sizeof(VdexFile::VdexChecksum))) {
+ PLOG(ERROR) << "Failed to write dex file location checksum. File: "
+ << vdex_out->GetLocation();
+ return false;
+ }
+ size_vdex_checksums_ += sizeof(VdexFile::VdexChecksum);
+ }
+
+ // Write header.
+ actual_offset = vdex_out->Seek(0, kSeekSet);
if (actual_offset != 0) {
PLOG(ERROR) << "Failed to seek to the beginning of vdex file. Actual: " << actual_offset
<< " File: " << vdex_out->GetLocation();
@@ -2610,12 +2641,15 @@ bool OatWriter::WriteVdexHeader(OutputStream* vdex_out) {
size_t verifier_deps_section_size = vdex_quickening_info_offset_ - vdex_verifier_deps_offset_;
size_t quickening_info_section_size = vdex_size_ - vdex_quickening_info_offset_;
- VdexFile::Header vdex_header(
- dex_section_size, verifier_deps_section_size, quickening_info_section_size);
+ VdexFile::Header vdex_header(oat_dex_files_.size(),
+ dex_section_size,
+ verifier_deps_section_size,
+ quickening_info_section_size);
if (!vdex_out->WriteFully(&vdex_header, sizeof(VdexFile::Header))) {
PLOG(ERROR) << "Failed to write vdex header. File: " << vdex_out->GetLocation();
return false;
}
+ size_vdex_header_ = sizeof(VdexFile::Header);
if (!vdex_out->Flush()) {
PLOG(ERROR) << "Failed to flush stream after writing to vdex file."