diff options
author | Andreas Gampe <agampe@google.com> | 2014-08-05 20:21:05 -0700 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2014-08-06 14:18:59 -0700 |
commit | 79273802f2b788bcd3eb76edf4df1bcaa57f886f (patch) | |
tree | 44dd09d962cc7a38eb6312296e45e98ae9c469f2 /compiler | |
parent | 1b192268f167f603fc372f02f9067f3ce5d82daf (diff) | |
download | art-79273802f2b788bcd3eb76edf4df1bcaa57f886f.zip art-79273802f2b788bcd3eb76edf4df1bcaa57f886f.tar.gz art-79273802f2b788bcd3eb76edf4df1bcaa57f886f.tar.bz2 |
ART: Rework CFA frame initialization and writing code
Move eh_frame initialization code and CFI writing code to
elf_writer_quick to remove hard-wired dependencies on specific
Quick-compiler backends.
Change-Id: I27ee8ce7245da33a20c90e0086b8d4fd0a2baf4d
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/compilers.cc | 14 | ||||
-rw-r--r-- | compiler/compilers.h | 11 | ||||
-rw-r--r-- | compiler/dex/quick/x86/codegen_x86.h | 6 | ||||
-rwxr-xr-x | compiler/dex/quick/x86/target_x86.cc | 83 | ||||
-rw-r--r-- | compiler/driver/compiler_driver.cc | 6 | ||||
-rw-r--r-- | compiler/driver/compiler_driver.h | 15 | ||||
-rw-r--r-- | compiler/elf_writer_quick.cc | 222 | ||||
-rw-r--r-- | compiler/elf_writer_quick.h | 6 | ||||
-rw-r--r-- | compiler/oat_writer.cc | 48 | ||||
-rw-r--r-- | compiler/oat_writer.h | 14 |
10 files changed, 203 insertions, 222 deletions
diff --git a/compiler/compilers.cc b/compiler/compilers.cc index 250924a..5cf846f 100644 --- a/compiler/compilers.cc +++ b/compiler/compilers.cc @@ -38,9 +38,6 @@ extern "C" art::CompiledMethod* ArtQuickJniCompileMethod(art::CompilerDriver* dr uint32_t access_flags, uint32_t method_idx, const art::DexFile& dex_file); -// Hack for CFI CIE initialization -extern std::vector<uint8_t>* X86CFIInitialization(bool is_x86_64); - void QuickCompiler::Init() const { ArtInitQuickCompilerContext(GetCompilerDriver()); } @@ -126,17 +123,6 @@ Backend* QuickCompiler::GetCodeGenerator(CompilationUnit* cu, void* compilation_ return mir_to_lir; } -std::vector<uint8_t>* QuickCompiler::GetCallFrameInformationInitialization( - const CompilerDriver& driver) const { - if (driver.GetInstructionSet() == kX86) { - return X86CFIInitialization(false); - } - if (driver.GetInstructionSet() == kX86_64) { - return X86CFIInitialization(true); - } - return nullptr; -} - CompiledMethod* OptimizingCompiler::Compile(const DexFile::CodeItem* code_item, uint32_t access_flags, InvokeType invoke_type, diff --git a/compiler/compilers.h b/compiler/compilers.h index 2c231e1..151bf6f 100644 --- a/compiler/compilers.h +++ b/compiler/compilers.h @@ -56,17 +56,6 @@ class QuickCompiler : public Compiler { void InitCompilationUnit(CompilationUnit& cu) const OVERRIDE {} - /* - * @brief Generate and return Dwarf CFI initialization, if supported by the - * backend. - * @param driver CompilerDriver for this compile. - * @returns nullptr if not supported by backend or a vector of bytes for CFI DWARF - * information. - * @note This is used for backtrace information in generated code. - */ - std::vector<uint8_t>* GetCallFrameInformationInitialization(const CompilerDriver& driver) const - OVERRIDE; - private: DISALLOW_COPY_AND_ASSIGN(QuickCompiler); }; diff --git a/compiler/dex/quick/x86/codegen_x86.h b/compiler/dex/quick/x86/codegen_x86.h index d74caae..1d8deae 100644 --- a/compiler/dex/quick/x86/codegen_x86.h +++ b/compiler/dex/quick/x86/codegen_x86.h @@ -355,12 +355,6 @@ class X86Mir2Lir : public Mir2Lir { void InstallLiteralPools() OVERRIDE; /* - * @brief Generate the debug_frame CFI information. - * @returns pointer to vector containing CFE information - */ - static std::vector<uint8_t>* ReturnCommonCallFrameInformation(bool is_x86_64); - - /* * @brief Generate the debug_frame FDE information. * @returns pointer to vector containing CFE information */ diff --git a/compiler/dex/quick/x86/target_x86.cc b/compiler/dex/quick/x86/target_x86.cc index bd2e0f3..62a75a5 100755 --- a/compiler/dex/quick/x86/target_x86.cc +++ b/compiler/dex/quick/x86/target_x86.cc @@ -1437,11 +1437,6 @@ static void AdvanceLoc(std::vector<uint8_t>&buf, uint32_t increment) { } } - -std::vector<uint8_t>* X86CFIInitialization(bool is_x86_64) { - return X86Mir2Lir::ReturnCommonCallFrameInformation(is_x86_64); -} - static void EncodeUnsignedLeb128(std::vector<uint8_t>& buf, uint32_t value) { uint8_t buffer[12]; uint8_t *ptr = EncodeUnsignedLeb128(buffer, value); @@ -1458,84 +1453,6 @@ static void EncodeSignedLeb128(std::vector<uint8_t>& buf, int32_t value) { } } -std::vector<uint8_t>* X86Mir2Lir::ReturnCommonCallFrameInformation(bool is_x86_64) { - std::vector<uint8_t>*cfi_info = new std::vector<uint8_t>; - - // Length (will be filled in later in this routine). - PushWord(*cfi_info, 0); - - // CIE id: always 0. - PushWord(*cfi_info, 0); - - // Version: always 1. - cfi_info->push_back(0x01); - - // Augmentation: 'zR\0' - cfi_info->push_back(0x7a); - cfi_info->push_back(0x52); - cfi_info->push_back(0x0); - - // Code alignment: 1. - EncodeUnsignedLeb128(*cfi_info, 1); - - // Data alignment. - if (is_x86_64) { - EncodeSignedLeb128(*cfi_info, -8); - } else { - EncodeSignedLeb128(*cfi_info, -4); - } - - // Return address register. - if (is_x86_64) { - // R16(RIP) - cfi_info->push_back(0x10); - } else { - // R8(EIP) - cfi_info->push_back(0x08); - } - - // Augmentation length: 1. - cfi_info->push_back(1); - - // Augmentation data: 0x03 ((DW_EH_PE_absptr << 4) | DW_EH_PE_udata4). - cfi_info->push_back(0x03); - - // Initial instructions. - if (is_x86_64) { - // DW_CFA_def_cfa R7(RSP) 8. - cfi_info->push_back(0x0c); - cfi_info->push_back(0x07); - cfi_info->push_back(0x08); - - // DW_CFA_offset R16(RIP) 1 (* -8). - cfi_info->push_back(0x90); - cfi_info->push_back(0x01); - } else { - // DW_CFA_def_cfa R4(ESP) 4. - cfi_info->push_back(0x0c); - cfi_info->push_back(0x04); - cfi_info->push_back(0x04); - - // DW_CFA_offset R8(EIP) 1 (* -4). - cfi_info->push_back(0x88); - cfi_info->push_back(0x01); - } - - // Padding to a multiple of 4 - while ((cfi_info->size() & 3) != 0) { - // DW_CFA_nop is encoded as 0. - cfi_info->push_back(0); - } - - // Set the length of the CIE inside the generated bytes. - uint32_t length = cfi_info->size() - 4; - (*cfi_info)[0] = length; - (*cfi_info)[1] = length >> 8; - (*cfi_info)[2] = length >> 16; - (*cfi_info)[3] = length >> 24; - return cfi_info; -} - static bool ARTRegIDToDWARFRegID(bool is_x86_64, int art_reg_id, int* dwarf_reg_id) { if (is_x86_64) { switch (art_reg_id) { diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index ed126ad..83a5f71 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -353,7 +353,6 @@ CompilerDriver::CompilerDriver(const CompilerOptions* compiler_options, 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"), @@ -376,11 +375,6 @@ CompilerDriver::CompilerDriver(const CompilerOptions* compiler_options, CHECK(image_classes_.get() == nullptr); } - // Are we generating CFI information? - if (compiler_options->GetGenerateGDBInformation()) { - cfi_info_.reset(compiler_->GetCallFrameInformationInitialization(*this)); - } - // Read the profile file if one is provided. if (!profile_file.empty()) { profile_present_ = profile_file_.LoadFile(profile_file); diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index 6dae398..c538a95 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -402,10 +402,6 @@ class CompilerDriver { return dump_passes_; } - bool DidIncludeDebugSymbols() const { - return compiler_options_->GetIncludeDebugSymbols(); - } - CumulativeLogger* GetTimingsLogger() const { return timings_logger_; } @@ -599,14 +595,6 @@ class CompilerDriver { 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(); - } - ProfileFile profile_file_; bool profile_present_; @@ -766,9 +754,6 @@ class CompilerDriver { bool support_boot_image_fixup_; - // Call Frame Information, which might be generated to help stack tracebacks. - std::unique_ptr<std::vector<uint8_t>> cfi_info_; - // DeDuplication data structures, these own the corresponding byte arrays. class DedupeHashFunc { public: diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc index 1fde12e..71f02d3 100644 --- a/compiler/elf_writer_quick.cc +++ b/compiler/elf_writer_quick.cc @@ -24,6 +24,7 @@ #include "elf_utils.h" #include "file_output_stream.h" #include "globals.h" +#include "leb128.h" #include "oat.h" #include "oat_writer.h" #include "utils.h" @@ -38,6 +39,25 @@ static uint8_t MakeStInfo(uint8_t binding, uint8_t type) { return ((binding) << 4) + ((type) & 0xf); } +static void UpdateWord(std::vector<uint8_t>* buf, int offset, int data) { + (*buf)[offset+0] = data; + (*buf)[offset+1] = data >> 8; + (*buf)[offset+2] = data >> 16; + (*buf)[offset+3] = data >> 24; +} + +static void PushWord(std::vector<uint8_t>* buf, int data) { + buf->push_back(data & 0xff); + buf->push_back((data >> 8) & 0xff); + buf->push_back((data >> 16) & 0xff); + buf->push_back((data >> 24) & 0xff); +} + +static void PushHalf(std::vector<uint8_t>* buf, int data) { + buf->push_back(data & 0xff); + buf->push_back((data >> 8) & 0xff); +} + bool ElfWriterQuick::ElfBuilder::Write() { // The basic layout of the elf file. Order may be different in final output. // +-------------------------+ @@ -822,37 +842,131 @@ void ElfWriterQuick::ReservePatchSpace(std::vector<uint8_t>* buffer, bool debug) } } +static void EncodeUnsignedLeb128(uint32_t data, std::vector<uint8_t>* dst) { + size_t encoded_size = UnsignedLeb128Size(data); + size_t cur_index = dst->size(); + dst->resize(dst->size() + encoded_size); + uint8_t* write_pos = &((*dst)[cur_index]); + uint8_t* write_pos_after = EncodeUnsignedLeb128(write_pos, data); + DCHECK_EQ(static_cast<size_t>(write_pos_after - write_pos), encoded_size); +} + +static void EncodeSignedLeb128(int32_t data, std::vector<uint8_t>* dst) { + size_t encoded_size = SignedLeb128Size(data); + size_t cur_index = dst->size(); + dst->resize(dst->size() + encoded_size); + uint8_t* write_pos = &((*dst)[cur_index]); + uint8_t* write_pos_after = EncodeSignedLeb128(write_pos, data); + DCHECK_EQ(static_cast<size_t>(write_pos_after - write_pos), encoded_size); +} + +std::vector<uint8_t>* ConstructCIEFrameX86(bool is_x86_64) { + std::vector<uint8_t>*cfi_info = new std::vector<uint8_t>; + + // Length (will be filled in later in this routine). + PushWord(cfi_info, 0); + + // CIE id: always 0. + PushWord(cfi_info, 0); + + // Version: always 1. + cfi_info->push_back(0x01); + + // Augmentation: 'zR\0' + cfi_info->push_back(0x7a); + cfi_info->push_back(0x52); + cfi_info->push_back(0x0); + + // Code alignment: 1. + EncodeUnsignedLeb128(1, cfi_info); + + // Data alignment. + if (is_x86_64) { + EncodeSignedLeb128(-8, cfi_info); + } else { + EncodeSignedLeb128(-4, cfi_info); + } + + // Return address register. + if (is_x86_64) { + // R16(RIP) + cfi_info->push_back(0x10); + } else { + // R8(EIP) + cfi_info->push_back(0x08); + } + + // Augmentation length: 1. + cfi_info->push_back(1); + + // Augmentation data: 0x03 ((DW_EH_PE_absptr << 4) | DW_EH_PE_udata4). + cfi_info->push_back(0x03); + + // Initial instructions. + if (is_x86_64) { + // DW_CFA_def_cfa R7(RSP) 8. + cfi_info->push_back(0x0c); + cfi_info->push_back(0x07); + cfi_info->push_back(0x08); + + // DW_CFA_offset R16(RIP) 1 (* -8). + cfi_info->push_back(0x90); + cfi_info->push_back(0x01); + } else { + // DW_CFA_def_cfa R4(ESP) 4. + cfi_info->push_back(0x0c); + cfi_info->push_back(0x04); + cfi_info->push_back(0x04); + + // DW_CFA_offset R8(EIP) 1 (* -4). + cfi_info->push_back(0x88); + cfi_info->push_back(0x01); + } + + // Padding to a multiple of 4 + while ((cfi_info->size() & 3) != 0) { + // DW_CFA_nop is encoded as 0. + cfi_info->push_back(0); + } + + // Set the length of the CIE inside the generated bytes. + uint32_t length = cfi_info->size() - 4; + (*cfi_info)[0] = length; + (*cfi_info)[1] = length >> 8; + (*cfi_info)[2] = length >> 16; + (*cfi_info)[3] = length >> 24; + return cfi_info; +} + +std::vector<uint8_t>* ConstructCIEFrame(InstructionSet isa) { + switch (isa) { + case kX86: + return ConstructCIEFrameX86(false); + case kX86_64: + return ConstructCIEFrameX86(true); + + default: + // Not implemented. + return nullptr; + } +} + bool ElfWriterQuick::Write(OatWriter* oat_writer, const std::vector<const DexFile*>& dex_files_unused, const std::string& android_root_unused, bool is_host_unused) { - const bool debug = false; - const bool add_symbols = oat_writer->DidAddSymbols(); + constexpr bool debug = false; const OatHeader& oat_header = oat_writer->GetOatHeader(); Elf32_Word oat_data_size = oat_header.GetExecutableOffset(); uint32_t oat_exec_size = oat_writer->GetSize() - oat_data_size; ElfBuilder builder(oat_writer, elf_file_, compiler_driver_->GetInstructionSet(), 0, - oat_data_size, oat_data_size, oat_exec_size, add_symbols, debug); + oat_data_size, oat_data_size, oat_exec_size, + compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols(), + debug); - if (add_symbols) { - AddDebugSymbols(builder, oat_writer, debug); - } - - bool generateDebugInformation = compiler_driver_->GetCallFrameInformation() != nullptr; - if (generateDebugInformation) { - ElfRawSectionBuilder debug_info(".debug_info", SHT_PROGBITS, 0, nullptr, 0, 1, 0); - ElfRawSectionBuilder debug_abbrev(".debug_abbrev", SHT_PROGBITS, 0, nullptr, 0, 1, 0); - ElfRawSectionBuilder debug_str(".debug_str", SHT_PROGBITS, 0, nullptr, 0, 1, 0); - ElfRawSectionBuilder eh_frame(".eh_frame", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, 4, 0); - eh_frame.SetBuffer(*compiler_driver_->GetCallFrameInformation()); - - FillInCFIInformation(oat_writer, debug_info.GetBuffer(), - debug_abbrev.GetBuffer(), debug_str.GetBuffer()); - builder.RegisterRawSection(debug_info); - builder.RegisterRawSection(debug_abbrev); - builder.RegisterRawSection(eh_frame); - builder.RegisterRawSection(debug_str); + if (compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) { + WriteDebugSymbols(builder, oat_writer); } if (compiler_driver_->GetCompilerOptions().GetIncludePatchInformation()) { @@ -865,32 +979,62 @@ bool ElfWriterQuick::Write(OatWriter* oat_writer, return builder.Write(); } -void ElfWriterQuick::AddDebugSymbols(ElfBuilder& builder, OatWriter* oat_writer, bool debug) { +void ElfWriterQuick::WriteDebugSymbols(ElfBuilder& builder, OatWriter* oat_writer) { + std::unique_ptr<std::vector<uint8_t>> cfi_info( + ConstructCIEFrame(compiler_driver_->GetInstructionSet())); + + // Iterate over the compiled methods. const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo(); ElfSymtabBuilder* symtab = &builder.symtab_builder_; for (auto it = method_info.begin(); it != method_info.end(); ++it) { symtab->AddSymbol(it->method_name_, &builder.text_builder_, it->low_pc_, true, it->high_pc_ - it->low_pc_, STB_GLOBAL, STT_FUNC); - } -} -static void UpdateWord(std::vector<uint8_t>*buf, int offset, int data) { - (*buf)[offset+0] = data; - (*buf)[offset+1] = data >> 8; - (*buf)[offset+2] = data >> 16; - (*buf)[offset+3] = data >> 24; -} + // Include CFI for compiled method, if possible. + if (cfi_info.get() != nullptr) { + DCHECK(it->compiled_method_ != nullptr); + + // Copy in the FDE, if present + const std::vector<uint8_t>* fde = it->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 'CIE_pointer' field to cur_offset+4. + uint32_t CIE_pointer = cur_offset + 4; + uint32_t offset_to_update = cur_offset + sizeof(uint32_t); + (*cfi_info)[offset_to_update+0] = CIE_pointer; + (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8; + (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16; + (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24; + + // Set the 'initial_location' field to address the start of the method. + offset_to_update = cur_offset + 2*sizeof(uint32_t); + const uint32_t quick_code_start = it->low_pc_; + (*cfi_info)[offset_to_update+0] = quick_code_start; + (*cfi_info)[offset_to_update+1] = quick_code_start >> 8; + (*cfi_info)[offset_to_update+2] = quick_code_start >> 16; + (*cfi_info)[offset_to_update+3] = quick_code_start >> 24; + } + } + } -static void PushWord(std::vector<uint8_t>*buf, int data) { - buf->push_back(data & 0xff); - buf->push_back((data >> 8) & 0xff); - buf->push_back((data >> 16) & 0xff); - buf->push_back((data >> 24) & 0xff); -} + if (cfi_info.get() != nullptr) { + // Now lay down the Elf sections. + ElfRawSectionBuilder debug_info(".debug_info", SHT_PROGBITS, 0, nullptr, 0, 1, 0); + ElfRawSectionBuilder debug_abbrev(".debug_abbrev", SHT_PROGBITS, 0, nullptr, 0, 1, 0); + ElfRawSectionBuilder debug_str(".debug_str", SHT_PROGBITS, 0, nullptr, 0, 1, 0); + ElfRawSectionBuilder eh_frame(".eh_frame", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, 4, 0); + eh_frame.SetBuffer(std::move(*cfi_info.get())); -static void PushHalf(std::vector<uint8_t>*buf, int data) { - buf->push_back(data & 0xff); - buf->push_back((data >> 8) & 0xff); + FillInCFIInformation(oat_writer, debug_info.GetBuffer(), debug_abbrev.GetBuffer(), + debug_str.GetBuffer()); + builder.RegisterRawSection(debug_info); + builder.RegisterRawSection(debug_abbrev); + builder.RegisterRawSection(eh_frame); + builder.RegisterRawSection(debug_str); + } } void ElfWriterQuick::FillInCFIInformation(OatWriter* oat_writer, diff --git a/compiler/elf_writer_quick.h b/compiler/elf_writer_quick.h index a0d36df..8cfe550 100644 --- a/compiler/elf_writer_quick.h +++ b/compiler/elf_writer_quick.h @@ -48,9 +48,7 @@ class ElfWriterQuick FINAL : public ElfWriter { ~ElfWriterQuick() {} class ElfBuilder; - void AddDebugSymbols(ElfBuilder& builder, - OatWriter* oat_writer, - bool debug); + void WriteDebugSymbols(ElfBuilder& builder, OatWriter* oat_writer); void ReservePatchSpace(std::vector<uint8_t>* buffer, bool debug); class ElfSectionBuilder { @@ -126,7 +124,7 @@ class ElfWriterQuick FINAL : public ElfWriter { : ElfSectionBuilder(sec_name, type, flags, link, info, align, entsize) {} ~ElfRawSectionBuilder() {} std::vector<uint8_t>* GetBuffer() { return &buf_; } - void SetBuffer(std::vector<uint8_t> buf) { buf_ = buf; } + void SetBuffer(std::vector<uint8_t>&& buf) { buf_ = buf; } protected: std::vector<uint8_t> buf_; diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc index 9da59ab..1ba5d32 100644 --- a/compiler/oat_writer.cc +++ b/compiler/oat_writer.cc @@ -357,7 +357,6 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor { uint32_t thumb_offset = compiled_method->CodeDelta(); quick_code_offset = offset_ + sizeof(OatQuickMethodHeader) + thumb_offset; - bool force_debug_capture = false; bool deduped = false; // Deduplicate code arrays. @@ -400,47 +399,22 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor { offset_ += code_size; } - uint32_t quick_code_start = quick_code_offset - writer_->oat_header_->GetExecutableOffset(); - std::vector<uint8_t>* cfi_info = writer_->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 'CIE_pointer' field to cur_offset+4. - uint32_t CIE_pointer = cur_offset + 4; - uint32_t offset_to_update = cur_offset + sizeof(uint32_t); - (*cfi_info)[offset_to_update+0] = CIE_pointer; - (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8; - (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16; - (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24; - - // Set the 'initial_location' field to address the start of the method. - offset_to_update = cur_offset + 2*sizeof(uint32_t); - (*cfi_info)[offset_to_update+0] = quick_code_start; - (*cfi_info)[offset_to_update+1] = quick_code_start >> 8; - (*cfi_info)[offset_to_update+2] = quick_code_start >> 16; - (*cfi_info)[offset_to_update+3] = quick_code_start >> 24; - force_debug_capture = true; - } - } + if (writer_->compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) { + // Record debug information for this function if we are doing that. - - if (writer_->compiler_driver_->DidIncludeDebugSymbols() || force_debug_capture) { - // Record debug information for this function if we are doing that or - // we have CFI and so need it. std::string name = PrettyMethod(it.GetMemberIndex(), *dex_file_, true); if (deduped) { - // TODO We should place the DEDUPED tag on the first instance of a - // deduplicated symbol so that it will show up in a debuggerd crash - // report. + // TODO We should place the DEDUPED tag on the first instance of a deduplicated symbol + // so that it will show up in a debuggerd crash report. name += " [ DEDUPED ]"; } - writer_->method_info_.push_back(DebugInfo(name, quick_code_start, - quick_code_start + code_size)); + + const uint32_t quick_code_start = quick_code_offset - + writer_->oat_header_->GetExecutableOffset(); + writer_->method_info_.push_back(DebugInfo(name, + quick_code_start, + quick_code_start + code_size, + compiled_method)); } } diff --git a/compiler/oat_writer.h b/compiler/oat_writer.h index 945048e..ef5fd6b 100644 --- a/compiler/oat_writer.h +++ b/compiler/oat_writer.h @@ -30,6 +30,7 @@ namespace art { class BitVector; +class CompiledMethod; class OutputStream; // OatHeader variable length with count of D OatDexFiles @@ -97,22 +98,21 @@ class OatWriter { ~OatWriter(); struct DebugInfo { - DebugInfo(const std::string& method_name, uint32_t low_pc, uint32_t high_pc) - : method_name_(method_name), low_pc_(low_pc), high_pc_(high_pc) { + DebugInfo(const std::string& method_name, uint32_t low_pc, uint32_t high_pc, + CompiledMethod* compiled_method) + : method_name_(method_name), low_pc_(low_pc), high_pc_(high_pc), + compiled_method_(compiled_method) { } - std::string method_name_; + std::string method_name_; // Note: this name is a pretty-printed name. uint32_t low_pc_; uint32_t high_pc_; + CompiledMethod* compiled_method_; }; const std::vector<DebugInfo>& GetCFIMethodInfo() const { return method_info_; } - bool DidAddSymbols() const { - return compiler_driver_->DidIncludeDebugSymbols(); - } - private: // The DataAccess classes are helper classes that provide access to members related to // a given map, i.e. GC map, mapping table or vmap table. By abstracting these away |