Ensure verifier deps in the vdex file are 4-byte aligned. am: 2ef367acf3 am: 9b733f884a am: f684ebdddc

Original change: https://android-review.googlesource.com/c/platform/art/+/1701125

Change-Id: Iedfe0f97c67633f21ab099d11de11a1e1763eaa6
diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc
index dae9d89..af2db2d 100644
--- a/dex2oat/linker/oat_writer.cc
+++ b/dex2oat/linker/oat_writer.cc
@@ -2528,18 +2528,16 @@
 
   TimingLogger::ScopedTiming split("VDEX verifier deps", timings_);
 
-  size_t initial_offset = vdex_size_;
-  size_t start_offset = RoundUp(initial_offset, 4u);
-
-  vdex_size_ = start_offset;
-  vdex_verifier_deps_offset_ = vdex_size_;
-  size_verifier_deps_alignment_ = start_offset - initial_offset;
-  buffer->resize(buffer->size() + size_verifier_deps_alignment_, 0u);
-
-  size_t old_buffer_size = buffer->size();
+  DCHECK(buffer->empty());
   verifier_deps->Encode(*dex_files_, buffer);
+  size_verifier_deps_ = buffer->size();
 
-  size_verifier_deps_ = buffer->size() - old_buffer_size;
+  // Verifier deps data should be 4 byte aligned.
+  size_verifier_deps_alignment_ = RoundUp(vdex_size_, 4u) - vdex_size_;
+  buffer->insert(buffer->begin(), size_verifier_deps_alignment_, 0u);
+
+  vdex_size_ += size_verifier_deps_alignment_;
+  vdex_verifier_deps_offset_ = vdex_size_;
   vdex_size_ += size_verifier_deps_;
 }
 
diff --git a/runtime/verifier/verifier_deps.cc b/runtime/verifier/verifier_deps.cc
index c416c3d..7d00f73 100644
--- a/runtime/verifier/verifier_deps.cc
+++ b/runtime/verifier/verifier_deps.cc
@@ -516,13 +516,13 @@
 
 void VerifierDeps::Encode(const std::vector<const DexFile*>& dex_files,
                           std::vector<uint8_t>* buffer) const {
-  uint32_t offset = buffer->size();
-  buffer->resize(buffer->size() + dex_files.size() * sizeof(uint32_t));
+  DCHECK(buffer->empty());
+  buffer->resize(dex_files.size() * sizeof(uint32_t));
   uint32_t dex_file_index = 0;
   for (const DexFile* dex_file : dex_files) {
     // Four byte alignment before encoding the data.
     buffer->resize(RoundUp(buffer->size(), sizeof(uint32_t)));
-    (reinterpret_cast<uint32_t*>(buffer->data() + offset))[dex_file_index++] = buffer->size();
+    (reinterpret_cast<uint32_t*>(buffer->data()))[dex_file_index++] = buffer->size();
     const DexFileDeps& deps = *GetDexFileDeps(*dex_file);
     EncodeSetVector(buffer, deps.assignable_types_, deps.verified_classes_);
     // Four byte alignment before encoding strings.
diff --git a/test/663-odd-dex-size/expected-stdout.txt b/test/663-odd-dex-size/expected-stdout.txt
index 3da1ec2..cd5a1ee 100644
--- a/test/663-odd-dex-size/expected-stdout.txt
+++ b/test/663-odd-dex-size/expected-stdout.txt
@@ -1 +1,2 @@
 HelloWorld
+HelloWorld
diff --git a/test/663-odd-dex-size/run b/test/663-odd-dex-size/run
new file mode 100644
index 0000000..51777ca
--- /dev/null
+++ b/test/663-odd-dex-size/run
@@ -0,0 +1,25 @@
+#!/bin/bash
+#
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Run normally.
+${RUN} $@
+return_status1=$?
+
+# Run without cdex to trigger the unalignment in the vdex file.
+${RUN} ${@} -Xcompiler-option --compact-dex-level=none
+return_status2=$?
+
+(exit ${return_status1}) && (exit ${return_status2})