summaryrefslogtreecommitdiffstats
path: root/compiler/oat_writer.cc
diff options
context:
space:
mode:
authorMark Mendell <mark.p.mendell@intel.com>2014-02-10 16:14:35 -0800
committerIan Rogers <irogers@google.com>2014-03-02 11:57:10 -0800
commitae9fd93c39a341e2dffe15c61cc7d9e841fa92c4 (patch)
treee5f70dc307945fd510660ebde1fd259aecdf66a1 /compiler/oat_writer.cc
parent9fab32265f35c808b216210a8d5bebd931279041 (diff)
downloadart-ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4.zip
art-ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4.tar.gz
art-ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4.tar.bz2
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>
Diffstat (limited to 'compiler/oat_writer.cc')
-rw-r--r--compiler/oat_writer.cc21
1 files changed, 21 insertions, 0 deletions
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index 970d2e3..a400bdd 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -378,6 +378,27 @@ size_t OatWriter::InitOatCodeMethod(size_t offset, size_t oat_class_index,
uint32_t thumb_offset = compiled_method->CodeDelta();
quick_code_offset = offset + sizeof(code_size) + thumb_offset;
+ std::vector<uint8_t>* cfi_info = compiler_driver_->GetCallFrameInformation();
+ if (cfi_info != nullptr) {
+ // Copy in the FDE, if present
+ const std::vector<uint8_t>* fde = compiled_method->GetCFIInfo();
+ if (fde != nullptr) {
+ // Copy the information into cfi_info and then fix the address in the new copy.
+ int cur_offset = cfi_info->size();
+ cfi_info->insert(cfi_info->end(), fde->begin(), fde->end());
+
+ // Set the 'initial_location' field to address the start of the method.
+ uint32_t new_value = quick_code_offset - oat_header_->GetExecutableOffset();
+ uint32_t offset_to_update = cur_offset + 2*sizeof(uint32_t);
+ (*cfi_info)[offset_to_update+0] = new_value;
+ (*cfi_info)[offset_to_update+1] = new_value >> 8;
+ (*cfi_info)[offset_to_update+2] = new_value >> 16;
+ (*cfi_info)[offset_to_update+3] = new_value >> 24;
+ method_info_.push_back(DebugInfo(PrettyMethod(class_def_method_index, dex_file, false),
+ new_value, new_value + code_size));
+ }
+ }
+
// Deduplicate code arrays
SafeMap<const std::vector<uint8_t>*, uint32_t>::iterator code_iter =
code_offsets_.find(quick_code);