OSDN Git Service

Add --include-cfi compiler option.
authorDavid Srbecky <dsrbecky@google.com>
Sun, 12 Apr 2015 10:40:39 +0000 (11:40 +0100)
committerDavid Srbecky <dsrbecky@google.com>
Mon, 13 Apr 2015 20:24:12 +0000 (21:24 +0100)
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

12 files changed:
compiler/dex/quick/codegen_util.cc
compiler/dex/quick/quick_cfi_test.cc
compiler/driver/compiler_options.cc
compiler/driver/compiler_options.h
compiler/elf_writer_debug.cc
compiler/elf_writer_debug.h
compiler/elf_writer_quick.cc
compiler/jit/jit_compiler.cc
compiler/jni/quick/jni_compiler.cc
compiler/oat_writer.cc
compiler/optimizing/optimizing_compiler.cc
dex2oat/dex2oat.cc

index 5ea36c2..9f4a318 100644 (file)
@@ -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);
index 6928acb..2db5a36 100644 (file)
@@ -60,6 +60,7 @@ class QuickCFITest : public CFITest {
       CompilerOptions::kDefaultTopKProfileThreshold,
       false,
       true,  // include_debug_symbols.
+      true,  // include_cfi
       false,
       false,
       false,
index de1f958..c5fc98a 100644 (file)
@@ -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),
index aa0db5d..bf3f8ec 100644 (file)
@@ -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_;
index 6df5ea9..f7811dd 100644 (file)
@@ -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);
index 4f1e333..2c03b98 100644 (file)
 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
index da1f81a..737b9d6 100644 (file)
@@ -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);
index cef9db2..be2c8c6 100644 (file)
@@ -77,6 +77,7 @@ JitCompiler::JitCompiler() : total_time_(0) {
       false,
       false,
       false,
+      false,
       false,  // pic
       nullptr,
       pass_manager_options,
index 8a14038..2402ea5 100644 (file)
@@ -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
index 4de287e..73d7210 100644 (file)
@@ -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;
index c2b5c99..56cea8a 100644 (file)
@@ -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(),
index 143dacd..eda7ec6 100644 (file)
@@ -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,