Fix compact dex shared section with update_input_vdex

For update input vdex, the shared data section is empty in the oat
writer. This was causing an error by not correctly updating the
vdex_size_ to be after the shared data section. Since the offset
was not update to be after the section, vdex and quickening data
would overwrite the shared data and it would get truncated.

Usually this would manifest as a crash in dequickening or reading the
dex file map list. This CL fixes the oat writer to verify and skip
the shared data section when update_input_vdex is true.

Test coverage is provided by re-enabling compact dex for the cases
where update_input_vdex is false.

Bug: 72608794
Bug: 63756964
Test: test-art-host

Change-Id: Ic1f64804231386fabf5847bd8be8783841d29eaa
(cherry picked from commit f160983d93e14bdb56d6fc0cd4d501b1fa2f4c61)
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index 6fcf695..5614ac6 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -783,7 +783,7 @@
                          app_image_file_name,
                          /* use_fd */ true,
                          /* num_profile_classes */ 1,
-                         { input_vdex, output_vdex, kDisableCompactDex });
+                         { input_vdex, output_vdex });
       EXPECT_GT(vdex_file1->GetLength(), 0u);
     }
     {
@@ -904,7 +904,7 @@
       GenerateOdexForTest(dex_location,
                           odex_location,
                           CompilerFilter::kQuicken,
-                          { input_vdex, output_vdex, kDisableCompactDex },
+                          { input_vdex, output_vdex },
                           /* expect_success */ true,
                           /* use_fd */ true);
       EXPECT_GT(vdex_file1->GetLength(), 0u);
diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc
index c7e9cda..d245cd1 100644
--- a/dex2oat/linker/oat_writer.cc
+++ b/dex2oat/linker/oat_writer.cc
@@ -3367,7 +3367,10 @@
 
     // Write shared dex file data section and fix up the dex file headers.
     vdex_dex_shared_data_offset_ = vdex_size_;
+    uint32_t shared_data_size = 0u;
+
     if (dex_container_ != nullptr) {
+      CHECK(!update_input_vdex) << "Update input vdex should have empty dex container";
       DexContainer::Section* const section = dex_container_->GetDataSection();
       if (section->Size() > 0) {
         const uint32_t shared_data_offset = vdex_size_;
@@ -3376,7 +3379,7 @@
           LOG(ERROR) << "Expected offset " << shared_data_offset << " but got " << existing_offset;
           return false;
         }
-        const uint32_t shared_data_size = section->Size();
+        shared_data_size = section->Size();
         if (!out->WriteFully(section->Begin(), shared_data_size)) {
           LOG(ERROR) << "Failed to write shared data!";
           return false;
@@ -3400,8 +3403,6 @@
             return false;
           }
         }
-        vdex_size_ += shared_data_size;
-        size_dex_file_ += shared_data_size;
         section->Clear();
         if (!out->Flush()) {
           PLOG(ERROR) << "Failed to flush after writing shared dex section.";
@@ -3409,9 +3410,35 @@
         }
       }
       dex_container_.reset();
+    } else {
+      if (update_input_vdex) {
+        for (OatDexFile& oat_dex_file : oat_dex_files_) {
+          DexFile::Header header;
+          if (!file->PreadFully(&header, sizeof(header), oat_dex_file.dex_file_offset_)) {
+            PLOG(ERROR) << "Failed to read dex header";
+            return false;
+          }
+          if (!CompactDexFile::IsMagicValid(header.magic_)) {
+            // Non compact dex does not have shared data section.
+            continue;
+          }
+          const uint32_t expected_data_off = vdex_dex_shared_data_offset_ -
+              oat_dex_file.dex_file_offset_;
+          if (header.data_off_ != expected_data_off) {
+            PLOG(ERROR) << "Shared data section offset " << header.data_off_
+                        << " does not match expected value " << expected_data_off;
+            return false;
+          }
+          // The different dex files currently can have different data sizes since
+          // the dex writer writes them one at a time into the shared section.:w
+          shared_data_size = std::max(shared_data_size, header.data_size_);
+        }
+      }
     }
+    vdex_size_ += shared_data_size;
+    size_dex_file_ += shared_data_size;
   } else {
-    vdex_dex_shared_data_offset_ =  vdex_size_;
+    vdex_dex_shared_data_offset_ = vdex_size_;
   }
 
   return true;