Write shared data section for oatdump export dex
Write this out so that the resulting dex can be dumped and inspected.
Bug: 77469384
Test: test-art-host-gtest-oatdump_test
Change-Id: Iadeaca0eaaf7c75a938dfc776801cf94c89d07f6
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index b342abe..b483e5f 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -300,11 +300,13 @@
$(HOST_CORE_IMAGE_DEFAULT_64) \
$(HOST_CORE_IMAGE_DEFAULT_32) \
oatdumpd-host \
- oatdumpds-host
+ oatdumpds-host \
+ dexdump2-host
ART_GTEST_oatdump_test_TARGET_DEPS := \
$(TARGET_CORE_IMAGE_DEFAULT_64) \
$(TARGET_CORE_IMAGE_DEFAULT_32) \
- oatdumpd-target
+ oatdumpd-target \
+ dexdump2-target
ART_GTEST_oatdump_image_test_HOST_DEPS := $(ART_GTEST_oatdump_test_HOST_DEPS)
ART_GTEST_oatdump_image_test_TARGET_DEPS := $(ART_GTEST_oatdump_test_TARGET_DEPS)
ART_GTEST_oatdump_app_test_HOST_DEPS := $(ART_GTEST_oatdump_test_HOST_DEPS) \
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 433ed9a..3bff123 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -1180,6 +1180,17 @@
}
}
+ // Update header for shared section.
+ uint32_t shared_section_offset = 0u;
+ uint32_t shared_section_size = 0u;
+ if (dex_file->IsCompactDexFile()) {
+ CompactDexFile::Header* const header =
+ reinterpret_cast<CompactDexFile::Header*>(const_cast<uint8_t*>(dex_file->Begin()));
+ shared_section_offset = header->data_off_;
+ shared_section_size = header->data_size_;
+ // The shared section will be serialized right after the dex file.
+ header->data_off_ = header->file_size_;
+ }
// Verify output directory exists
if (!OS::DirectoryExists(options_.export_dex_location_)) {
// TODO: Extend OS::DirectoryExists if symlink support is required
@@ -1226,16 +1237,22 @@
return false;
}
- bool success = false;
- success = file->WriteFully(dex_file->Begin(), fsize);
- // }
-
+ bool success = file->WriteFully(dex_file->Begin(), fsize);
if (!success) {
os << "Failed to write dex file";
file->Erase();
return false;
}
+ if (shared_section_size != 0) {
+ success = file->WriteFully(dex_file->Begin() + shared_section_offset, shared_section_size);
+ if (!success) {
+ os << "Failed to write shared data section";
+ file->Erase();
+ return false;
+ }
+ }
+
if (file->FlushCloseOrErase() != 0) {
os << "Flush and close failed";
return false;
diff --git a/oatdump/oatdump_test.cc b/oatdump/oatdump_test.cc
index 0034469..18cb2fd 100644
--- a/oatdump/oatdump_test.cc
+++ b/oatdump/oatdump_test.cc
@@ -75,6 +75,11 @@
std::string error_msg;
ASSERT_TRUE(Exec(kDynamic, kModeOat, {"--export-dex-to=" + tmp_dir_}, kListOnly, &error_msg))
<< error_msg;
+ const std::string dex_location = tmp_dir_+ "/core-oj-hostdex.jar_export.dex";
+ const std::string dexdump2 = GetExecutableFilePath("dexdump2",
+ /*is_debug*/false,
+ /*is_static*/false);
+ ASSERT_TRUE(ForkAndExecAndWait({dexdump2, "-d", dex_location}, &error_msg)) << error_msg;
}
TEST_F(OatDumpTest, TestExportDexStatic) {
TEST_DISABLED_FOR_NON_STATIC_HOST_BUILDS();
diff --git a/oatdump/oatdump_test.h b/oatdump/oatdump_test.h
index fac0bb2..b85730d 100644
--- a/oatdump/oatdump_test.h
+++ b/oatdump/oatdump_test.h
@@ -70,20 +70,24 @@
kStatic, // oatdump(d)s, dex2oat(d)s
};
- // Returns path to the oatdump/dex2oat binary.
- std::string GetExecutableFilePath(Flavor flavor, const char* name) {
+ // Returns path to the oatdump/dex2oat/dexdump binary.
+ std::string GetExecutableFilePath(const char* name, bool is_debug, bool is_static) {
std::string root = GetTestAndroidRoot();
root += "/bin/";
root += name;
- if (kIsDebugBuild) {
+ if (is_debug) {
root += "d";
}
- if (flavor == kStatic) {
+ if (is_static) {
root += "s";
}
return root;
}
+ std::string GetExecutableFilePath(Flavor flavor, const char* name) {
+ return GetExecutableFilePath(name, kIsDebugBuild, flavor == kStatic);
+ }
+
enum Mode {
kModeOat,
kModeOatWithBootImage,
@@ -127,17 +131,7 @@
};
exec_argv.insert(exec_argv.end(), args.begin(), args.end());
- pid_t pid;
- int pipe_fd;
- bool result = ForkAndExec(exec_argv, &pid, &pipe_fd, error_msg);
- if (result) {
- close(pipe_fd);
- int status = 0;
- if (waitpid(pid, &status, 0) != -1) {
- result = (status == 0);
- }
- }
- return result;
+ return ForkAndExecAndWait(exec_argv, error_msg);
}
// Run the test with custom arguments.
@@ -300,6 +294,21 @@
}
}
+ bool ForkAndExecAndWait(const std::vector<std::string>& exec_argv,
+ /*out*/ std::string* error_msg) {
+ pid_t pid;
+ int pipe_fd;
+ bool result = ForkAndExec(exec_argv, &pid, &pipe_fd, error_msg);
+ if (result) {
+ close(pipe_fd);
+ int status = 0;
+ if (waitpid(pid, &status, 0) != -1) {
+ result = (status == 0);
+ }
+ }
+ return result;
+ }
+
std::string tmp_dir_;
private: