From 8dc7324da5bd0f2afd2ab558ab04882329a61fe8 Mon Sep 17 00:00:00 2001 From: David Srbecky Date: Sun, 12 Apr 2015 11:40:39 +0100 Subject: [PATCH] Add --include-cfi compiler option. Decouple generation of CFI from the rest of debug symbols. This makes it possible to generate oat with CFI but without the rest of debug symbols. This is in line with intention of the .eh_frame section. The section does not have the .debug_ prefix because it is considered somewhat different to the rest of debug symbols. Change-Id: I32816ecd4f30ac4e0dc69d69a4993e349c737f96 --- compiler/dex/quick/codegen_util.cc | 2 +- compiler/dex/quick/quick_cfi_test.cc | 1 + compiler/driver/compiler_options.cc | 3 +++ compiler/driver/compiler_options.h | 7 +++++++ compiler/elf_writer_debug.cc | 33 +++++++++++++++++------------- compiler/elf_writer_debug.h | 14 ++++++++----- compiler/elf_writer_quick.cc | 13 +++++++++--- compiler/jit/jit_compiler.cc | 1 + compiler/jni/quick/jni_compiler.cc | 2 +- compiler/oat_writer.cc | 3 ++- compiler/optimizing/optimizing_compiler.cc | 2 +- dex2oat/dex2oat.cc | 11 ++++++++++ 12 files changed, 66 insertions(+), 26 deletions(-) diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc index 5ea36c276..9f4a318cc 100644 --- a/compiler/dex/quick/codegen_util.cc +++ b/compiler/dex/quick/codegen_util.cc @@ -1071,7 +1071,7 @@ Mir2Lir::Mir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena pc_rel_temp_(nullptr), dex_cache_arrays_min_offset_(std::numeric_limits::max()), cfi_(&last_lir_insn_, - cu->compiler_driver->GetCompilerOptions().GetIncludeDebugSymbols(), + cu->compiler_driver->GetCompilerOptions().GetIncludeCFI(), arena), in_to_reg_storage_mapping_(arena) { switch_tables_.reserve(4); diff --git a/compiler/dex/quick/quick_cfi_test.cc b/compiler/dex/quick/quick_cfi_test.cc index 6928acbc8..2db5a366d 100644 --- a/compiler/dex/quick/quick_cfi_test.cc +++ b/compiler/dex/quick/quick_cfi_test.cc @@ -60,6 +60,7 @@ class QuickCFITest : public CFITest { CompilerOptions::kDefaultTopKProfileThreshold, false, true, // include_debug_symbols. + true, // include_cfi false, false, false, diff --git a/compiler/driver/compiler_options.cc b/compiler/driver/compiler_options.cc index de1f95885..c5fc98a95 100644 --- a/compiler/driver/compiler_options.cc +++ b/compiler/driver/compiler_options.cc @@ -31,6 +31,7 @@ CompilerOptions::CompilerOptions() top_k_profile_threshold_(kDefaultTopKProfileThreshold), debuggable_(false), include_debug_symbols_(kDefaultIncludeDebugSymbols), + include_cfi_(false), implicit_null_checks_(true), implicit_so_checks_(true), implicit_suspend_checks_(false), @@ -56,6 +57,7 @@ CompilerOptions::CompilerOptions(CompilerFilter compiler_filter, double top_k_profile_threshold, bool debuggable, bool include_debug_symbols, + bool include_cfi, bool implicit_null_checks, bool implicit_so_checks, bool implicit_suspend_checks, @@ -75,6 +77,7 @@ CompilerOptions::CompilerOptions(CompilerFilter compiler_filter, top_k_profile_threshold_(top_k_profile_threshold), debuggable_(debuggable), include_debug_symbols_(include_debug_symbols), + include_cfi_(include_cfi), implicit_null_checks_(implicit_null_checks), implicit_so_checks_(implicit_so_checks), implicit_suspend_checks_(implicit_suspend_checks), diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h index aa0db5d87..bf3f8ec08 100644 --- a/compiler/driver/compiler_options.h +++ b/compiler/driver/compiler_options.h @@ -65,6 +65,7 @@ class CompilerOptions FINAL { double top_k_profile_threshold, bool debuggable, bool include_debug_symbols, + bool include_cfi, bool implicit_null_checks, bool implicit_so_checks, bool implicit_suspend_checks, @@ -149,6 +150,11 @@ class CompilerOptions FINAL { return include_debug_symbols_; } + bool GetIncludeCFI() const { + // include-debug-symbols implies include-cfi. + return include_cfi_ || include_debug_symbols_; + } + bool GetImplicitNullChecks() const { return implicit_null_checks_; } @@ -207,6 +213,7 @@ class CompilerOptions FINAL { const double top_k_profile_threshold_; const bool debuggable_; const bool include_debug_symbols_; + const bool include_cfi_; const bool implicit_null_checks_; const bool implicit_so_checks_; const bool implicit_suspend_checks_; diff --git a/compiler/elf_writer_debug.cc b/compiler/elf_writer_debug.cc index 6df5ea9ee..f7811dd18 100644 --- a/compiler/elf_writer_debug.cc +++ b/compiler/elf_writer_debug.cc @@ -149,6 +149,25 @@ static void WriteEhFrameCIE(InstructionSet isa, std::vector* eh_frame) UNREACHABLE(); } +void WriteEhFrame(const CompilerDriver* compiler, + OatWriter* oat_writer, + uint32_t text_section_offset, + std::vector* eh_frame) { + const auto& method_infos = oat_writer->GetMethodDebugInfo(); + const InstructionSet isa = compiler->GetInstructionSet(); + size_t cie_offset = eh_frame->size(); + auto* eh_frame_patches = oat_writer->GetAbsolutePatchLocationsFor(".eh_frame"); + WriteEhFrameCIE(isa, eh_frame); + for (const OatWriter::DebugInfo& mi : method_infos) { + const SwapVector* opcodes = mi.compiled_method_->GetCFIInfo(); + if (opcodes != nullptr) { + WriteEhFrameFDE(Is64BitInstructionSet(isa), cie_offset, + text_section_offset + mi.low_pc_, mi.high_pc_ - mi.low_pc_, + opcodes, eh_frame, eh_frame_patches); + } + } +} + /* * @brief Generate the DWARF sections. * @param oat_writer The Oat file Writer. @@ -161,7 +180,6 @@ static void WriteEhFrameCIE(InstructionSet isa, std::vector* eh_frame) void WriteDebugSections(const CompilerDriver* compiler, OatWriter* oat_writer, uint32_t text_section_offset, - std::vector* eh_frame, std::vector* debug_info, std::vector* debug_abbrev, std::vector* debug_str, @@ -175,19 +193,6 @@ void WriteDebugSections(const CompilerDriver* compiler, cunit_high_pc = std::max(cunit_high_pc, method_info.high_pc_); } - // Write .eh_frame section. - auto* eh_frame_patches = oat_writer->GetAbsolutePatchLocationsFor(".eh_frame"); - size_t cie_offset = eh_frame->size(); - WriteEhFrameCIE(isa, eh_frame); - for (const OatWriter::DebugInfo& mi : method_infos) { - const SwapVector* opcodes = mi.compiled_method_->GetCFIInfo(); - if (opcodes != nullptr) { - WriteEhFrameFDE(Is64BitInstructionSet(isa), cie_offset, - text_section_offset + mi.low_pc_, mi.high_pc_ - mi.low_pc_, - opcodes, eh_frame, eh_frame_patches); - } - } - // Write .debug_info section. size_t debug_abbrev_offset = debug_abbrev->size(); DebugInfoEntryWriter<> info(false /* 32 bit */, debug_abbrev); diff --git a/compiler/elf_writer_debug.h b/compiler/elf_writer_debug.h index 4f1e333bd..2c03b9877 100644 --- a/compiler/elf_writer_debug.h +++ b/compiler/elf_writer_debug.h @@ -24,14 +24,18 @@ namespace art { namespace dwarf { +void WriteEhFrame(const CompilerDriver* compiler, + OatWriter* oat_writer, + uint32_t text_section_offset, + std::vector* eh_frame); + void WriteDebugSections(const CompilerDriver* compiler, OatWriter* oat_writer, uint32_t text_section_offset, - std::vector* eh_frame_data, - std::vector* debug_info_data, - std::vector* debug_abbrev_data, - std::vector* debug_str_data, - std::vector* debug_line_data); + std::vector* debug_info, + std::vector* debug_abbrev, + std::vector* debug_str, + std::vector* debug_line); } // namespace dwarf } // namespace art diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc index da1f81a52..737b9d613 100644 --- a/compiler/elf_writer_quick.cc +++ b/compiler/elf_writer_quick.cc @@ -144,6 +144,16 @@ bool ElfWriterQuickGetCompilerOptions().GetIncludeCFI() && + !oat_writer->GetMethodDebugInfo().empty()) { + ElfRawSectionBuilder eh_frame( + ".eh_frame", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, 4, 0); + dwarf::WriteEhFrame(compiler_driver_, oat_writer, + builder->GetTextBuilder().GetSection()->sh_addr, + eh_frame.GetBuffer()); + builder->RegisterRawSection(eh_frame); + } + if (compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols() && !oat_writer->GetMethodDebugInfo().empty()) { WriteDebugSymbols(compiler_driver_, builder.get(), oat_writer); @@ -198,7 +208,6 @@ static void WriteDebugSymbols(const CompilerDriver* compiler_driver, } typedef ElfRawSectionBuilder Section; - Section eh_frame(".eh_frame", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, 4, 0); Section debug_info(".debug_info", SHT_PROGBITS, 0, nullptr, 0, 1, 0); Section debug_abbrev(".debug_abbrev", SHT_PROGBITS, 0, nullptr, 0, 1, 0); Section debug_str(".debug_str", SHT_PROGBITS, 0, nullptr, 0, 1, 0); @@ -207,13 +216,11 @@ static void WriteDebugSymbols(const CompilerDriver* compiler_driver, dwarf::WriteDebugSections(compiler_driver, oat_writer, builder->GetTextBuilder().GetSection()->sh_addr, - eh_frame.GetBuffer(), debug_info.GetBuffer(), debug_abbrev.GetBuffer(), debug_str.GetBuffer(), debug_line.GetBuffer()); - builder->RegisterRawSection(eh_frame); builder->RegisterRawSection(debug_info); builder->RegisterRawSection(debug_abbrev); builder->RegisterRawSection(debug_str); diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc index cef9db2ee..be2c8c61b 100644 --- a/compiler/jit/jit_compiler.cc +++ b/compiler/jit/jit_compiler.cc @@ -77,6 +77,7 @@ JitCompiler::JitCompiler() : total_time_(0) { false, false, false, + false, false, // pic nullptr, pass_manager_options, diff --git a/compiler/jni/quick/jni_compiler.cc b/compiler/jni/quick/jni_compiler.cc index 8a1403807..2402ea50b 100644 --- a/compiler/jni/quick/jni_compiler.cc +++ b/compiler/jni/quick/jni_compiler.cc @@ -94,7 +94,7 @@ CompiledMethod* ArtJniCompileMethodInternal(CompilerDriver* driver, // Assembler that holds generated instructions std::unique_ptr jni_asm(Assembler::Create(instruction_set)); - jni_asm->cfi().SetEnabled(driver->GetCompilerOptions().GetIncludeDebugSymbols()); + jni_asm->cfi().SetEnabled(driver->GetCompilerOptions().GetIncludeCFI()); // Offsets into data structures // TODO: if cross compiling these offsets are for the host not the target diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc index 4de287e74..73d7210fe 100644 --- a/compiler/oat_writer.cc +++ b/compiler/oat_writer.cc @@ -450,7 +450,8 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor { } } - if (writer_->compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) { + if (writer_->compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols() || + writer_->compiler_driver_->GetCompilerOptions().GetIncludeCFI()) { // Record debug information for this function if we are doing that. const uint32_t quick_code_start = quick_code_offset - writer_->oat_header_->GetExecutableOffset() - thumb_offset; diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index c2b5c997f..56cea8aba 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -516,7 +516,7 @@ CompiledMethod* OptimizingCompiler::TryCompile(const DexFile::CodeItem* code_ite return nullptr; } codegen->GetAssembler()->cfi().SetEnabled( - compiler_driver->GetCompilerOptions().GetIncludeDebugSymbols()); + compiler_driver->GetCompilerOptions().GetIncludeCFI()); PassInfoPrinter pass_info_printer(graph, method_name.c_str(), diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 143dacdf6..eda7ec6f6 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -231,6 +231,11 @@ NO_RETURN static void Usage(const char* fmt, ...) { UsageError(""); UsageError(" --no-include-debug-symbols: Do not include ELF symbols in this oat file"); UsageError(""); + UsageError(" --include-cfi: Include call frame information in the .eh_frame section."); + UsageError(" The --include-debug-symbols option implies --include-cfi."); + UsageError(""); + UsageError(" --no-include-cfi: Do not include call frame information in the .eh_frame section."); + UsageError(""); UsageError(" --runtime-arg : used to specify various arguments for the runtime,"); UsageError(" such as initial heap size, maximum heap size, and verbose output."); UsageError(" Use a separate --runtime-arg switch for each argument."); @@ -496,6 +501,7 @@ class Dex2Oat FINAL { bool debuggable = false; bool include_patch_information = CompilerOptions::kDefaultIncludePatchInformation; bool include_debug_symbols = kIsDebugBuild; + bool include_cfi = kIsDebugBuild; bool watch_dog_enabled = true; bool abort_on_hard_verifier_error = false; bool requested_specific_compiler = false; @@ -677,6 +683,10 @@ class Dex2Oat FINAL { include_debug_symbols = true; } else if (option == "--no-include-debug-symbols" || option == "--strip-symbols") { include_debug_symbols = false; + } else if (option == "--include-cfi") { + include_cfi = true; + } else if (option == "--no-include-cfi") { + include_cfi = false; } else if (option == "--debuggable") { debuggable = true; } else if (option.starts_with("--profile-file=")) { @@ -932,6 +942,7 @@ class Dex2Oat FINAL { top_k_profile_threshold, debuggable, include_debug_symbols, + include_cfi, implicit_null_checks, implicit_so_checks, implicit_suspend_checks, -- 2.11.0