diff options
| author | 2016-03-11 14:25:40 +0000 | |
|---|---|---|
| committer | 2016-03-11 14:25:41 +0000 | |
| commit | 1a008a127730710f8f56c1ca66385e1b062a2dcb (patch) | |
| tree | b3d33325c5e5ef2f34aa9a497c83863cf2481abb | |
| parent | 2af7213a4e0d395fe22dcdce6ec10a3bd131023d (diff) | |
| parent | 197160d47f34238cb5e7444fa4c2de300db8e2c6 (diff) | |
Merge "Refactor MethodDebugInfo (input of DWARF writer)."
| -rw-r--r-- | compiler/debug/elf_compilation_unit.h | 5 | ||||
| -rw-r--r-- | compiler/debug/elf_debug_frame_writer.h | 14 | ||||
| -rw-r--r-- | compiler/debug/elf_debug_info_writer.h | 24 | ||||
| -rw-r--r-- | compiler/debug/elf_debug_line_writer.h | 24 | ||||
| -rw-r--r-- | compiler/debug/elf_debug_loc_writer.h | 43 | ||||
| -rw-r--r-- | compiler/debug/elf_debug_writer.cc | 7 | ||||
| -rw-r--r-- | compiler/debug/elf_symtab_writer.h | 28 | ||||
| -rw-r--r-- | compiler/debug/method_debug_info.h | 18 | ||||
| -rw-r--r-- | compiler/elf_builder.h | 29 | ||||
| -rw-r--r-- | compiler/oat_writer.cc | 34 | ||||
| -rw-r--r-- | compiler/optimizing/optimizing_compiler.cc | 43 | ||||
| -rw-r--r-- | oatdump/oatdump.cc | 21 |
12 files changed, 142 insertions, 148 deletions
diff --git a/compiler/debug/elf_compilation_unit.h b/compiler/debug/elf_compilation_unit.h index f725f45e15..b1d89ebeb2 100644 --- a/compiler/debug/elf_compilation_unit.h +++ b/compiler/debug/elf_compilation_unit.h @@ -27,8 +27,9 @@ namespace debug { struct ElfCompilationUnit { std::vector<const MethodDebugInfo*> methods; size_t debug_line_offset = 0; - uintptr_t low_pc = std::numeric_limits<uintptr_t>::max(); - uintptr_t high_pc = 0; + bool is_code_address_text_relative; // Is the address offset from start of .text section? + uint64_t code_address = std::numeric_limits<uint64_t>::max(); + uint64_t code_end = 0; }; } // namespace debug diff --git a/compiler/debug/elf_debug_frame_writer.h b/compiler/debug/elf_debug_frame_writer.h index f6d9b169c4..badbd93cb0 100644 --- a/compiler/debug/elf_debug_frame_writer.h +++ b/compiler/debug/elf_debug_frame_writer.h @@ -200,8 +200,8 @@ void WriteCFISection(ElfBuilder<ElfTypes>* builder, sorted_method_infos.begin(), sorted_method_infos.end(), [](const MethodDebugInfo* lhs, const MethodDebugInfo* rhs) { - ArrayRef<const uint8_t> l = lhs->compiled_method->GetCFIInfo(); - ArrayRef<const uint8_t> r = rhs->compiled_method->GetCFIInfo(); + ArrayRef<const uint8_t> l = lhs->cfi; + ArrayRef<const uint8_t> r = rhs->cfi; return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end()); }); @@ -212,9 +212,6 @@ void WriteCFISection(ElfBuilder<ElfTypes>* builder, { cfi_section->Start(); const bool is64bit = Is64BitInstructionSet(builder->GetIsa()); - const Elf_Addr text_address = builder->GetText()->Exists() - ? builder->GetText()->GetAddress() - : 0; const Elf_Addr cfi_address = cfi_section->GetAddress(); const Elf_Addr cie_address = cfi_address; Elf_Addr buffer_address = cfi_address; @@ -225,9 +222,10 @@ void WriteCFISection(ElfBuilder<ElfTypes>* builder, buffer.clear(); for (const MethodDebugInfo* mi : sorted_method_infos) { if (!mi->deduped) { // Only one FDE per unique address. - ArrayRef<const uint8_t> opcodes = mi->compiled_method->GetCFIInfo(); + ArrayRef<const uint8_t> opcodes = mi->cfi; if (!opcodes.empty()) { - const Elf_Addr code_address = text_address + mi->low_pc; + const Elf_Addr code_address = mi->code_address + + (mi->is_code_address_text_relative ? builder->GetText()->GetAddress() : 0); if (format == dwarf::DW_EH_FRAME_FORMAT) { binary_search_table.push_back( dchecked_integral_cast<uint32_t>(code_address)); @@ -235,7 +233,7 @@ void WriteCFISection(ElfBuilder<ElfTypes>* builder, dchecked_integral_cast<uint32_t>(buffer_address)); } WriteFDE(is64bit, cfi_address, cie_address, - code_address, mi->high_pc - mi->low_pc, + code_address, mi->code_size, opcodes, format, buffer_address, &buffer, &patch_locations); cfi_section->WriteFully(buffer.data(), buffer.size()); diff --git a/compiler/debug/elf_debug_info_writer.h b/compiler/debug/elf_debug_info_writer.h index bddb054b80..af74d4c5b5 100644 --- a/compiler/debug/elf_debug_info_writer.h +++ b/compiler/debug/elf_debug_info_writer.h @@ -117,17 +117,17 @@ class ElfCompilationUnitWriter { void Write(const ElfCompilationUnit& compilation_unit) { CHECK(!compilation_unit.methods.empty()); - const Elf_Addr text_address = owner_->builder_->GetText()->Exists() + const Elf_Addr base_address = compilation_unit.is_code_address_text_relative ? owner_->builder_->GetText()->GetAddress() : 0; - const uintptr_t cu_size = compilation_unit.high_pc - compilation_unit.low_pc; + const uint64_t cu_size = compilation_unit.code_end - compilation_unit.code_address; using namespace dwarf; // NOLINT. For easy access to DWARF constants. info_.StartTag(DW_TAG_compile_unit); info_.WriteString(DW_AT_producer, "Android dex2oat"); info_.WriteData1(DW_AT_language, DW_LANG_Java); info_.WriteString(DW_AT_comp_dir, "$JAVA_SRC_ROOT"); - info_.WriteAddr(DW_AT_low_pc, text_address + compilation_unit.low_pc); + info_.WriteAddr(DW_AT_low_pc, base_address + compilation_unit.code_address); info_.WriteUdata(DW_AT_high_pc, dchecked_integral_cast<uint32_t>(cu_size)); info_.WriteSecOffset(DW_AT_stmt_list, compilation_unit.debug_line_offset); @@ -165,8 +165,8 @@ class ElfCompilationUnitWriter { int start_depth = info_.Depth(); info_.StartTag(DW_TAG_subprogram); WriteName(dex->GetMethodName(dex_method)); - info_.WriteAddr(DW_AT_low_pc, text_address + mi->low_pc); - info_.WriteUdata(DW_AT_high_pc, dchecked_integral_cast<uint32_t>(mi->high_pc-mi->low_pc)); + info_.WriteAddr(DW_AT_low_pc, base_address + mi->code_address); + info_.WriteUdata(DW_AT_high_pc, mi->code_size); std::vector<uint8_t> expr_buffer; Expression expr(&expr_buffer); expr.WriteOpCallFrameCfa(); @@ -176,8 +176,8 @@ class ElfCompilationUnitWriter { // Decode dex register locations for all stack maps. // It might be expensive, so do it just once and reuse the result. std::vector<DexRegisterMap> dex_reg_maps; - if (mi->IsFromOptimizingCompiler()) { - const CodeInfo code_info(mi->compiled_method->GetVmapTable().data()); + if (mi->code_info != nullptr) { + const CodeInfo code_info(mi->code_info); StackMapEncoding encoding = code_info.ExtractEncoding(); for (size_t s = 0; s < code_info.GetNumberOfStackMaps(); ++s) { const StackMap& stack_map = code_info.GetStackMapAt(s, encoding); @@ -200,7 +200,7 @@ class ElfCompilationUnitWriter { // Write the stack location of the parameter. const uint32_t vreg = dex_code->registers_size_ - dex_code->ins_size_ + arg_reg; const bool is64bitValue = false; - WriteRegLocation(mi, dex_reg_maps, vreg, is64bitValue, compilation_unit.low_pc); + WriteRegLocation(mi, dex_reg_maps, vreg, is64bitValue, compilation_unit.code_address); } arg_reg++; info_.EndTag(); @@ -219,7 +219,7 @@ class ElfCompilationUnitWriter { if (dex_code != nullptr) { // Write the stack location of the parameter. const uint32_t vreg = dex_code->registers_size_ - dex_code->ins_size_ + arg_reg; - WriteRegLocation(mi, dex_reg_maps, vreg, is64bitValue, compilation_unit.low_pc); + WriteRegLocation(mi, dex_reg_maps, vreg, is64bitValue, compilation_unit.code_address); } arg_reg += is64bitValue ? 2 : 1; info_.EndTag(); @@ -246,7 +246,7 @@ class ElfCompilationUnitWriter { dex_reg_maps, var.reg_, is64bitValue, - compilation_unit.low_pc, + compilation_unit.code_address, var.start_address_, var.end_address_); info_.EndTag(); @@ -445,14 +445,14 @@ class ElfCompilationUnitWriter { const std::vector<DexRegisterMap>& dex_register_maps, uint16_t vreg, bool is64bitValue, - uint32_t compilation_unit_low_pc, + uint64_t compilation_unit_code_address, uint32_t dex_pc_low = 0, uint32_t dex_pc_high = 0xFFFFFFFF) { WriteDebugLocEntry(method_info, dex_register_maps, vreg, is64bitValue, - compilation_unit_low_pc, + compilation_unit_code_address, dex_pc_low, dex_pc_high, owner_->builder_->GetIsa(), diff --git a/compiler/debug/elf_debug_line_writer.h b/compiler/debug/elf_debug_line_writer.h index 11be4e9844..ed26d96603 100644 --- a/compiler/debug/elf_debug_line_writer.h +++ b/compiler/debug/elf_debug_line_writer.h @@ -53,7 +53,7 @@ class ElfDebugLineWriter { // Returns the number of bytes written. size_t WriteCompilationUnit(ElfCompilationUnit& compilation_unit) { const bool is64bit = Is64BitInstructionSet(builder_->GetIsa()); - const Elf_Addr text_address = builder_->GetText()->Exists() + const Elf_Addr base_address = compilation_unit.is_code_address_text_relative ? builder_->GetText()->GetAddress() : 0; @@ -90,37 +90,31 @@ class ElfDebugLineWriter { } uint32_t prologue_end = std::numeric_limits<uint32_t>::max(); - ArrayRef<const SrcMapElem> pc2dex_map; - std::vector<SrcMapElem> pc2dex_map_from_stack_maps; - if (mi->IsFromOptimizingCompiler()) { + std::vector<SrcMapElem> pc2dex_map; + if (mi->code_info != nullptr) { // Use stack maps to create mapping table from pc to dex. - const CodeInfo code_info(mi->compiled_method->GetVmapTable().data()); + const CodeInfo code_info(mi->code_info); const StackMapEncoding encoding = code_info.ExtractEncoding(); + pc2dex_map.reserve(code_info.GetNumberOfStackMaps()); for (uint32_t s = 0; s < code_info.GetNumberOfStackMaps(); s++) { StackMap stack_map = code_info.GetStackMapAt(s, encoding); DCHECK(stack_map.IsValid()); const uint32_t pc = stack_map.GetNativePcOffset(encoding); const int32_t dex = stack_map.GetDexPc(encoding); - pc2dex_map_from_stack_maps.push_back({pc, dex}); + pc2dex_map.push_back({pc, dex}); if (stack_map.HasDexRegisterMap(encoding)) { // Guess that the first map with local variables is the end of prologue. prologue_end = std::min(prologue_end, pc); } } - std::sort(pc2dex_map_from_stack_maps.begin(), - pc2dex_map_from_stack_maps.end()); - pc2dex_map = ArrayRef<const SrcMapElem>(pc2dex_map_from_stack_maps); - } else { - // Use the mapping table provided by the quick compiler. - pc2dex_map = mi->compiled_method->GetSrcMappingTable(); - prologue_end = 0; + std::sort(pc2dex_map.begin(), pc2dex_map.end()); } if (pc2dex_map.empty()) { continue; } - Elf_Addr method_address = text_address + mi->low_pc; + Elf_Addr method_address = base_address + mi->code_address; PositionInfos dex2line_map; const DexFile* dex = mi->dex_file; @@ -226,7 +220,7 @@ class ElfDebugLineWriter { opcodes.AddRow(method_address, 0); } - opcodes.AdvancePC(text_address + mi->high_pc); + opcodes.AdvancePC(method_address + mi->code_size); opcodes.EndSequence(); } std::vector<uint8_t> buffer; diff --git a/compiler/debug/elf_debug_loc_writer.h b/compiler/debug/elf_debug_loc_writer.h index c321b4bc4f..2d4fff4d14 100644 --- a/compiler/debug/elf_debug_loc_writer.h +++ b/compiler/debug/elf_debug_loc_writer.h @@ -74,8 +74,8 @@ static Reg GetDwarfFpReg(InstructionSet isa, int machine_reg) { } struct VariableLocation { - uint32_t low_pc; - uint32_t high_pc; + uint32_t low_pc; // Relative to compilation unit. + uint32_t high_pc; // Relative to compilation unit. DexRegisterLocation reg_lo; // May be None if the location is unknown. DexRegisterLocation reg_hi; // Most significant bits of 64-bit value. }; @@ -90,19 +90,23 @@ std::vector<VariableLocation> GetVariableLocations( const std::vector<DexRegisterMap>& dex_register_maps, uint16_t vreg, bool is64bitValue, + uint64_t compilation_unit_code_address, uint32_t dex_pc_low, uint32_t dex_pc_high) { std::vector<VariableLocation> variable_locations; // Get stack maps sorted by pc (they might not be sorted internally). - const CodeInfo code_info(method_info->compiled_method->GetVmapTable().data()); + const CodeInfo code_info(method_info->code_info); const StackMapEncoding encoding = code_info.ExtractEncoding(); std::map<uint32_t, uint32_t> stack_maps; // low_pc -> stack_map_index. for (uint32_t s = 0; s < code_info.GetNumberOfStackMaps(); s++) { StackMap stack_map = code_info.GetStackMapAt(s, encoding); DCHECK(stack_map.IsValid()); - const uint32_t low_pc = method_info->low_pc + stack_map.GetNativePcOffset(encoding); - DCHECK_LE(low_pc, method_info->high_pc); + const uint32_t pc_offset = stack_map.GetNativePcOffset(encoding); + DCHECK_LE(pc_offset, method_info->code_size); + DCHECK_LE(compilation_unit_code_address, method_info->code_address); + const uint32_t low_pc = dchecked_integral_cast<uint32_t>( + method_info->code_address + pc_offset - compilation_unit_code_address); stack_maps.emplace(low_pc, s); } @@ -113,8 +117,9 @@ std::vector<VariableLocation> GetVariableLocations( const StackMap& stack_map = code_info.GetStackMapAt(stack_map_index, encoding); auto next_it = it; next_it++; - const uint32_t high_pc = next_it != stack_maps.end() ? next_it->first - : method_info->high_pc; + const uint32_t high_pc = next_it != stack_maps.end() + ? next_it->first + : method_info->code_address + method_info->code_size - compilation_unit_code_address; DCHECK_LE(low_pc, high_pc); if (low_pc == high_pc) { continue; // Ignore if the address range is empty. @@ -165,7 +170,7 @@ static void WriteDebugLocEntry(const MethodDebugInfo* method_info, const std::vector<DexRegisterMap>& dex_register_maps, uint16_t vreg, bool is64bitValue, - uint32_t compilation_unit_low_pc, + uint64_t compilation_unit_code_address, uint32_t dex_pc_low, uint32_t dex_pc_high, InstructionSet isa, @@ -173,7 +178,7 @@ static void WriteDebugLocEntry(const MethodDebugInfo* method_info, std::vector<uint8_t>* debug_loc_buffer, std::vector<uint8_t>* debug_ranges_buffer) { using Kind = DexRegisterLocation::Kind; - if (!method_info->IsFromOptimizingCompiler()) { + if (method_info->code_info == nullptr || dex_register_maps.empty()) { return; } @@ -182,6 +187,7 @@ static void WriteDebugLocEntry(const MethodDebugInfo* method_info, dex_register_maps, vreg, is64bitValue, + compilation_unit_code_address, dex_pc_low, dex_pc_high); @@ -202,9 +208,8 @@ static void WriteDebugLocEntry(const MethodDebugInfo* method_info, const Kind kind = reg_loc.GetKind(); const int32_t value = reg_loc.GetValue(); if (kind == Kind::kInStack) { - const size_t frame_size = method_info->compiled_method->GetFrameSizeInBytes(); // The stack offset is relative to SP. Make it relative to CFA. - expr.WriteOpFbreg(value - frame_size); + expr.WriteOpFbreg(value - method_info->frame_size_in_bytes); if (piece == 0 && reg_hi.GetKind() == Kind::kInStack && reg_hi.GetValue() == value + 4) { break; // the high word is correctly implied by the low word. @@ -249,11 +254,11 @@ static void WriteDebugLocEntry(const MethodDebugInfo* method_info, if (expr.size() > 0) { if (is64bit) { - debug_loc.PushUint64(variable_location.low_pc - compilation_unit_low_pc); - debug_loc.PushUint64(variable_location.high_pc - compilation_unit_low_pc); + debug_loc.PushUint64(variable_location.low_pc); + debug_loc.PushUint64(variable_location.high_pc); } else { - debug_loc.PushUint32(variable_location.low_pc - compilation_unit_low_pc); - debug_loc.PushUint32(variable_location.high_pc - compilation_unit_low_pc); + debug_loc.PushUint32(variable_location.low_pc); + debug_loc.PushUint32(variable_location.high_pc); } // Write the expression. debug_loc.PushUint16(expr.size()); @@ -283,11 +288,11 @@ static void WriteDebugLocEntry(const MethodDebugInfo* method_info, high_pc = variable_locations[++i].high_pc; } if (is64bit) { - debug_ranges.PushUint64(low_pc - compilation_unit_low_pc); - debug_ranges.PushUint64(high_pc - compilation_unit_low_pc); + debug_ranges.PushUint64(low_pc); + debug_ranges.PushUint64(high_pc); } else { - debug_ranges.PushUint32(low_pc - compilation_unit_low_pc); - debug_ranges.PushUint32(high_pc - compilation_unit_low_pc); + debug_ranges.PushUint32(low_pc); + debug_ranges.PushUint32(high_pc); } } // Write end-of-list entry. diff --git a/compiler/debug/elf_debug_writer.cc b/compiler/debug/elf_debug_writer.cc index 79069d1aa2..4f2a007492 100644 --- a/compiler/debug/elf_debug_writer.cc +++ b/compiler/debug/elf_debug_writer.cc @@ -62,8 +62,11 @@ static void WriteDebugSections(ElfBuilder<ElfTypes>* builder, } ElfCompilationUnit& cu = compilation_units.back(); cu.methods.push_back(&mi); - cu.low_pc = std::min(cu.low_pc, mi.low_pc); - cu.high_pc = std::max(cu.high_pc, mi.high_pc); + // All methods must have the same addressing mode otherwise the min/max below does not work. + DCHECK_EQ(cu.methods.front()->is_code_address_text_relative, mi.is_code_address_text_relative); + cu.is_code_address_text_relative = mi.is_code_address_text_relative; + cu.code_address = std::min(cu.code_address, mi.code_address); + cu.code_end = std::max(cu.code_end, mi.code_address + mi.code_size); last_source_file = source_file; } diff --git a/compiler/debug/elf_symtab_writer.h b/compiler/debug/elf_symtab_writer.h index 41508f44b4..0a199dac35 100644 --- a/compiler/debug/elf_symtab_writer.h +++ b/compiler/debug/elf_symtab_writer.h @@ -47,12 +47,12 @@ static void WriteDebugSymbols(ElfBuilder<ElfTypes>* builder, return; } - // Find all addresses (low_pc) which contain deduped methods. + // Find all addresses which contain deduped methods. // The first instance of method is not marked deduped_, but the rest is. - std::unordered_set<uint32_t> deduped_addresses; + std::unordered_set<uint64_t> deduped_addresses; for (const MethodDebugInfo& info : method_infos) { if (info.deduped) { - deduped_addresses.insert(info.low_pc); + deduped_addresses.insert(info.code_address); } } @@ -65,33 +65,25 @@ static void WriteDebugSymbols(ElfBuilder<ElfTypes>* builder, continue; // Add symbol only for the first instance. } std::string name = PrettyMethod(info.dex_method_index, *info.dex_file, with_signature); - if (deduped_addresses.find(info.low_pc) != deduped_addresses.end()) { + if (deduped_addresses.find(info.code_address) != deduped_addresses.end()) { name += " [DEDUPED]"; } // If we write method names without signature, we might see the same name multiple times. size_t name_offset = (name == last_name ? last_name_offset : strtab->Write(name)); - const auto* text = builder->GetText()->Exists() ? builder->GetText() : nullptr; - const bool is_relative = (text != nullptr); - uint32_t low_pc = info.low_pc; + const auto* text = info.is_code_address_text_relative ? builder->GetText() : nullptr; + uint64_t address = info.code_address + (text != nullptr ? text->GetAddress() : 0); // Add in code delta, e.g., thumb bit 0 for Thumb2 code. - low_pc += info.compiled_method->CodeDelta(); - symtab->Add(name_offset, - text, - low_pc, - is_relative, - info.high_pc - info.low_pc, - STB_GLOBAL, - STT_FUNC); + address += CompiledMethod::CodeDelta(info.isa); + symtab->Add(name_offset, text, address, info.code_size, STB_GLOBAL, STT_FUNC); // Conforming to aaelf, add $t mapping symbol to indicate start of a sequence of thumb2 // instructions, so that disassembler tools can correctly disassemble. // Note that even if we generate just a single mapping symbol, ARM's Streamline // requires it to match function symbol. Just address 0 does not work. - if (info.compiled_method->GetInstructionSet() == kThumb2) { + if (info.isa == kThumb2) { if (!generated_mapping_symbol || !kGenerateSingleArmMappingSymbol) { - symtab->Add(strtab->Write("$t"), text, info.low_pc & ~1, - is_relative, 0, STB_LOCAL, STT_NOTYPE); + symtab->Add(strtab->Write("$t"), text, address & ~1, 0, STB_LOCAL, STT_NOTYPE); generated_mapping_symbol = true; } } diff --git a/compiler/debug/method_debug_info.h b/compiler/debug/method_debug_info.h index bb09f7e814..1ccc705ff9 100644 --- a/compiler/debug/method_debug_info.h +++ b/compiler/debug/method_debug_info.h @@ -29,18 +29,16 @@ struct MethodDebugInfo { uint32_t dex_method_index; uint32_t access_flags; const DexFile::CodeItem* code_item; + InstructionSet isa; bool deduped; bool is_native_debuggable; - uintptr_t low_pc; - uintptr_t high_pc; - CompiledMethod* compiled_method; - - bool IsFromOptimizingCompiler() const { - return compiled_method->GetQuickCode().size() > 0 && - compiled_method->GetVmapTable().size() > 0 && - compiled_method->GetGcMap().size() == 0 && - code_item != nullptr; - } + bool is_optimized; + bool is_code_address_text_relative; // Is the address offset from start of .text section? + uint64_t code_address; + uint32_t code_size; + uint32_t frame_size_in_bytes; + const uint8_t* code_info; + ArrayRef<const uint8_t> cfi; }; } // namespace debug diff --git a/compiler/elf_builder.h b/compiler/elf_builder.h index 0a474c6599..ef44a6fe1c 100644 --- a/compiler/elf_builder.h +++ b/compiler/elf_builder.h @@ -165,12 +165,6 @@ class ElfBuilder FINAL { } } - // Returns true if the section was written to disk. - // (Used to check whether we have .text when writing JIT debug info) - bool Exists() const { - return finished_; - } - // Get the location of this section in virtual memory. Elf_Addr GetAddress() const { CHECK(started_); @@ -364,16 +358,18 @@ class ElfBuilder FINAL { void Add(Elf_Word name, const Section* section, Elf_Addr addr, - bool is_relative, Elf_Word size, uint8_t binding, - uint8_t type, - uint8_t other = 0) { - DCHECK(section != nullptr || !is_relative); - Elf_Addr abs_addr = addr + (is_relative ? section->GetAddress() : 0); - Elf_Word section_index = - (section != nullptr) ? section->GetSectionIndex() : static_cast<Elf_Word>(SHN_ABS); - Add(name, section_index, abs_addr, size, binding, type, other); + uint8_t type) { + Elf_Word section_index; + if (section != nullptr) { + DCHECK_LE(section->GetAddress(), addr); + DCHECK_LE(addr, section->GetAddress() + section->GetSize()); + section_index = section->GetSectionIndex(); + } else { + section_index = static_cast<Elf_Word>(SHN_ABS); + } + Add(name, section_index, addr, size, binding, type); } void Add(Elf_Word name, @@ -381,13 +377,12 @@ class ElfBuilder FINAL { Elf_Addr addr, Elf_Word size, uint8_t binding, - uint8_t type, - uint8_t other = 0) { + uint8_t type) { Elf_Sym sym = Elf_Sym(); sym.st_name = name; sym.st_value = addr; sym.st_size = size; - sym.st_other = other; + sym.st_other = 0; sym.st_shndx = section_index; sym.st_info = (binding << 4) + (type & 0xf); CachedSection::Add(&sym, sizeof(sym)); diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc index 50f5aba061..2b511fc082 100644 --- a/compiler/oat_writer.cc +++ b/compiler/oat_writer.cc @@ -807,21 +807,27 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor { } const CompilerOptions& compiler_options = writer_->compiler_driver_->GetCompilerOptions(); - if (compiler_options.GenerateAnyDebugInfo()) { + // Exclude quickened dex methods (code_size == 0) since they have no native code. + if (compiler_options.GenerateAnyDebugInfo() && code_size != 0) { + bool has_code_info = method_header->IsOptimized(); // 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; - writer_->method_info_.push_back(debug::MethodDebugInfo { - dex_file_, - class_def_index_, - it.GetMemberIndex(), - it.GetMethodAccessFlags(), - it.GetMethodCodeItem(), - deduped, - compiler_options.GetNativeDebuggable(), - quick_code_start, - quick_code_start + code_size, - compiled_method}); + debug::MethodDebugInfo info; + info.dex_file = dex_file_; + info.class_def_index = class_def_index_; + info.dex_method_index = it.GetMemberIndex(); + info.access_flags = it.GetMethodAccessFlags(); + info.code_item = it.GetMethodCodeItem(); + info.isa = compiled_method->GetInstructionSet(); + info.deduped = deduped; + info.is_native_debuggable = compiler_options.GetNativeDebuggable(); + info.is_optimized = method_header->IsOptimized(); + info.is_code_address_text_relative = true; + info.code_address = code_offset - writer_->oat_header_->GetExecutableOffset(); + info.code_size = code_size; + info.frame_size_in_bytes = compiled_method->GetFrameSizeInBytes(); + info.code_info = has_code_info ? compiled_method->GetVmapTable().data() : nullptr; + info.cfi = compiled_method->GetCFIInfo(); + writer_->method_info_.push_back(info); } if (kIsDebugBuild) { diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 4ecd1e66d8..989c3e410f 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -919,35 +919,26 @@ bool OptimizingCompiler::JitCompile(Thread* self, if (compiler_options.GetGenerateDebugInfo()) { const auto* method_header = reinterpret_cast<const OatQuickMethodHeader*>(code); const uintptr_t code_address = reinterpret_cast<uintptr_t>(method_header->GetCode()); - CompiledMethod compiled_method( - GetCompilerDriver(), - codegen->GetInstructionSet(), - ArrayRef<const uint8_t>(code_allocator.GetMemory()), - codegen->HasEmptyFrame() ? 0 : codegen->GetFrameSize(), - codegen->GetCoreSpillMask(), - codegen->GetFpuSpillMask(), - ArrayRef<const SrcMapElem>(), - ArrayRef<const uint8_t>(), // mapping_table. - ArrayRef<const uint8_t>(stack_map_data, stack_map_size), - ArrayRef<const uint8_t>(), // native_gc_map. - ArrayRef<const uint8_t>(*codegen->GetAssembler()->cfi().data()), - ArrayRef<const LinkerPatch>()); - debug::MethodDebugInfo method_debug_info { - dex_file, - class_def_idx, - method_idx, - access_flags, - code_item, - false, // deduped. - compiler_options.GetNativeDebuggable(), - code_address, - code_address + code_allocator.GetSize(), - &compiled_method - }; + debug::MethodDebugInfo info; + info.dex_file = dex_file; + info.class_def_index = class_def_idx; + info.dex_method_index = method_idx; + info.access_flags = access_flags; + info.code_item = code_item; + info.isa = codegen->GetInstructionSet(); + info.deduped = false; + info.is_native_debuggable = compiler_options.GetNativeDebuggable(); + info.is_optimized = true; + info.is_code_address_text_relative = false; + info.code_address = code_address; + info.code_size = code_allocator.GetSize(); + 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()); ArrayRef<const uint8_t> elf_file = debug::WriteDebugElfFileForMethod( GetCompilerDriver()->GetInstructionSet(), GetCompilerDriver()->GetInstructionSetFeatures(), - method_debug_info); + info); CreateJITCodeEntryForAddress(code_address, std::unique_ptr<const uint8_t[]>(elf_file.data()), elf_file.size()); diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index e4876c66e3..0e17fc2efa 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -180,8 +180,13 @@ class OatSymbolizer FINAL { uint64_t symbol_value = code_offset - oat_file_->GetOatHeader().GetExecutableOffset(); // Specifying 0 as the symbol size means that the symbol lasts until the next symbol or until // the end of the section in case of the last symbol. - builder_->GetSymTab()->Add(name_offset, builder_->GetText(), symbol_value, - /* is_relative */ true, /* size */ 0, STB_GLOBAL, STT_FUNC); + builder_->GetSymTab()->Add( + name_offset, + builder_->GetText(), + builder_->GetText()->GetAddress() + symbol_value, + /* size */ 0, + STB_GLOBAL, + STT_FUNC); } } @@ -333,9 +338,15 @@ class OatSymbolizer FINAL { } int name_offset = builder_->GetStrTab()->Write(pretty_name); - builder_->GetSymTab()->Add(name_offset, builder_->GetText(), - oat_method.GetCodeOffset() - oat_file_->GetOatHeader().GetExecutableOffset(), - true, oat_method.GetQuickCodeSize(), STB_GLOBAL, STT_FUNC); + uint64_t address = oat_method.GetCodeOffset() - + oat_file_->GetOatHeader().GetExecutableOffset() + + builder_->GetText()->GetAddress(); + builder_->GetSymTab()->Add(name_offset, + builder_->GetText(), + address, + oat_method.GetQuickCodeSize(), + STB_GLOBAL, + STT_FUNC); } } |