diff options
-rw-r--r-- | compiler/elf_builder.h | 2 | ||||
-rw-r--r-- | oatdump/oatdump.cc | 49 |
2 files changed, 37 insertions, 14 deletions
diff --git a/compiler/elf_builder.h b/compiler/elf_builder.h index ef44a6fe1c..26ab281741 100644 --- a/compiler/elf_builder.h +++ b/compiler/elf_builder.h @@ -841,7 +841,7 @@ class ElfBuilder FINAL { load.p_type = PT_LOAD; load.p_flags = PF_R; load.p_offset = load.p_vaddr = load.p_paddr = 0; - load.p_filesz = load.p_memsz = sections_[0]->header_.sh_offset; + load.p_filesz = load.p_memsz = sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * kMaxProgramHeaders; load.p_align = kPageSize; phdrs.push_back(load); } diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index 0e17fc2efa..00a691bcda 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -101,9 +101,11 @@ const DexFile* OpenDexFile(const OatFile::OatDexFile* oat_dex_file, std::string* template <typename ElfTypes> class OatSymbolizer FINAL { public: - OatSymbolizer(const OatFile* oat_file, const std::string& output_name) : - oat_file_(oat_file), builder_(nullptr), - output_name_(output_name.empty() ? "symbolized.oat" : output_name) { + OatSymbolizer(const OatFile* oat_file, const std::string& output_name, bool no_bits) : + oat_file_(oat_file), + builder_(nullptr), + output_name_(output_name.empty() ? "symbolized.oat" : output_name), + no_bits_(no_bits) { } typedef void (OatSymbolizer::*Callback)(const DexFile::ClassDef&, @@ -132,17 +134,25 @@ class OatSymbolizer FINAL { auto* strtab = builder_->GetStrTab(); auto* symtab = builder_->GetSymTab(); - rodata->Start(); const uint8_t* rodata_begin = oat_file_->Begin(); const size_t rodata_size = oat_file_->GetOatHeader().GetExecutableOffset(); - rodata->WriteFully(rodata_begin, rodata_size); - rodata->End(); + if (no_bits_) { + rodata->WriteNoBitsSection(rodata_size); + } else { + rodata->Start(); + rodata->WriteFully(rodata_begin, rodata_size); + rodata->End(); + } - text->Start(); const uint8_t* text_begin = oat_file_->Begin() + rodata_size; const size_t text_size = oat_file_->End() - text_begin; - text->WriteFully(text_begin, text_size); - text->End(); + if (no_bits_) { + text->WriteNoBitsSection(text_size); + } else { + text->Start(); + text->WriteFully(text_begin, text_size); + text->End(); + } if (oat_file_->BssSize() != 0) { bss->WriteNoBitsSection(oat_file_->BssSize()); @@ -364,6 +374,7 @@ class OatSymbolizer FINAL { std::unique_ptr<ElfBuilder<ElfTypes> > builder_; std::unordered_map<uint32_t, uint32_t> state_; const std::string output_name_; + bool no_bits_; }; class OatDumperOptions { @@ -2550,7 +2561,7 @@ static int DumpOat(Runtime* runtime, const char* oat_filename, OatDumperOptions* } } -static int SymbolizeOat(const char* oat_filename, std::string& output_name) { +static int SymbolizeOat(const char* oat_filename, std::string& output_name, bool no_bits) { std::string error_msg; OatFile* oat_file = OatFile::Open(oat_filename, oat_filename, nullptr, nullptr, false, nullptr, &error_msg); @@ -2563,10 +2574,10 @@ static int SymbolizeOat(const char* oat_filename, std::string& output_name) { // Try to produce an ELF file of the same type. This is finicky, as we have used 32-bit ELF // files for 64-bit code in the past. if (Is64BitInstructionSet(oat_file->GetOatHeader().GetInstructionSet())) { - OatSymbolizer<ElfTypes64> oat_symbolizer(oat_file, output_name); + OatSymbolizer<ElfTypes64> oat_symbolizer(oat_file, output_name, no_bits); result = oat_symbolizer.Symbolize(); } else { - OatSymbolizer<ElfTypes32> oat_symbolizer(oat_file, output_name); + OatSymbolizer<ElfTypes32> oat_symbolizer(oat_file, output_name, no_bits); result = oat_symbolizer.Symbolize(); } if (!result) { @@ -2609,6 +2620,8 @@ struct OatdumpArgs : public CmdlineArgs { } else if (option.starts_with("--symbolize=")) { oat_filename_ = option.substr(strlen("--symbolize=")).data(); symbolize_ = true; + } else if (option.starts_with("--only-keep-debug")) { + only_keep_debug_ = true; } else if (option.starts_with("--class-filter=")) { class_filter_ = option.substr(strlen("--class-filter=")).data(); } else if (option.starts_with("--method-filter=")) { @@ -2703,6 +2716,10 @@ struct OatdumpArgs : public CmdlineArgs { " --symbolize=<file.oat>: output a copy of file.oat with elf symbols included.\n" " Example: --symbolize=/system/framework/boot.oat\n" "\n" + " --only-keep-debug<file.oat>: Modifies the behaviour of --symbolize so that\n" + " .rodata and .text sections are omitted in the output file to save space.\n" + " Example: --symbolize=/system/framework/boot.oat --only-keep-debug\n" + "\n" " --class-filter=<class name>: only dumps classes that contain the filter.\n" " Example: --class-filter=com.example.foo\n" "\n" @@ -2732,6 +2749,7 @@ struct OatdumpArgs : public CmdlineArgs { bool dump_code_info_stack_maps_ = false; bool disassemble_code_ = true; bool symbolize_ = false; + bool only_keep_debug_ = false; bool list_classes_ = false; bool list_methods_ = false; bool dump_header_only_ = false; @@ -2772,7 +2790,12 @@ struct OatdumpMain : public CmdlineMain<OatdumpArgs> { MemMap::Init(); if (args_->symbolize_) { - return SymbolizeOat(args_->oat_filename_, args_->output_name_) == EXIT_SUCCESS; + // ELF has special kind of section called SHT_NOBITS which allows us to create + // sections which exist but their data is omitted from the ELF file to save space. + // This is what "strip --only-keep-debug" does when it creates separate ELF file + // with only debug data. We use it in similar way to exclude .rodata and .text. + bool no_bits = args_->only_keep_debug_; + return SymbolizeOat(args_->oat_filename_, args_->output_name_, no_bits) == EXIT_SUCCESS; } else { return DumpOat(nullptr, args_->oat_filename_, |