summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
author Treehugger Robot <treehugger-gerrit@google.com> 2016-05-26 12:56:08 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2016-05-26 12:56:08 +0000
commit1b0b6bfb87d915facbf081c8a6855b6336a36ac6 (patch)
tree9495850ace926ce6bfdc8392c1fafde976f4ae9f /compiler
parenta11a08ce2abc129b357741102bf5801b3fcd7308 (diff)
parente079e217157b0a3ba006f96403b19046d4846d35 (diff)
Merge "Fix OatWriter to update the header checksum correctly."
Diffstat (limited to 'compiler')
-rw-r--r--compiler/oat_writer.cc84
-rw-r--r--compiler/oat_writer.h1
2 files changed, 58 insertions, 27 deletions
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index 1aa26090ad..42320028e5 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -63,6 +63,29 @@ const UnalignedDexFileHeader* AsUnalignedDexFileHeader(const uint8_t* raw_data)
return reinterpret_cast<const UnalignedDexFileHeader*>(raw_data);
}
+class ChecksumUpdatingOutputStream : public OutputStream {
+ public:
+ ChecksumUpdatingOutputStream(OutputStream* out, OatHeader* oat_header)
+ : OutputStream(out->GetLocation()), out_(out), oat_header_(oat_header) { }
+
+ bool WriteFully(const void* buffer, size_t byte_count) OVERRIDE {
+ oat_header_->UpdateChecksum(buffer, byte_count);
+ return out_->WriteFully(buffer, byte_count);
+ }
+
+ off_t Seek(off_t offset, Whence whence) OVERRIDE {
+ return out_->Seek(offset, whence);
+ }
+
+ bool Flush() OVERRIDE {
+ return out_->Flush();
+ }
+
+ private:
+ OutputStream* const out_;
+ OatHeader* const oat_header_;
+};
+
} // anonymous namespace
// Defines the location of the raw dex file to write.
@@ -422,13 +445,21 @@ bool OatWriter::WriteAndOpenDexFiles(
for (OatDexFile& oat_dex_file : oat_dex_files_) {
oat_dex_file.ReserveClassOffsets(this);
}
- if (!WriteOatDexFiles(rodata) ||
+ ChecksumUpdatingOutputStream checksum_updating_rodata(rodata, oat_header_.get());
+ if (!WriteOatDexFiles(&checksum_updating_rodata) ||
!ExtendForTypeLookupTables(rodata, file, size_after_type_lookup_tables) ||
!OpenDexFiles(file, verify, &dex_files_map, &dex_files) ||
!WriteTypeLookupTables(dex_files_map.get(), dex_files)) {
return false;
}
+ // Do a bulk checksum update for Dex[] and TypeLookupTable[]. Doing it piece by
+ // piece would be difficult because we're not using the OutpuStream directly.
+ if (!oat_dex_files_.empty()) {
+ size_t size = size_after_type_lookup_tables - oat_dex_files_[0].dex_file_offset_;
+ oat_header_->UpdateChecksum(dex_files_map->Begin(), size);
+ }
+
*opened_dex_files_map = std::move(dex_files_map);
*opened_dex_files = std::move(dex_files);
write_state_ = WriteState::kPrepareLayout;
@@ -996,7 +1027,7 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor {
<< PrettyMethod(it.GetMemberIndex(), *dex_file_);
const OatQuickMethodHeader& method_header =
oat_class->method_headers_[method_offsets_index_];
- if (!writer_->WriteData(out, &method_header, sizeof(method_header))) {
+ if (!out->WriteFully(&method_header, sizeof(method_header))) {
ReportWriteFailure("method header", it);
return false;
}
@@ -1063,7 +1094,7 @@ class OatWriter::WriteCodeMethodVisitor : public OatDexMethodVisitor {
}
}
- if (!writer_->WriteData(out, quick_code.data(), code_size)) {
+ if (!out->WriteFully(quick_code.data(), code_size)) {
ReportWriteFailure("method code", it);
return false;
}
@@ -1279,7 +1310,7 @@ class OatWriter::WriteMapMethodVisitor : public OatDexMethodVisitor {
size_t map_size = map.size() * sizeof(map[0]);
if (map_offset == offset_) {
// Write deduplicated map (code info for Optimizing or transformation info for dex2dex).
- if (UNLIKELY(!writer_->WriteData(out, map.data(), map_size))) {
+ if (UNLIKELY(!out->WriteFully(map.data(), map_size))) {
ReportWriteFailure(it);
return false;
}
@@ -1457,6 +1488,10 @@ size_t OatWriter::InitOatCodeDexFiles(size_t offset) {
bool OatWriter::WriteRodata(OutputStream* out) {
CHECK(write_state_ == WriteState::kWriteRoData);
+ // Wrap out to update checksum with each write.
+ ChecksumUpdatingOutputStream checksum_updating_out(out, oat_header_.get());
+ out = &checksum_updating_out;
+
if (!WriteClassOffsets(out)) {
LOG(ERROR) << "Failed to write class offsets to " << out->GetLocation();
return false;
@@ -1499,6 +1534,10 @@ bool OatWriter::WriteRodata(OutputStream* out) {
bool OatWriter::WriteCode(OutputStream* out) {
CHECK(write_state_ == WriteState::kWriteText);
+ // Wrap out to update checksum with each write.
+ ChecksumUpdatingOutputStream checksum_updating_out(out, oat_header_.get());
+ out = &checksum_updating_out;
+
SetMultiOatRelativePatcherAdjustment();
const size_t file_offset = oat_data_offset_;
@@ -1683,7 +1722,7 @@ size_t OatWriter::WriteCode(OutputStream* out, const size_t file_offset, size_t
uint32_t alignment_padding = aligned_offset - relative_offset; \
out->Seek(alignment_padding, kSeekCurrent); \
size_trampoline_alignment_ += alignment_padding; \
- if (!WriteData(out, (field)->data(), (field)->size())) { \
+ if (!out->WriteFully((field)->data(), (field)->size())) { \
PLOG(ERROR) << "Failed to write " # field " to " << out->GetLocation(); \
return false; \
} \
@@ -2013,7 +2052,7 @@ bool OatWriter::WriteDexFile(OutputStream* rodata,
DCHECK(ValidateDexFileHeader(dex_file, oat_dex_file->GetLocation()));
const UnalignedDexFileHeader* header = AsUnalignedDexFileHeader(dex_file);
- if (!WriteData(rodata, dex_file, header->file_size_)) {
+ if (!rodata->WriteFully(dex_file, header->file_size_)) {
PLOG(ERROR) << "Failed to write dex file " << oat_dex_file->GetLocation()
<< " to " << rodata->GetLocation();
return false;
@@ -2193,18 +2232,13 @@ bool OatWriter::WriteCodeAlignment(OutputStream* out, uint32_t aligned_code_delt
0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u
};
DCHECK_LE(aligned_code_delta, sizeof(kPadding));
- if (UNLIKELY(!WriteData(out, kPadding, aligned_code_delta))) {
+ if (UNLIKELY(!out->WriteFully(kPadding, aligned_code_delta))) {
return false;
}
size_code_alignment_ += aligned_code_delta;
return true;
}
-bool OatWriter::WriteData(OutputStream* out, const void* data, size_t size) {
- oat_header_->UpdateChecksum(data, size);
- return out->WriteFully(data, size);
-}
-
void OatWriter::SetMultiOatRelativePatcherAdjustment() {
DCHECK(dex_files_ != nullptr);
DCHECK(relative_patcher_ != nullptr);
@@ -2274,39 +2308,37 @@ bool OatWriter::OatDexFile::Write(OatWriter* oat_writer, OutputStream* out) cons
const size_t file_offset = oat_writer->oat_data_offset_;
DCHECK_OFFSET_();
- if (!oat_writer->WriteData(out, &dex_file_location_size_, sizeof(dex_file_location_size_))) {
+ if (!out->WriteFully(&dex_file_location_size_, sizeof(dex_file_location_size_))) {
PLOG(ERROR) << "Failed to write dex file location length to " << out->GetLocation();
return false;
}
oat_writer->size_oat_dex_file_location_size_ += sizeof(dex_file_location_size_);
- if (!oat_writer->WriteData(out, dex_file_location_data_, dex_file_location_size_)) {
+ if (!out->WriteFully(dex_file_location_data_, dex_file_location_size_)) {
PLOG(ERROR) << "Failed to write dex file location data to " << out->GetLocation();
return false;
}
oat_writer->size_oat_dex_file_location_data_ += dex_file_location_size_;
- if (!oat_writer->WriteData(out,
- &dex_file_location_checksum_,
- sizeof(dex_file_location_checksum_))) {
+ if (!out->WriteFully(&dex_file_location_checksum_, sizeof(dex_file_location_checksum_))) {
PLOG(ERROR) << "Failed to write dex file location checksum to " << out->GetLocation();
return false;
}
oat_writer->size_oat_dex_file_location_checksum_ += sizeof(dex_file_location_checksum_);
- if (!oat_writer->WriteData(out, &dex_file_offset_, sizeof(dex_file_offset_))) {
+ if (!out->WriteFully(&dex_file_offset_, sizeof(dex_file_offset_))) {
PLOG(ERROR) << "Failed to write dex file offset to " << out->GetLocation();
return false;
}
oat_writer->size_oat_dex_file_offset_ += sizeof(dex_file_offset_);
- if (!oat_writer->WriteData(out, &class_offsets_offset_, sizeof(class_offsets_offset_))) {
+ if (!out->WriteFully(&class_offsets_offset_, sizeof(class_offsets_offset_))) {
PLOG(ERROR) << "Failed to write class offsets offset to " << out->GetLocation();
return false;
}
oat_writer->size_oat_dex_file_class_offsets_offset_ += sizeof(class_offsets_offset_);
- if (!oat_writer->WriteData(out, &lookup_table_offset_, sizeof(lookup_table_offset_))) {
+ if (!out->WriteFully(&lookup_table_offset_, sizeof(lookup_table_offset_))) {
PLOG(ERROR) << "Failed to write lookup table offset to " << out->GetLocation();
return false;
}
@@ -2316,7 +2348,7 @@ bool OatWriter::OatDexFile::Write(OatWriter* oat_writer, OutputStream* out) cons
}
bool OatWriter::OatDexFile::WriteClassOffsets(OatWriter* oat_writer, OutputStream* out) {
- if (!oat_writer->WriteData(out, class_offsets_.data(), GetClassOffsetsRawSize())) {
+ if (!out->WriteFully(class_offsets_.data(), GetClassOffsetsRawSize())) {
PLOG(ERROR) << "Failed to write oat class offsets for " << GetLocation()
<< " to " << out->GetLocation();
return false;
@@ -2405,13 +2437,13 @@ bool OatWriter::OatClass::Write(OatWriter* oat_writer,
OutputStream* out,
const size_t file_offset) const {
DCHECK_OFFSET_();
- if (!oat_writer->WriteData(out, &status_, sizeof(status_))) {
+ if (!out->WriteFully(&status_, sizeof(status_))) {
PLOG(ERROR) << "Failed to write class status to " << out->GetLocation();
return false;
}
oat_writer->size_oat_class_status_ += sizeof(status_);
- if (!oat_writer->WriteData(out, &type_, sizeof(type_))) {
+ if (!out->WriteFully(&type_, sizeof(type_))) {
PLOG(ERROR) << "Failed to write oat class type to " << out->GetLocation();
return false;
}
@@ -2419,20 +2451,20 @@ bool OatWriter::OatClass::Write(OatWriter* oat_writer,
if (method_bitmap_size_ != 0) {
CHECK_EQ(kOatClassSomeCompiled, type_);
- if (!oat_writer->WriteData(out, &method_bitmap_size_, sizeof(method_bitmap_size_))) {
+ if (!out->WriteFully(&method_bitmap_size_, sizeof(method_bitmap_size_))) {
PLOG(ERROR) << "Failed to write method bitmap size to " << out->GetLocation();
return false;
}
oat_writer->size_oat_class_method_bitmaps_ += sizeof(method_bitmap_size_);
- if (!oat_writer->WriteData(out, method_bitmap_->GetRawStorage(), method_bitmap_size_)) {
+ if (!out->WriteFully(method_bitmap_->GetRawStorage(), method_bitmap_size_)) {
PLOG(ERROR) << "Failed to write method bitmap to " << out->GetLocation();
return false;
}
oat_writer->size_oat_class_method_bitmaps_ += method_bitmap_size_;
}
- if (!oat_writer->WriteData(out, method_offsets_.data(), GetMethodOffsetsRawSize())) {
+ if (!out->WriteFully(method_offsets_.data(), GetMethodOffsetsRawSize())) {
PLOG(ERROR) << "Failed to write method offsets to " << out->GetLocation();
return false;
}
diff --git a/compiler/oat_writer.h b/compiler/oat_writer.h
index 3862798329..cc81f39f36 100644
--- a/compiler/oat_writer.h
+++ b/compiler/oat_writer.h
@@ -271,7 +271,6 @@ class OatWriter {
bool WriteTypeLookupTables(MemMap* opened_dex_files_map,
const std::vector<std::unique_ptr<const DexFile>>& opened_dex_files);
bool WriteCodeAlignment(OutputStream* out, uint32_t aligned_code_delta);
- bool WriteData(OutputStream* out, const void* data, size_t size);
void SetMultiOatRelativePatcherAdjustment();
enum class WriteState {