summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author David Srbecky <dsrbecky@google.com> 2016-03-11 14:25:40 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2016-03-11 14:25:41 +0000
commit1a008a127730710f8f56c1ca66385e1b062a2dcb (patch)
treeb3d33325c5e5ef2f34aa9a497c83863cf2481abb
parent2af7213a4e0d395fe22dcdce6ec10a3bd131023d (diff)
parent197160d47f34238cb5e7444fa4c2de300db8e2c6 (diff)
Merge "Refactor MethodDebugInfo (input of DWARF writer)."
-rw-r--r--compiler/debug/elf_compilation_unit.h5
-rw-r--r--compiler/debug/elf_debug_frame_writer.h14
-rw-r--r--compiler/debug/elf_debug_info_writer.h24
-rw-r--r--compiler/debug/elf_debug_line_writer.h24
-rw-r--r--compiler/debug/elf_debug_loc_writer.h43
-rw-r--r--compiler/debug/elf_debug_writer.cc7
-rw-r--r--compiler/debug/elf_symtab_writer.h28
-rw-r--r--compiler/debug/method_debug_info.h18
-rw-r--r--compiler/elf_builder.h29
-rw-r--r--compiler/oat_writer.cc34
-rw-r--r--compiler/optimizing/optimizing_compiler.cc43
-rw-r--r--oatdump/oatdump.cc21
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);
}
}