simpleperf: fix reading dex files for unwinding while recording.

When simpleperf does unwinding while recording, it processes mmap
records before reading dex file linked list (via JITDebugReader).
To process mmap records, it creates Dso objects of type ELF_FILE.
Then after reading dex file linked list, it realizes some ELF_FILE Dso
should actually be DEX_FILE.

So this patch supports converting Dso objects of type ELF_FILE
into DEX_FILE when they have dex file offsets.

Bug: http://b/73126888
Test: run simpleperf_unit_test.
Test: run `simpleperf record -g --no-post-unwind` on an app.

Change-Id: I580a382724b17c1396a7f52d7b3f5df45bcbcfb7
diff --git a/simpleperf/dso_test.cpp b/simpleperf/dso_test.cpp
index f42b276..cc44193 100644
--- a/simpleperf/dso_test.cpp
+++ b/simpleperf/dso_test.cpp
@@ -65,3 +65,23 @@
   ASSERT_EQ(finder.FindDebugFile("[vdso]", false, build_id), fake_vdso32);
   ASSERT_EQ(finder.FindDebugFile("[vdso]", true, build_id), fake_vdso64);
 }
+
+TEST(dso, dex_file_dso) {
+#if defined(__linux__)
+  for (DsoType dso_type : {DSO_DEX_FILE, DSO_ELF_FILE}) {
+    std::unique_ptr<Dso> dso = Dso::CreateDso(dso_type, GetTestData("base.vdex"));
+    ASSERT_TRUE(dso);
+    dso->AddDexFileOffset(0x28);
+    ASSERT_EQ(DSO_DEX_FILE, dso->type());
+    const Symbol* symbol = dso->FindSymbol(0x6c77e);
+    ASSERT_NE(symbol, nullptr);
+    ASSERT_EQ(symbol->addr, static_cast<uint64_t>(0x6c77e));
+    ASSERT_EQ(symbol->len, static_cast<uint64_t>(0x16));
+    ASSERT_STREQ(symbol->DemangledName(),
+                 "com.example.simpleperf.simpleperfexamplewithnative.MixActivity$1.run");
+    ASSERT_EQ(0u, dso->MinVirtualAddress());
+  }
+#else
+  GTEST_LOG_(INFO) << "This test only runs on linux because of libdexfile";
+#endif  // defined(__linux__)
+}