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.tar.gz
art-8dc7324da5bd0f2afd2ab558ab04882329a61fe8.tar.bz2
art-8dc7324da5bd0f2afd2ab558ab04882329a61fe8.zip
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 5ea36c2769..9f4a318cc2 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 6928acbc8b..2db5a366df 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 de1f95885f..c5fc98a957 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 aa0db5d87b..bf3f8ec08a 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 6df5ea9eef..f7811dd18b 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 4f1e333bd9..2c03b98777 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 da1f81a52e..737b9d613e 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 cef9db2eef..be2c8c61b0 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 8a14038074..2402ea50bf 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 4de287e745..73d7210fe5 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 c2b5c997f4..56cea8aba7 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 143dacdf67..eda7ec6f6f 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,