summaryrefslogtreecommitdiff
path: root/oatdump/oatdump.cc
diff options
context:
space:
mode:
Diffstat (limited to 'oatdump/oatdump.cc')
-rw-r--r--oatdump/oatdump.cc84
1 files changed, 80 insertions, 4 deletions
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index c0d0478bf95..6a68b55fad5 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -34,6 +34,7 @@
#include "art_field-inl.h"
#include "art_method-inl.h"
#include "base/bit_utils_iterator.h"
+#include "base/indenter.h"
#include "base/os.h"
#include "base/safe_map.h"
#include "base/stl_util.h"
@@ -49,6 +50,7 @@
#include "dex/dex_file-inl.h"
#include "dex/dex_instruction-inl.h"
#include "dex/string_reference.h"
+#include "dex/type_lookup_table.h"
#include "disassembler.h"
#include "gc/accounting/space_bitmap-inl.h"
#include "gc/space/image_space.h"
@@ -56,7 +58,6 @@
#include "gc/space/space-inl.h"
#include "image-inl.h"
#include "imtable-inl.h"
-#include "indenter.h"
#include "subtype_check.h"
#include "index_bss_mapping.h"
#include "interpreter/unstarted_runtime.h"
@@ -75,7 +76,6 @@
#include "stack.h"
#include "stack_map.h"
#include "thread_list.h"
-#include "type_lookup_table.h"
#include "vdex_file.h"
#include "verifier/method_verifier.h"
#include "verifier/verifier_deps.h"
@@ -172,6 +172,7 @@ class OatSymbolizer FINAL {
builder_->PrepareDynamicSection(elf_file->GetPath(),
rodata_size,
text_size,
+ oat_file_->DataBimgRelRoSize(),
oat_file_->BssSize(),
oat_file_->BssMethodsOffset(),
oat_file_->BssRootsOffset(),
@@ -513,6 +514,18 @@ class OatDumper {
os << StringPrintf("0x%08x\n\n", resolved_addr2instr_);
}
+ // Dump .data.bimg.rel.ro entries.
+ DumpDataBimgRelRoEntries(os);
+
+ // Dump .bss summary, individual entries are dumped per dex file.
+ os << ".bss: ";
+ if (oat_file_.GetBssMethods().empty() && oat_file_.GetBssGcRoots().empty()) {
+ os << "empty.\n\n";
+ } else {
+ os << oat_file_.GetBssMethods().size() << " methods, ";
+ os << oat_file_.GetBssGcRoots().size() << " GC roots.\n\n";
+ }
+
// Dumping the dex file overview is compact enough to do even if header only.
DexFileData cumulative;
for (size_t i = 0; i < oat_dex_files_.size(); i++) {
@@ -1701,7 +1714,10 @@ class OatDumper {
CHECK(dex_cache != nullptr);
ArtMethod* method = runtime->GetClassLinker()->ResolveMethodWithoutInvokeType(
dex_method_idx, dex_cache, *options_.class_loader_);
- CHECK(method != nullptr);
+ if (method == nullptr) {
+ soa.Self()->ClearException();
+ return nullptr;
+ }
return verifier::MethodVerifier::VerifyMethodAndDump(
soa.Self(), vios, dex_method_idx, dex_file, dex_cache, *options_.class_loader_,
class_def, code_item, method, method_access_flags);
@@ -1927,6 +1943,66 @@ class OatDumper {
}
}
+ void DumpDataBimgRelRoEntries(std::ostream& os) {
+ os << ".data.bimg.rel.ro: ";
+ if (oat_file_.GetBootImageRelocations().empty()) {
+ os << "empty.\n\n";
+ return;
+ }
+
+ os << oat_file_.GetBootImageRelocations().size() << " entries.\n";
+ Runtime* runtime = Runtime::Current();
+ if (runtime != nullptr && !runtime->GetHeap()->GetBootImageSpaces().empty()) {
+ const std::vector<gc::space::ImageSpace*>& boot_image_spaces =
+ runtime->GetHeap()->GetBootImageSpaces();
+ ScopedObjectAccess soa(Thread::Current());
+ for (const uint32_t& object_offset : oat_file_.GetBootImageRelocations()) {
+ uint32_t entry_index = &object_offset - oat_file_.GetBootImageRelocations().data();
+ uint32_t entry_offset = entry_index * sizeof(oat_file_.GetBootImageRelocations()[0]);
+ os << StringPrintf(" 0x%x: 0x%08x", entry_offset, object_offset);
+ uint8_t* object = boot_image_spaces[0]->Begin() + object_offset;
+ bool found = false;
+ for (gc::space::ImageSpace* space : boot_image_spaces) {
+ uint64_t local_offset = object - space->Begin();
+ if (local_offset < space->GetImageHeader().GetImageSize()) {
+ if (space->GetImageHeader().GetObjectsSection().Contains(local_offset)) {
+ ObjPtr<mirror::Object> o = reinterpret_cast<mirror::Object*>(object);
+ if (o->IsString()) {
+ os << " String: " << o->AsString()->ToModifiedUtf8();
+ } else if (o->IsClass()) {
+ os << " Class: " << o->AsClass()->PrettyDescriptor();
+ } else {
+ os << StringPrintf(" 0x%08x %s",
+ object_offset,
+ o->GetClass()->PrettyDescriptor().c_str());
+ }
+ } else if (space->GetImageHeader().GetMethodsSection().Contains(local_offset)) {
+ ArtMethod* m = reinterpret_cast<ArtMethod*>(object);
+ os << " ArtMethod: " << m->PrettyMethod();
+ } else {
+ os << StringPrintf(" 0x%08x <unexpected section in %s>",
+ object_offset,
+ space->GetImageFilename().c_str());
+ }
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ os << StringPrintf(" 0x%08x <outside boot image spaces>", object_offset);
+ }
+ os << "\n";
+ }
+ } else {
+ for (const uint32_t& object_offset : oat_file_.GetBootImageRelocations()) {
+ uint32_t entry_index = &object_offset - oat_file_.GetBootImageRelocations().data();
+ uint32_t entry_offset = entry_index * sizeof(oat_file_.GetBootImageRelocations()[0]);
+ os << StringPrintf(" 0x%x: 0x%08x\n", entry_offset, object_offset);
+ }
+ }
+ os << "\n";
+ }
+
template <typename NameGetter>
void DumpBssEntries(std::ostream& os,
const char* slot_type,
@@ -2201,7 +2277,7 @@ class ImageDumper {
// Intern table is 8-byte aligned.
uint32_t end_caches = dex_cache_arrays_section.Offset() + dex_cache_arrays_section.Size();
- CHECK_ALIGNED(intern_section.Offset(), sizeof(uint64_t));
+ CHECK_EQ(RoundUp(end_caches, 8U), intern_section.Offset());
stats_.alignment_bytes += intern_section.Offset() - end_caches;
// Add space between intern table and class table.