summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Srbecky <dsrbecky@google.com>2015-04-12 11:40:39 +0100
committerDavid Srbecky <dsrbecky@google.com>2015-04-13 21:24:12 +0100
commit8dc7324da5bd0f2afd2ab558ab04882329a61fe8 (patch)
tree245ce4265cc31990fa6d2f6e792ccd9d44af1dc1
parent4af290af4e89cfbc3a4e1ada79909ccee353361a (diff)
downloadart-8dc7324da5bd0f2afd2ab558ab04882329a61fe8.zip
art-8dc7324da5bd0f2afd2ab558ab04882329a61fe8.tar.gz
art-8dc7324da5bd0f2afd2ab558ab04882329a61fe8.tar.bz2
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
-rw-r--r--compiler/dex/quick/codegen_util.cc2
-rw-r--r--compiler/dex/quick/quick_cfi_test.cc1
-rw-r--r--compiler/driver/compiler_options.cc3
-rw-r--r--compiler/driver/compiler_options.h7
-rw-r--r--compiler/elf_writer_debug.cc33
-rw-r--r--compiler/elf_writer_debug.h14
-rw-r--r--compiler/elf_writer_quick.cc13
-rw-r--r--compiler/jit/jit_compiler.cc1
-rw-r--r--compiler/jni/quick/jni_compiler.cc2
-rw-r--r--compiler/oat_writer.cc3
-rw-r--r--compiler/optimizing/optimizing_compiler.cc2
-rw-r--r--dex2oat/dex2oat.cc11
12 files changed, 66 insertions, 26 deletions
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 @@ Mir2Lir::Mir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena
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 @@ 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 de1f958..c5fc98a 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 aa0db5d..bf3f8ec 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 6df5ea9..f7811dd 100644
--- a/compiler/elf_writer_debug.cc
+++ b/compiler/elf_writer_debug.cc
@@ -149,6 +149,25 @@ static void WriteEhFrameCIE(InstructionSet isa, std::vector<uint8_t>* eh_frame)
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 @@ static void WriteEhFrameCIE(InstructionSet isa, 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,
std::vector<uint8_t>* debug_info,
std::vector<uint8_t>* debug_abbrev,
std::vector<uint8_t>* 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<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 @@ bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
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 @@ static void WriteDebugSymbols(const CompilerDriver* compiler_driver,
}
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 @@ 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 cef9db2..be2c8c6 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 8a14038..2402ea5 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<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 @@ 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 c2b5c99..56cea8a 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 143dacd..eda7ec6 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 <argument>: 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,