Tell GDB about Quick ART generated code

This is actually a lot of work.  To do this, we need:
.debug_info
.debug_abbrev
.debug_frame
.debug_str

These are generated into the OAT file by OatWriter and ElfWriterQuick.

Since the Quick ART runtime doesn't use dlopen to load the OAT files,
GDB can't find this information.  Use the alternate GDB JIT interface,
which can be invoked at runtime. To use this interface, an ELF image
needs to be built in memory.  Read the information from the OAT file,
fixup the addresses to point to the real locations, add a symbol table
to hold the .text symbol, and then let GDB know about the information,
which will be read from the runtime address space.

This is quite primitive now, and could be cleaned up considerably.  It
probably needs symbol table entries for the methods, and descriptions of
parameters and return types.

Currently only supported for X86.

This defaults to enabled for debug builds. Added dexoat --gen-gdb-info
and --no-gen-gdb-info flags to override.

Change-Id: I4d18b2370f6dfaa00c8cc1925f10717be3bd1a62
Signed-off-by: Mark Mendell <mark.p.mendell@intel.com>
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 931055b..708cce6 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -31,6 +31,7 @@
 #include "dex/verification_results.h"
 #include "dex/verified_method.h"
 #include "dex/quick/dex_file_method_inliner.h"
+#include "driver/compiler_options.h"
 #include "jni_internal.h"
 #include "object_utils.h"
 #include "runtime.h"
@@ -323,10 +324,12 @@
       compiler_enable_auto_elf_loading_(NULL),
       compiler_get_method_code_addr_(NULL),
       support_boot_image_fixup_(instruction_set != kMips),
+      cfi_info_(nullptr),
       dedupe_code_("dedupe code"),
       dedupe_mapping_table_("dedupe mapping table"),
       dedupe_vmap_table_("dedupe vmap table"),
-      dedupe_gc_map_("dedupe gc map") {
+      dedupe_gc_map_("dedupe gc map"),
+      dedupe_cfi_info_("dedupe cfi info") {
   DCHECK(compiler_options_ != nullptr);
   DCHECK(verification_results_ != nullptr);
   DCHECK(method_inliner_map_ != nullptr);
@@ -341,6 +344,11 @@
   if (!image_) {
     CHECK(image_classes_.get() == NULL);
   }
+
+  // Are we generating CFI information?
+  if (compiler_options->GetGenerateGDBInformation()) {
+    cfi_info_.reset(compiler_backend_->GetCallFrameInformationInitialization(*this));
+  }
 }
 
 std::vector<uint8_t>* CompilerDriver::DeduplicateCode(const std::vector<uint8_t>& code) {
@@ -359,6 +367,13 @@
   return dedupe_gc_map_.Add(Thread::Current(), code);
 }
 
+std::vector<uint8_t>* CompilerDriver::DeduplicateCFIInfo(const std::vector<uint8_t>* cfi_info) {
+  if (cfi_info == nullptr) {
+    return nullptr;
+  }
+  return dedupe_cfi_info_.Add(Thread::Current(), *cfi_info);
+}
+
 CompilerDriver::~CompilerDriver() {
   Thread* self = Thread::Current();
   {
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 5a5fc36..6ccbf0f 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -493,6 +493,15 @@
   std::vector<uint8_t>* DeduplicateMappingTable(const std::vector<uint8_t>& code);
   std::vector<uint8_t>* DeduplicateVMapTable(const std::vector<uint8_t>& code);
   std::vector<uint8_t>* DeduplicateGCMap(const std::vector<uint8_t>& code);
+  std::vector<uint8_t>* DeduplicateCFIInfo(const std::vector<uint8_t>* cfi_info);
+
+  /*
+   * @brief return the pointer to the Call Frame Information.
+   * @return pointer to call frame information for this compilation.
+   */
+  std::vector<uint8_t>* GetCallFrameInformation() const {
+    return cfi_info_.get();
+  }
 
  private:
   // Compute constant code and method pointers when possible
@@ -625,6 +634,9 @@
 
   bool support_boot_image_fixup_;
 
+  // Call Frame Information, which might be generated to help stack tracebacks.
+  UniquePtr<std::vector<uint8_t> > cfi_info_;
+
   // DeDuplication data structures, these own the corresponding byte arrays.
   class DedupeHashFunc {
    public:
@@ -663,6 +675,7 @@
   DedupeSet<std::vector<uint8_t>, size_t, DedupeHashFunc, 4> dedupe_mapping_table_;
   DedupeSet<std::vector<uint8_t>, size_t, DedupeHashFunc, 4> dedupe_vmap_table_;
   DedupeSet<std::vector<uint8_t>, size_t, DedupeHashFunc, 4> dedupe_gc_map_;
+  DedupeSet<std::vector<uint8_t>, size_t, DedupeHashFunc, 4> dedupe_cfi_info_;
 
   DISALLOW_COPY_AND_ASSIGN(CompilerDriver);
 };
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h
index 9f6745b..39738ab 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -43,7 +43,8 @@
     large_method_threshold_(kDefaultLargeMethodThreshold),
     small_method_threshold_(kDefaultSmallMethodThreshold),
     tiny_method_threshold_(kDefaultTinyMethodThreshold),
-    num_dex_methods_threshold_(kDefaultNumDexMethodsThreshold)
+    num_dex_methods_threshold_(kDefaultNumDexMethodsThreshold),
+    generate_gdb_information_(false)
 #ifdef ART_SEA_IR_MODE
     , sea_ir_mode_(false)
 #endif
@@ -54,7 +55,8 @@
                   size_t large_method_threshold,
                   size_t small_method_threshold,
                   size_t tiny_method_threshold,
-                  size_t num_dex_methods_threshold
+                  size_t num_dex_methods_threshold,
+                  bool generate_gdb_information
 #ifdef ART_SEA_IR_MODE
                   , bool sea_ir_mode
 #endif
@@ -64,7 +66,8 @@
     large_method_threshold_(large_method_threshold),
     small_method_threshold_(small_method_threshold),
     tiny_method_threshold_(tiny_method_threshold),
-    num_dex_methods_threshold_(num_dex_methods_threshold)
+    num_dex_methods_threshold_(num_dex_methods_threshold),
+    generate_gdb_information_(generate_gdb_information)
 #ifdef ART_SEA_IR_MODE
     , sea_ir_mode_(sea_ir_mode)
 #endif
@@ -118,6 +121,10 @@
   bool GetSeaIrMode();
 #endif
 
+  bool GetGenerateGDBInformation() const {
+    return generate_gdb_information_;
+  }
+
  private:
   CompilerFilter compiler_filter_;
   size_t huge_method_threshold_;
@@ -125,6 +132,7 @@
   size_t small_method_threshold_;
   size_t tiny_method_threshold_;
   size_t num_dex_methods_threshold_;
+  bool generate_gdb_information_;
 
 #ifdef ART_SEA_IR_MODE
   bool sea_ir_mode_;