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
diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc
index 5ea36c2..9f4a318 100644
--- a/compiler/dex/quick/codegen_util.cc
+++ b/compiler/dex/quick/codegen_util.cc
@@ -1071,7 +1071,7 @@
pc_rel_temp_(nullptr),
dex_cache_arrays_min_offset_(std::numeric_limits<uint32_t>::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 6928acb..2db5a36 100644
--- a/compiler/dex/quick/quick_cfi_test.cc
+++ b/compiler/dex/quick/quick_cfi_test.cc
@@ -60,6 +60,7 @@
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 de1f958..c5fc98a 100644
--- a/compiler/driver/compiler_options.cc
+++ b/compiler/driver/compiler_options.cc
@@ -31,6 +31,7 @@
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 @@
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 @@
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 aa0db5d..bf3f8ec 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -65,6 +65,7 @@
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 @@
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 @@
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 6df5ea9..f7811dd 100644
--- a/compiler/elf_writer_debug.cc
+++ b/compiler/elf_writer_debug.cc
@@ -149,6 +149,25 @@
UNREACHABLE();
}
+void WriteEhFrame(const CompilerDriver* compiler,
+ OatWriter* oat_writer,
+ uint32_t text_section_offset,
+ std::vector<uint8_t>* 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<uint8_t>* 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 @@
void WriteDebugSections(const CompilerDriver* compiler,
OatWriter* oat_writer,
uint32_t text_section_offset,
- std::vector<uint8_t>* eh_frame,
std::vector<uint8_t>* debug_info,
std::vector<uint8_t>* debug_abbrev,
std::vector<uint8_t>* debug_str,
@@ -175,19 +193,6 @@
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<uint8_t>* 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 4f1e333..2c03b98 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<uint8_t>* eh_frame);
+
void WriteDebugSections(const CompilerDriver* compiler,
OatWriter* oat_writer,
uint32_t text_section_offset,
- std::vector<uint8_t>* eh_frame_data,
- std::vector<uint8_t>* debug_info_data,
- std::vector<uint8_t>* debug_abbrev_data,
- std::vector<uint8_t>* debug_str_data,
- std::vector<uint8_t>* debug_line_data);
+ std::vector<uint8_t>* debug_info,
+ std::vector<uint8_t>* debug_abbrev,
+ std::vector<uint8_t>* debug_str,
+ std::vector<uint8_t>* debug_line);
} // namespace dwarf
} // namespace art
diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc
index da1f81a..737b9d6 100644
--- a/compiler/elf_writer_quick.cc
+++ b/compiler/elf_writer_quick.cc
@@ -144,6 +144,16 @@
return false;
}
+ if (compiler_driver_->GetCompilerOptions().GetIncludeCFI() &&
+ !oat_writer->GetMethodDebugInfo().empty()) {
+ ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> 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 @@
}
typedef ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> 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 @@
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 cef9db2..be2c8c6 100644
--- a/compiler/jit/jit_compiler.cc
+++ b/compiler/jit/jit_compiler.cc
@@ -77,6 +77,7 @@
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 8a14038..2402ea5 100644
--- a/compiler/jni/quick/jni_compiler.cc
+++ b/compiler/jni/quick/jni_compiler.cc
@@ -94,7 +94,7 @@
// Assembler that holds generated instructions
std::unique_ptr<Assembler> 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 4de287e..73d7210 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -450,7 +450,8 @@
}
}
- 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 c2b5c99..56cea8a 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -516,7 +516,7 @@
return nullptr;
}
codegen->GetAssembler()->cfi().SetEnabled(
- compiler_driver->GetCompilerOptions().GetIncludeDebugSymbols());
+ compiler_driver->GetCompilerOptions().GetIncludeCFI());
PassInfoPrinter pass_info_printer(graph,
method_name.c_str(),