Add mini-debug-info generation mode for JIT.

This excludes everything that is not needed for backtraces and
compresses the resulting ELF file (wrapped in another ELF file).

This approximately halves the size of the debug data for JIT.
The vast majority of the data is the overhead of ELF header.
We could amortize this by storing more methods per ELF file.

It also adds NOBITS .text section to all debug ELF files,
as that seems necessary for gdb to find the symbols.
On the other hand, it removes .rodata from debug ELF files.

Test: Manually tested that gdb can use this data to unwind.
Test: m test-art-host-gtest
Test: testrunner.py --optimizing --host
Test: testrunner.py -t 137-cfi

Change-Id: Ic0a2dfa953cb79973a7b2ae99d32018599e61171
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 73c72fc..24b1a12 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -1224,7 +1224,7 @@
     }
 
     const CompilerOptions& compiler_options = GetCompilerDriver()->GetCompilerOptions();
-    if (compiler_options.GetGenerateDebugInfo()) {
+    if (compiler_options.GenerateAnyDebugInfo()) {
       const auto* method_header = reinterpret_cast<const OatQuickMethodHeader*>(code);
       const uintptr_t code_address = reinterpret_cast<uintptr_t>(method_header->GetCode());
       debug::MethodDebugInfo info = {};
@@ -1244,10 +1244,13 @@
       info.frame_size_in_bytes = method_header->GetFrameSizeInBytes();
       info.code_info = nullptr;
       info.cfi = jni_compiled_method.GetCfi();
-      std::vector<uint8_t> elf_file = debug::WriteDebugElfFileForMethods(
+      // If both flags are passed, generate full debug info.
+      const bool mini_debug_info = !compiler_options.GetGenerateDebugInfo();
+      std::vector<uint8_t> elf_file = debug::MakeElfFileForJIT(
           GetCompilerDriver()->GetInstructionSet(),
           GetCompilerDriver()->GetInstructionSetFeatures(),
-          ArrayRef<const debug::MethodDebugInfo>(&info, 1));
+          mini_debug_info,
+          info);
       CreateJITCodeEntryForAddress(code_address, std::move(elf_file));
     }
 
@@ -1352,7 +1355,7 @@
   }
 
   const CompilerOptions& compiler_options = GetCompilerDriver()->GetCompilerOptions();
-  if (compiler_options.GetGenerateDebugInfo()) {
+  if (compiler_options.GenerateAnyDebugInfo()) {
     const auto* method_header = reinterpret_cast<const OatQuickMethodHeader*>(code);
     const uintptr_t code_address = reinterpret_cast<uintptr_t>(method_header->GetCode());
     debug::MethodDebugInfo info = {};
@@ -1372,10 +1375,13 @@
     info.frame_size_in_bytes = method_header->GetFrameSizeInBytes();
     info.code_info = stack_map_size == 0 ? nullptr : stack_map_data;
     info.cfi = ArrayRef<const uint8_t>(*codegen->GetAssembler()->cfi().data());
-    std::vector<uint8_t> elf_file = debug::WriteDebugElfFileForMethods(
+    // If both flags are passed, generate full debug info.
+    const bool mini_debug_info = !compiler_options.GetGenerateDebugInfo();
+    std::vector<uint8_t> elf_file = debug::MakeElfFileForJIT(
         GetCompilerDriver()->GetInstructionSet(),
         GetCompilerDriver()->GetInstructionSetFeatures(),
-        ArrayRef<const debug::MethodDebugInfo>(&info, 1));
+        mini_debug_info,
+        info);
     CreateJITCodeEntryForAddress(code_address, std::move(elf_file));
   }