Handle empty uncompressed and aligned dex file in an archive.

Return an error message for it. Callers expect it.

Test: dex2oat_test
Bug: 131175467
Change-Id: I55c05f0a9c48cea252869f88740c6338b5b28b1f
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index dbe3567..52fcb49 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -86,6 +86,11 @@
 ART_TEST_HOST_GTEST_EmptyUncompressed_DEX := $(basename $(ART_TEST_HOST_GTEST_Main_DEX))EmptyUncompressed$(suffix $(ART_TEST_HOST_GTEST_Main_DEX))
 ART_TEST_TARGET_GTEST_EmptyUncompressed_DEX := $(basename $(ART_TEST_TARGET_GTEST_Main_DEX))EmptyUncompressed$(suffix $(ART_TEST_TARGET_GTEST_Main_DEX))
 
+# Create rules for UncompressedEmptyAligned, a classes.dex that is empty, uncompressed,
+# and 4 byte aligned for the dex2oat tests.
+ART_TEST_HOST_GTEST_EmptyUncompressedAligned_DEX := $(basename $(ART_TEST_HOST_GTEST_Main_DEX))EmptyUncompressedAligned$(suffix $(ART_TEST_HOST_GTEST_Main_DEX))
+ART_TEST_TARGET_GTEST_EmptyUncompressedAligned_DEX := $(basename $(ART_TEST_TARGET_GTEST_Main_DEX))EmptyUncompressedAligned$(suffix $(ART_TEST_TARGET_GTEST_Main_DEX))
+
 # Create rules for MultiDexUncompressed, a copy of MultiDex with the classes.dex uncompressed
 # for the OatFile tests.
 ART_TEST_HOST_GTEST_MultiDexUncompressed_DEX := $(basename $(ART_TEST_HOST_GTEST_MultiDex_DEX))Uncompressed$(suffix $(ART_TEST_HOST_GTEST_MultiDex_DEX))
@@ -118,19 +123,37 @@
 endif
 
 ifdef ART_TEST_HOST_GTEST_Main_DEX
-$(ART_TEST_HOST_GTEST_EmptyUncompressed_DEX): $(ZIPALIGN)
+$(ART_TEST_HOST_GTEST_EmptyUncompressed_DEX):
 	touch $(dir $@)classes.dex
 	zip -j -qD -X -0 $@ $(dir $@)classes.dex
 	rm $(dir $@)classes.dex
 endif
 
 ifdef ART_TEST_TARGET_GTEST_Main_DEX
-$(ART_TEST_TARGET_GTEST_EmptyUncompressed_DEX): $(ZIPALIGN)
+$(ART_TEST_TARGET_GTEST_EmptyUncompressed_DEX):
 	touch $(dir $@)classes.dex
 	zip -j -qD -X -0 $@ $(dir $@)classes.dex
 	rm $(dir $@)classes.dex
 endif
 
+ifdef ART_TEST_HOST_GTEST_Main_DEX
+$(ART_TEST_HOST_GTEST_EmptyUncompressedAligned_DEX): $(ZIPALIGN)
+	touch $(dir $@)classes.dex
+	zip -j -0 $(dir $@)temp.zip $(dir $@)classes.dex
+	$(ZIPALIGN) -f -v 4 $(dir $@)temp.zip $@
+	rm $(dir $@)classes.dex
+	rm $(dir $@)temp.zip
+endif
+
+ifdef ART_TEST_TARGET_GTEST_Main_DEX
+$(ART_TEST_TARGET_GTEST_EmptyUncompressedAligned_DEX): $(ZIPALIGN)
+	touch $(dir $@)classes.dex
+	zip -j -0 $(dir $@)temp.zip $(dir $@)classes.dex
+	$(ZIPALIGN) -f -v 4 $(dir $@)temp.zip $@
+	rm $(dir $@)classes.dex
+	rm $(dir $@)temp.zip
+endif
+
 ifdef ART_TEST_HOST_GTEST_MultiDex_DEX
 $(ART_TEST_HOST_GTEST_MultiDexUncompressed_DEX): $(ART_TEST_HOST_GTEST_MultiDex_DEX) $(ZIPALIGN)
 	cp $< $@
@@ -186,7 +209,7 @@
 ART_GTEST_dex_cache_test_DEX_DEPS := Main Packages MethodTypes
 ART_GTEST_dexanalyze_test_DEX_DEPS := MultiDex
 ART_GTEST_dexlayout_test_DEX_DEPS := ManyMethods
-ART_GTEST_dex2oat_test_DEX_DEPS := $(ART_GTEST_dex2oat_environment_tests_DEX_DEPS) ManyMethods Statics VerifierDeps MainUncompressed EmptyUncompressed StringLiterals
+ART_GTEST_dex2oat_test_DEX_DEPS := $(ART_GTEST_dex2oat_environment_tests_DEX_DEPS) ManyMethods Statics VerifierDeps MainUncompressed EmptyUncompressed EmptyUncompressedAligned StringLiterals
 ART_GTEST_dex2oat_image_test_DEX_DEPS := $(ART_GTEST_dex2oat_environment_tests_DEX_DEPS) Statics VerifierDeps
 ART_GTEST_exception_test_DEX_DEPS := ExceptionHandle
 ART_GTEST_hiddenapi_test_DEX_DEPS := HiddenApi HiddenApiStubs
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index 758e69f..ca06b11 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -1662,6 +1662,22 @@
   ASSERT_EQ(WEXITSTATUS(status), 1) << error_msg;
 }
 
+TEST_F(Dex2oatTest, EmptyUncompressedAlignedDexTest) {
+  std::string out_dir = GetScratchDir();
+  const std::string base_oat_name = out_dir + "/base.oat";
+  std::string error_msg;
+  int status = GenerateOdexForTestWithStatus(
+      { GetTestDexFileName("MainEmptyUncompressedAligned") },
+      base_oat_name,
+      CompilerFilter::Filter::kQuicken,
+      &error_msg,
+      { },
+      /*use_fd*/ false);
+  // Expect to fail with code 1 and not SIGSEGV or SIGABRT.
+  ASSERT_TRUE(WIFEXITED(status));
+  ASSERT_EQ(WEXITSTATUS(status), 1) << error_msg;
+}
+
 // Dex file that has duplicate methods have different code items and debug info.
 static const char kDuplicateMethodInputDex[] =
     "ZGV4CjAzOQDEy8VPdj4qHpgPYFWtLCtOykfFP4kB8tGYDAAAcAAAAHhWNBIAAAAAAAAAANALAABI"
diff --git a/libartbase/base/mem_map.cc b/libartbase/base/mem_map.cc
index ba2a7c6..3dbe7b8 100644
--- a/libartbase/base/mem_map.cc
+++ b/libartbase/base/mem_map.cc
@@ -516,6 +516,7 @@
   }
 
   if (byte_count == 0) {
+    *error_msg = "Empty MemMap requested";
     return Invalid();
   }
   // Adjust 'offset' to be page-aligned as required by mmap.