summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Srbecky <dsrbecky@google.com>2015-03-30 14:21:42 +0100
committerDavid Srbecky <dsrbecky@google.com>2015-04-01 12:57:10 +0100
commit6f7158927fee233255f8e96719c374694b10cad3 (patch)
tree518cef41f4cd9c3119879eb463aa4b67af5f6ff8
parentef3456f872539df65c4c88ca346713f74366d803 (diff)
downloadandroid_art-6f7158927fee233255f8e96719c374694b10cad3.tar.gz
android_art-6f7158927fee233255f8e96719c374694b10cad3.tar.bz2
android_art-6f7158927fee233255f8e96719c374694b10cad3.zip
Write .debug_line section using the new DWARF library.
Also simplify dex to java mapping and handle mapping in prologues and epilogues. Change-Id: I410f06024580f2a8788f2c93fe9bca132805029a
-rw-r--r--compiler/compiled_method.cc3
-rw-r--r--compiler/compiled_method.h88
-rw-r--r--compiler/dex/compiler_enums.h18
-rw-r--r--compiler/dex/quick/arm/assemble_arm.cc2
-rw-r--r--compiler/dex/quick/arm/call_arm.cc2
-rw-r--r--compiler/dex/quick/arm64/assemble_arm64.cc2
-rw-r--r--compiler/dex/quick/arm64/call_arm64.cc5
-rw-r--r--compiler/dex/quick/codegen_util.cc33
-rw-r--r--compiler/dex/quick/mips/call_mips.cc2
-rw-r--r--compiler/dex/quick/mir_to_lir.cc4
-rw-r--r--compiler/dex/quick/x86/call_x86.cc2
-rw-r--r--compiler/elf_writer_quick.cc413
-rw-r--r--compiler/oat_writer.cc8
-rw-r--r--compiler/oat_writer.h16
-rw-r--r--runtime/dwarf.h2
-rw-r--r--runtime/elf_file.cc65
16 files changed, 304 insertions, 361 deletions
diff --git a/compiler/compiled_method.cc b/compiler/compiled_method.cc
index 1849e7ef64..03370db6c0 100644
--- a/compiler/compiled_method.cc
+++ b/compiler/compiled_method.cc
@@ -142,7 +142,6 @@ CompiledMethod::CompiledMethod(CompilerDriver* driver,
if (src_mapping_table == nullptr) {
src_mapping_table_ = new SwapSrcMap(driver->GetSwapSpaceAllocator());
} else {
- src_mapping_table->Arrange();
src_mapping_table_ = new SwapSrcMap(src_mapping_table->begin(), src_mapping_table->end(),
driver->GetSwapSpaceAllocator());
}
@@ -159,7 +158,7 @@ CompiledMethod::CompiledMethod(CompilerDriver* driver,
} else {
src_mapping_table_ = src_mapping_table == nullptr ?
driver->DeduplicateSrcMappingTable(ArrayRef<SrcMapElem>()) :
- driver->DeduplicateSrcMappingTable(ArrayRef<SrcMapElem>(src_mapping_table->Arrange()));
+ driver->DeduplicateSrcMappingTable(ArrayRef<SrcMapElem>(*src_mapping_table));
mapping_table_ = mapping_table.empty() ?
nullptr : driver->DeduplicateMappingTable(mapping_table);
vmap_table_ = driver->DeduplicateVMapTable(vmap_table);
diff --git a/compiler/compiled_method.h b/compiler/compiled_method.h
index 23869140ae..7497b175fc 100644
--- a/compiler/compiled_method.h
+++ b/compiler/compiled_method.h
@@ -94,20 +94,12 @@ class SrcMapElem {
uint32_t from_;
int32_t to_;
- explicit operator int64_t() const {
- return (static_cast<int64_t>(to_) << 32) | from_;
- }
-
- bool operator<(const SrcMapElem& sme) const {
- return int64_t(*this) < int64_t(sme);
- }
-
- bool operator==(const SrcMapElem& sme) const {
- return int64_t(*this) == int64_t(sme);
- }
-
- explicit operator uint8_t() const {
- return static_cast<uint8_t>(from_ + to_);
+ // Lexicographical compare.
+ bool operator<(const SrcMapElem& other) const {
+ if (from_ != other.from_) {
+ return from_ < other.from_;
+ }
+ return to_ < other.to_;
}
};
@@ -129,49 +121,33 @@ class SrcMap FINAL : public std::vector<SrcMapElem, Allocator> {
SrcMap(InputIt first, InputIt last, const Allocator& alloc)
: std::vector<SrcMapElem, Allocator>(first, last, alloc) {}
- void SortByFrom() {
- std::sort(begin(), end(), [] (const SrcMapElem& lhs, const SrcMapElem& rhs) -> bool {
- return lhs.from_ < rhs.from_;
- });
- }
-
- const_iterator FindByTo(int32_t to) const {
- return std::lower_bound(begin(), end(), SrcMapElem({0, to}));
- }
-
- SrcMap& Arrange() {
- if (!empty()) {
- std::sort(begin(), end());
- resize(std::unique(begin(), end()) - begin());
- shrink_to_fit();
- }
- return *this;
- }
-
- void DeltaFormat(const SrcMapElem& start, uint32_t highest_pc) {
- // Convert from abs values to deltas.
+ void push_back(const SrcMapElem& elem) {
if (!empty()) {
- SortByFrom();
-
- // TODO: one PC can be mapped to several Java src lines.
- // do we want such a one-to-many correspondence?
-
- // get rid of the highest values
- size_t i = size() - 1;
- for (; i > 0 ; i--) {
- if ((*this)[i].from_ < highest_pc) {
- break;
- }
+ // Check that the addresses are inserted in sorted order.
+ DCHECK_GE(elem.from_, this->back().from_);
+ // If two consequitive entries map to the same value, ignore the later.
+ // E.g. for map {{0, 1}, {4, 1}, {8, 2}}, all values in [0,8) map to 1.
+ if (elem.to_ == this->back().to_) {
+ return;
}
- this->resize(i + 1);
-
- for (i = size(); --i >= 1; ) {
- (*this)[i].from_ -= (*this)[i-1].from_;
- (*this)[i].to_ -= (*this)[i-1].to_;
- }
- DCHECK((*this)[0].from_ >= start.from_);
- (*this)[0].from_ -= start.from_;
- (*this)[0].to_ -= start.to_;
+ }
+ std::vector<SrcMapElem, Allocator>::push_back(elem);
+ }
+
+ // Returns true and the corresponding "to" value if the mapping is found.
+ // Oterwise returns false and 0.
+ std::pair<bool, int32_t> Find(uint32_t from) const {
+ // Finds first mapping such that lb.from_ >= from.
+ auto lb = std::lower_bound(begin(), end(), SrcMapElem {from, INT32_MIN});
+ if (lb != end() && lb->from_ == from) {
+ // Found exact match.
+ return std::make_pair(true, lb->to_);
+ } else if (lb != begin()) {
+ // The previous mapping is still in effect.
+ return std::make_pair(true, (--lb)->to_);
+ } else {
+ // Not found because 'from' is smaller than first entry in the map.
+ return std::make_pair(false, 0);
}
}
};
@@ -428,7 +404,7 @@ class CompiledMethod FINAL : public CompiledCode {
const uint32_t core_spill_mask_;
// For quick code, a bit mask describing spilled FPR callee-save registers.
const uint32_t fp_spill_mask_;
- // For quick code, a set of pairs (PC, Line) mapping from native PC offset to Java line
+ // For quick code, a set of pairs (PC, DEX) mapping from native PC offset to DEX offset.
SwapSrcMap* src_mapping_table_;
// For quick code, a uleb128 encoded map from native PC offset to dex PC aswell as dex PC to
// native PC offset. Size prefixed.
diff --git a/compiler/dex/compiler_enums.h b/compiler/dex/compiler_enums.h
index 39725dee38..0acdd422df 100644
--- a/compiler/dex/compiler_enums.h
+++ b/compiler/dex/compiler_enums.h
@@ -99,14 +99,16 @@ std::ostream& operator<<(std::ostream& os, const BBType& code);
// Shared pseudo opcodes - must be < 0.
enum LIRPseudoOpcode {
- kPseudoExportedPC = -16,
- kPseudoSafepointPC = -15,
- kPseudoIntrinsicRetry = -14,
- kPseudoSuspendTarget = -13,
- kPseudoThrowTarget = -12,
- kPseudoCaseLabel = -11,
- kPseudoMethodEntry = -10,
- kPseudoMethodExit = -9,
+ kPseudoPrologueBegin = -18,
+ kPseudoPrologueEnd = -17,
+ kPseudoEpilogueBegin = -16,
+ kPseudoEpilogueEnd = -15,
+ kPseudoExportedPC = -14,
+ kPseudoSafepointPC = -13,
+ kPseudoIntrinsicRetry = -12,
+ kPseudoSuspendTarget = -11,
+ kPseudoThrowTarget = -10,
+ kPseudoCaseLabel = -9,
kPseudoBarrier = -8,
kPseudoEntryBlock = -7,
kPseudoExitBlock = -6,
diff --git a/compiler/dex/quick/arm/assemble_arm.cc b/compiler/dex/quick/arm/assemble_arm.cc
index 3e69878846..c5ac4c1508 100644
--- a/compiler/dex/quick/arm/assemble_arm.cc
+++ b/compiler/dex/quick/arm/assemble_arm.cc
@@ -1083,7 +1083,9 @@ void ArmMir2Lir::InsertFixupBefore(LIR* prev_lir, LIR* orig_lir, LIR* new_lir) {
#define PADDING_MOV_R5_R5 0x1C2D
uint8_t* ArmMir2Lir::EncodeLIRs(uint8_t* write_pos, LIR* lir) {
+ uint8_t* const write_buffer = write_pos;
for (; lir != NULL; lir = NEXT_LIR(lir)) {
+ lir->offset = (write_pos - write_buffer);
if (!lir->flags.is_nop) {
int opcode = lir->opcode;
if (IsPseudoLirOp(opcode)) {
diff --git a/compiler/dex/quick/arm/call_arm.cc b/compiler/dex/quick/arm/call_arm.cc
index 3081c9e752..e6158c3200 100644
--- a/compiler/dex/quick/arm/call_arm.cc
+++ b/compiler/dex/quick/arm/call_arm.cc
@@ -372,7 +372,6 @@ void ArmMir2Lir::GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method) {
* a leaf *and* our frame size < fudge factor.
*/
bool skip_overflow_check = mir_graph_->MethodIsLeaf() && !FrameNeedsStackCheck(frame_size_, kArm);
- NewLIR0(kPseudoMethodEntry);
const size_t kStackOverflowReservedUsableBytes = GetStackOverflowReservedBytes(kArm);
bool large_frame = (static_cast<size_t>(frame_size_) > kStackOverflowReservedUsableBytes);
bool generate_explicit_stack_overflow_check = large_frame ||
@@ -507,7 +506,6 @@ void ArmMir2Lir::GenExitSequence() {
LockTemp(rs_r0);
LockTemp(rs_r1);
- NewLIR0(kPseudoMethodExit);
OpRegImm(kOpAdd, rs_rARM_SP, frame_size_ - (spill_count * 4));
/* Need to restore any FP callee saves? */
if (num_fp_spills_) {
diff --git a/compiler/dex/quick/arm64/assemble_arm64.cc b/compiler/dex/quick/arm64/assemble_arm64.cc
index a59deb5db7..2f1ae66bfc 100644
--- a/compiler/dex/quick/arm64/assemble_arm64.cc
+++ b/compiler/dex/quick/arm64/assemble_arm64.cc
@@ -686,7 +686,9 @@ void Arm64Mir2Lir::InsertFixupBefore(LIR* prev_lir, LIR* orig_lir, LIR* new_lir)
#define PADDING_NOP (UINT32_C(0xd503201f))
uint8_t* Arm64Mir2Lir::EncodeLIRs(uint8_t* write_pos, LIR* lir) {
+ uint8_t* const write_buffer = write_pos;
for (; lir != nullptr; lir = NEXT_LIR(lir)) {
+ lir->offset = (write_pos - write_buffer);
bool opcode_is_wide = IS_WIDE(lir->opcode);
A64Opcode opcode = UNWIDE(lir->opcode);
diff --git a/compiler/dex/quick/arm64/call_arm64.cc b/compiler/dex/quick/arm64/call_arm64.cc
index 3316945ed1..6b47bba884 100644
--- a/compiler/dex/quick/arm64/call_arm64.cc
+++ b/compiler/dex/quick/arm64/call_arm64.cc
@@ -312,8 +312,6 @@ void Arm64Mir2Lir::GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method)
bool skip_overflow_check = mir_graph_->MethodIsLeaf() &&
!FrameNeedsStackCheck(frame_size_, kArm64);
- NewLIR0(kPseudoMethodEntry);
-
const size_t kStackOverflowReservedUsableBytes = GetStackOverflowReservedBytes(kArm64);
const bool large_frame = static_cast<size_t>(frame_size_) > kStackOverflowReservedUsableBytes;
bool generate_explicit_stack_overflow_check = large_frame ||
@@ -401,9 +399,6 @@ void Arm64Mir2Lir::GenExitSequence() {
*/
LockTemp(rs_x0);
LockTemp(rs_x1);
-
- NewLIR0(kPseudoMethodExit);
-
UnspillRegs(rs_sp, core_spill_mask_, fp_spill_mask_, frame_size_);
// Finally return.
diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc
index 509d4487ad..483a5d06cc 100644
--- a/compiler/dex/quick/codegen_util.cc
+++ b/compiler/dex/quick/codegen_util.cc
@@ -203,12 +203,17 @@ void Mir2Lir::DumpLIRInsn(LIR* lir, unsigned char* base_addr) {
/* Handle pseudo-ops individually, and all regular insns as a group */
switch (lir->opcode) {
- case kPseudoMethodEntry:
- LOG(INFO) << "-------- method entry "
- << PrettyMethod(cu_->method_idx, *cu_->dex_file);
+ case kPseudoPrologueBegin:
+ LOG(INFO) << "-------- PrologueBegin";
break;
- case kPseudoMethodExit:
- LOG(INFO) << "-------- Method_Exit";
+ case kPseudoPrologueEnd:
+ LOG(INFO) << "-------- PrologueEnd";
+ break;
+ case kPseudoEpilogueBegin:
+ LOG(INFO) << "-------- EpilogueBegin";
+ break;
+ case kPseudoEpilogueEnd:
+ LOG(INFO) << "-------- EpilogueEnd";
break;
case kPseudoBarrier:
LOG(INFO) << "-------- BARRIER";
@@ -267,8 +272,9 @@ void Mir2Lir::DumpLIRInsn(LIR* lir, unsigned char* base_addr) {
lir, base_addr));
std::string op_operands(BuildInsnString(GetTargetInstFmt(lir->opcode),
lir, base_addr));
- LOG(INFO) << StringPrintf("%5p: %-9s%s%s",
+ LOG(INFO) << StringPrintf("%5p|0x%02x: %-9s%s%s",
base_addr + offset,
+ lir->dalvik_offset,
op_name.c_str(), op_operands.c_str(),
lir->flags.is_nop ? "(nop)" : "");
}
@@ -713,14 +719,17 @@ void Mir2Lir::CreateMappingTables() {
DCHECK_EQ(static_cast<size_t>(write_pos - &encoded_mapping_table_[0]), hdr_data_size);
uint8_t* write_pos2 = write_pos + pc2dex_data_size;
+ bool is_in_prologue_or_epilogue = false;
pc2dex_offset = 0u;
pc2dex_dalvik_offset = 0u;
dex2pc_offset = 0u;
dex2pc_dalvik_offset = 0u;
for (LIR* tgt_lir = first_lir_insn_; tgt_lir != nullptr; tgt_lir = NEXT_LIR(tgt_lir)) {
- if (generate_src_map && !tgt_lir->flags.is_nop) {
- src_mapping_table_.push_back(SrcMapElem({tgt_lir->offset,
- static_cast<int32_t>(tgt_lir->dalvik_offset)}));
+ if (generate_src_map && !tgt_lir->flags.is_nop && tgt_lir->opcode >= 0) {
+ if (!is_in_prologue_or_epilogue) {
+ src_mapping_table_.push_back(SrcMapElem({tgt_lir->offset,
+ static_cast<int32_t>(tgt_lir->dalvik_offset)}));
+ }
}
if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) {
DCHECK(pc2dex_offset <= tgt_lir->offset);
@@ -738,6 +747,12 @@ void Mir2Lir::CreateMappingTables() {
dex2pc_offset = tgt_lir->offset;
dex2pc_dalvik_offset = tgt_lir->dalvik_offset;
}
+ if (tgt_lir->opcode == kPseudoPrologueBegin || tgt_lir->opcode == kPseudoEpilogueBegin) {
+ is_in_prologue_or_epilogue = true;
+ }
+ if (tgt_lir->opcode == kPseudoPrologueEnd || tgt_lir->opcode == kPseudoEpilogueEnd) {
+ is_in_prologue_or_epilogue = false;
+ }
}
DCHECK_EQ(static_cast<size_t>(write_pos - &encoded_mapping_table_[0]),
hdr_data_size + pc2dex_data_size);
diff --git a/compiler/dex/quick/mips/call_mips.cc b/compiler/dex/quick/mips/call_mips.cc
index de66b35418..c932df6dc9 100644
--- a/compiler/dex/quick/mips/call_mips.cc
+++ b/compiler/dex/quick/mips/call_mips.cc
@@ -275,7 +275,6 @@ void MipsMir2Lir::GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method)
*/
skip_overflow_check = mir_graph_->MethodIsLeaf() && !FrameNeedsStackCheck(frame_size_, target);
- NewLIR0(kPseudoMethodEntry);
RegStorage check_reg = AllocPtrSizeTemp();
RegStorage new_sp = AllocPtrSizeTemp();
const RegStorage rs_sp = TargetPtrReg(kSp);
@@ -345,7 +344,6 @@ void MipsMir2Lir::GenExitSequence() {
LockTemp(TargetPtrReg(kRet0));
LockTemp(TargetPtrReg(kRet1));
- NewLIR0(kPseudoMethodExit);
UnSpillCoreRegs();
OpReg(kOpBx, TargetPtrReg(kLr));
}
diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc
index 0b480a09c6..ed8e21e817 100644
--- a/compiler/dex/quick/mir_to_lir.cc
+++ b/compiler/dex/quick/mir_to_lir.cc
@@ -1250,10 +1250,14 @@ bool Mir2Lir::MethodBlockCodeGen(BasicBlock* bb) {
if (bb->block_type == kEntryBlock) {
ResetRegPool();
int start_vreg = mir_graph_->GetFirstInVR();
+ AppendLIR(NewLIR0(kPseudoPrologueBegin));
GenEntrySequence(&mir_graph_->reg_location_[start_vreg], mir_graph_->GetMethodLoc());
+ AppendLIR(NewLIR0(kPseudoPrologueEnd));
} else if (bb->block_type == kExitBlock) {
ResetRegPool();
+ AppendLIR(NewLIR0(kPseudoEpilogueBegin));
GenExitSequence();
+ AppendLIR(NewLIR0(kPseudoEpilogueEnd));
}
for (mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
diff --git a/compiler/dex/quick/x86/call_x86.cc b/compiler/dex/quick/x86/call_x86.cc
index e81228a5e9..89f6c6edbd 100644
--- a/compiler/dex/quick/x86/call_x86.cc
+++ b/compiler/dex/quick/x86/call_x86.cc
@@ -186,7 +186,6 @@ void X86Mir2Lir::GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method) {
stack_decrement_ = OpRegImm(kOpSub, rs_rSP, frame_size_ -
GetInstructionSetPointerSize(cu_->instruction_set));
- NewLIR0(kPseudoMethodEntry);
/* Spill core callee saves */
SpillCoreRegs();
SpillFPRegs();
@@ -259,7 +258,6 @@ void X86Mir2Lir::GenExitSequence() {
LockTemp(rs_rX86_RET0);
LockTemp(rs_rX86_RET1);
- NewLIR0(kPseudoMethodExit);
UnSpillCoreRegs();
UnSpillFPRegs();
/* Remove frame except for return address */
diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc
index ca5ec66381..a92ce69c6d 100644
--- a/compiler/elf_writer_quick.cc
+++ b/compiler/elf_writer_quick.cc
@@ -25,6 +25,8 @@
#include "driver/compiler_driver.h"
#include "driver/compiler_options.h"
#include "dwarf.h"
+#include "dwarf/debug_frame_writer.h"
+#include "dwarf/debug_line_writer.h"
#include "elf_builder.h"
#include "elf_file.h"
#include "elf_utils.h"
@@ -275,96 +277,8 @@ bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
return builder->Write();
}
-class LineTableGenerator FINAL : public Leb128Encoder {
- public:
- LineTableGenerator(int line_base, int line_range, int opcode_base,
- std::vector<uint8_t>* data, uintptr_t current_address,
- size_t current_line)
- : Leb128Encoder(data), line_base_(line_base), line_range_(line_range),
- opcode_base_(opcode_base), current_address_(current_address),
- current_line_(current_line), current_file_index_(0) {}
-
- void PutDelta(unsigned delta_addr, int delta_line) {
- current_line_ += delta_line;
- current_address_ += delta_addr;
-
- if (delta_line >= line_base_ && delta_line < line_base_ + line_range_) {
- unsigned special_opcode = (delta_line - line_base_) +
- (line_range_ * delta_addr) + opcode_base_;
- if (special_opcode <= 255) {
- PushByte(data_, special_opcode);
- return;
- }
- }
-
- // generate standart opcode for address advance
- if (delta_addr != 0) {
- PushByte(data_, DW_LNS_advance_pc);
- PushBackUnsigned(delta_addr);
- }
-
- // generate standart opcode for line delta
- if (delta_line != 0) {
- PushByte(data_, DW_LNS_advance_line);
- PushBackSigned(delta_line);
- }
-
- // generate standart opcode for new LTN entry
- PushByte(data_, DW_LNS_copy);
- }
-
- void SetAddr(uintptr_t addr) {
- if (current_address_ == addr) {
- return;
- }
-
- current_address_ = addr;
-
- PushByte(data_, 0); // extended opcode:
- PushByte(data_, 1 + 4); // length: opcode_size + address_size
- PushByte(data_, DW_LNE_set_address);
- Push32(data_, addr);
- }
-
- void SetLine(unsigned line) {
- int delta_line = line - current_line_;
- if (delta_line) {
- current_line_ = line;
- PushByte(data_, DW_LNS_advance_line);
- PushBackSigned(delta_line);
- }
- }
-
- void SetFile(unsigned file_index) {
- if (current_file_index_ != file_index) {
- current_file_index_ = file_index;
- PushByte(data_, DW_LNS_set_file);
- PushBackUnsigned(file_index);
- }
- }
-
- void EndSequence() {
- // End of Line Table Program
- // 0(=ext), 1(len), DW_LNE_end_sequence
- PushByte(data_, 0);
- PushByte(data_, 1);
- PushByte(data_, DW_LNE_end_sequence);
- }
-
- private:
- const int line_base_;
- const int line_range_;
- const int opcode_base_;
- uintptr_t current_address_;
- size_t current_line_;
- unsigned current_file_index_;
-
- DISALLOW_COPY_AND_ASSIGN(LineTableGenerator);
-};
-
// TODO: rewriting it using DexFile::DecodeDebugInfo needs unneeded stuff.
-static void GetLineInfoForJava(const uint8_t* dbgstream, const SwapSrcMap& pc2dex,
- DefaultSrcMap* result, uint32_t start_pc = 0) {
+static void GetLineInfoForJava(const uint8_t* dbgstream, DefaultSrcMap* dex2line) {
if (dbgstream == nullptr) {
return;
}
@@ -419,12 +333,7 @@ static void GetLineInfoForJava(const uint8_t* dbgstream, const SwapSrcMap& pc2de
adjopcode = opcode - DexFile::DBG_FIRST_SPECIAL;
dex_offset += adjopcode / DexFile::DBG_LINE_RANGE;
java_line += DexFile::DBG_LINE_BASE + (adjopcode % DexFile::DBG_LINE_RANGE);
-
- for (SwapSrcMap::const_iterator found = pc2dex.FindByTo(dex_offset);
- found != pc2dex.end() && found->to_ == static_cast<int32_t>(dex_offset);
- found++) {
- result->push_back({found->from_ + start_pc, static_cast<int32_t>(java_line)});
- }
+ dex2line->push_back({dex_offset, static_cast<int32_t>(java_line)});
break;
}
}
@@ -443,71 +352,78 @@ static void FillInCFIInformation(OatWriter* oat_writer,
std::vector<uint8_t>* dbg_str,
std::vector<uint8_t>* dbg_line,
uint32_t text_section_offset) {
- const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo();
+ const std::vector<OatWriter::DebugInfo>& method_infos = oat_writer->GetCFIMethodInfo();
uint32_t producer_str_offset = PushStr(dbg_str, "Android dex2oat");
+ constexpr bool use_64bit_addresses = false;
+
// Create the debug_abbrev section with boilerplate information.
// We only care about low_pc and high_pc right now for the compilation
// unit and methods.
// Tag 1: Compilation unit: DW_TAG_compile_unit.
PushByte(dbg_abbrev, 1);
- PushByte(dbg_abbrev, DW_TAG_compile_unit);
+ PushByte(dbg_abbrev, dwarf::DW_TAG_compile_unit);
// There are children (the methods).
- PushByte(dbg_abbrev, DW_CHILDREN_yes);
+ PushByte(dbg_abbrev, dwarf::DW_CHILDREN_yes);
// DW_AT_producer DW_FORM_data1.
// REVIEW: we can get rid of dbg_str section if
// DW_FORM_string (immediate string) was used everywhere instead of
// DW_FORM_strp (ref to string from .debug_str section).
// DW_FORM_strp makes sense only if we reuse the strings.
- PushByte(dbg_abbrev, DW_AT_producer);
- PushByte(dbg_abbrev, DW_FORM_strp);
+ PushByte(dbg_abbrev, dwarf::DW_AT_producer);
+ PushByte(dbg_abbrev, dwarf::DW_FORM_strp);
// DW_LANG_Java DW_FORM_data1.
- PushByte(dbg_abbrev, DW_AT_language);
- PushByte(dbg_abbrev, DW_FORM_data1);
+ PushByte(dbg_abbrev, dwarf::DW_AT_language);
+ PushByte(dbg_abbrev, dwarf::DW_FORM_data1);
// DW_AT_low_pc DW_FORM_addr.
- PushByte(dbg_abbrev, DW_AT_low_pc);
- PushByte(dbg_abbrev, DW_FORM_addr);
+ PushByte(dbg_abbrev, dwarf::DW_AT_low_pc);
+ PushByte(dbg_abbrev, dwarf::DW_FORM_addr);
// DW_AT_high_pc DW_FORM_addr.
- PushByte(dbg_abbrev, DW_AT_high_pc);
- PushByte(dbg_abbrev, DW_FORM_addr);
+ PushByte(dbg_abbrev, dwarf::DW_AT_high_pc);
+ PushByte(dbg_abbrev, dwarf::DW_FORM_addr);
if (dbg_line != nullptr) {
// DW_AT_stmt_list DW_FORM_sec_offset.
- PushByte(dbg_abbrev, DW_AT_stmt_list);
- PushByte(dbg_abbrev, DW_FORM_sec_offset);
+ PushByte(dbg_abbrev, dwarf::DW_AT_stmt_list);
+ PushByte(dbg_abbrev, dwarf::DW_FORM_data4);
}
// End of DW_TAG_compile_unit.
- PushHalf(dbg_abbrev, 0);
+ PushByte(dbg_abbrev, 0); // DW_AT.
+ PushByte(dbg_abbrev, 0); // DW_FORM.
// Tag 2: Compilation unit: DW_TAG_subprogram.
PushByte(dbg_abbrev, 2);
- PushByte(dbg_abbrev, DW_TAG_subprogram);
+ PushByte(dbg_abbrev, dwarf::DW_TAG_subprogram);
// There are no children.
- PushByte(dbg_abbrev, DW_CHILDREN_no);
+ PushByte(dbg_abbrev, dwarf::DW_CHILDREN_no);
// Name of the method.
- PushByte(dbg_abbrev, DW_AT_name);
- PushByte(dbg_abbrev, DW_FORM_strp);
+ PushByte(dbg_abbrev, dwarf::DW_AT_name);
+ PushByte(dbg_abbrev, dwarf::DW_FORM_strp);
// DW_AT_low_pc DW_FORM_addr.
- PushByte(dbg_abbrev, DW_AT_low_pc);
- PushByte(dbg_abbrev, DW_FORM_addr);
+ PushByte(dbg_abbrev, dwarf::DW_AT_low_pc);
+ PushByte(dbg_abbrev, dwarf::DW_FORM_addr);
// DW_AT_high_pc DW_FORM_addr.
- PushByte(dbg_abbrev, DW_AT_high_pc);
- PushByte(dbg_abbrev, DW_FORM_addr);
+ PushByte(dbg_abbrev, dwarf::DW_AT_high_pc);
+ PushByte(dbg_abbrev, dwarf::DW_FORM_addr);
// End of DW_TAG_subprogram.
- PushHalf(dbg_abbrev, 0);
+ PushByte(dbg_abbrev, 0); // DW_AT.
+ PushByte(dbg_abbrev, 0); // DW_FORM.
+
+ // End of abbrevs for compilation unit
+ PushByte(dbg_abbrev, 0);
// Start the debug_info section with the header information
// 'unit_length' will be filled in later.
@@ -520,8 +436,8 @@ static void FillInCFIInformation(OatWriter* oat_writer,
// Offset into .debug_abbrev section (always 0).
Push32(dbg_info, 0);
- // Address size: 4.
- PushByte(dbg_info, 4);
+ // Address size: 4 or 8.
+ PushByte(dbg_info, use_64bit_addresses ? 8 : 4);
// Start the description for the compilation unit.
// This uses tag 1.
@@ -531,31 +447,34 @@ static void FillInCFIInformation(OatWriter* oat_writer,
Push32(dbg_info, producer_str_offset);
// The language is Java.
- PushByte(dbg_info, DW_LANG_Java);
+ PushByte(dbg_info, dwarf::DW_LANG_Java);
// low_pc and high_pc.
- uint32_t cunit_low_pc = 0 - 1;
+ uint32_t cunit_low_pc = static_cast<uint32_t>(-1);
uint32_t cunit_high_pc = 0;
- int cunit_low_pc_pos = dbg_info->size();
- Push32(dbg_info, 0);
- Push32(dbg_info, 0);
+ for (auto method_info : method_infos) {
+ cunit_low_pc = std::min(cunit_low_pc, method_info.low_pc_);
+ cunit_high_pc = std::max(cunit_high_pc, method_info.high_pc_);
+ }
+ Push32(dbg_info, cunit_low_pc + text_section_offset);
+ Push32(dbg_info, cunit_high_pc + text_section_offset);
- if (dbg_line == nullptr) {
- for (size_t i = 0; i < method_info.size(); ++i) {
- const OatWriter::DebugInfo &dbg = method_info[i];
+ if (dbg_line != nullptr) {
+ // Line number table offset.
+ Push32(dbg_info, dbg_line->size());
+ }
- cunit_low_pc = std::min(cunit_low_pc, dbg.low_pc_);
- cunit_high_pc = std::max(cunit_high_pc, dbg.high_pc_);
+ for (auto method_info : method_infos) {
+ // Start a new TAG: subroutine (2).
+ PushByte(dbg_info, 2);
- // Start a new TAG: subroutine (2).
- PushByte(dbg_info, 2);
+ // Enter name, low_pc, high_pc.
+ Push32(dbg_info, PushStr(dbg_str, method_info.method_name_));
+ Push32(dbg_info, method_info.low_pc_ + text_section_offset);
+ Push32(dbg_info, method_info.high_pc_ + text_section_offset);
+ }
- // Enter name, low_pc, high_pc.
- Push32(dbg_info, PushStr(dbg_str, dbg.method_name_));
- Push32(dbg_info, dbg.low_pc_ + text_section_offset);
- Push32(dbg_info, dbg.high_pc_ + text_section_offset);
- }
- } else {
+ if (dbg_line != nullptr) {
// TODO: in gdb info functions <regexp> - reports Java functions, but
// source file is <unknown> because .debug_line is formed as one
// compilation unit. To fix this it is possible to generate
@@ -563,110 +482,135 @@ static void FillInCFIInformation(OatWriter* oat_writer,
// Each of the these compilation units can have several non-adjacent
// method ranges.
- // Line number table offset
- Push32(dbg_info, dbg_line->size());
+ std::vector<dwarf::DebugLineWriter<>::FileEntry> files;
+ std::unordered_map<std::string, size_t> files_map;
+ std::vector<std::string> directories;
+ std::unordered_map<std::string, size_t> directories_map;
+
+ int code_factor_bits_ = 0;
+ int isa = -1;
+ switch (oat_writer->GetOatHeader().GetInstructionSet()) {
+ case kThumb2:
+ code_factor_bits_ = 1; // 16-bit instuctions
+ isa = 1; // DW_ISA_ARM_thumb.
+ break;
+ case kArm:
+ code_factor_bits_ = 2; // 32-bit instructions
+ isa = 2; // DW_ISA_ARM_arm.
+ break;
+ case kArm64:
+ case kMips:
+ case kMips64:
+ code_factor_bits_ = 2; // 32-bit instructions
+ break;
+ case kNone:
+ case kX86:
+ case kX86_64:
+ break;
+ }
- size_t lnt_length = dbg_line->size();
- Push32(dbg_line, 0);
-
- PushHalf(dbg_line, 4); // LNT Version DWARF v4 => 4
-
- size_t lnt_hdr_length = dbg_line->size();
- Push32(dbg_line, 0); // TODO: 64-bit uses 8-byte here
-
- PushByte(dbg_line, 1); // minimum_instruction_length (ubyte)
- PushByte(dbg_line, 1); // maximum_operations_per_instruction (ubyte) = always 1
- PushByte(dbg_line, 1); // default_is_stmt (ubyte)
-
- const int8_t LINE_BASE = -5;
- PushByte(dbg_line, LINE_BASE); // line_base (sbyte)
-
- const uint8_t LINE_RANGE = 14;
- PushByte(dbg_line, LINE_RANGE); // line_range (ubyte)
-
- const uint8_t OPCODE_BASE = 13;
- PushByte(dbg_line, OPCODE_BASE); // opcode_base (ubyte)
-
- // Standard_opcode_lengths (array of ubyte).
- PushByte(dbg_line, 0); PushByte(dbg_line, 1); PushByte(dbg_line, 1);
- PushByte(dbg_line, 1); PushByte(dbg_line, 1); PushByte(dbg_line, 0);
- PushByte(dbg_line, 0); PushByte(dbg_line, 0); PushByte(dbg_line, 1);
- PushByte(dbg_line, 0); PushByte(dbg_line, 0); PushByte(dbg_line, 1);
-
- PushByte(dbg_line, 0); // include_directories (sequence of path names) = EMPTY
-
- // File_names (sequence of file entries).
- std::unordered_map<const char*, size_t> files;
- for (size_t i = 0; i < method_info.size(); ++i) {
- const OatWriter::DebugInfo &dbg = method_info[i];
- // TODO: add package directory to the file name
- const char* file_name = dbg.src_file_name_ == nullptr ? "null" : dbg.src_file_name_;
- auto found = files.find(file_name);
- if (found == files.end()) {
- size_t file_index = 1 + files.size();
- files[file_name] = file_index;
- PushStr(dbg_line, file_name);
- PushByte(dbg_line, 0); // include directory index = LEB128(0) - no directory
- PushByte(dbg_line, 0); // modification time = LEB128(0) - NA
- PushByte(dbg_line, 0); // file length = LEB128(0) - NA
- }
+ dwarf::DebugLineOpCodeWriter<> opcodes(use_64bit_addresses, code_factor_bits_);
+ opcodes.SetAddress(text_section_offset + cunit_low_pc);
+ if (isa != -1) {
+ opcodes.SetISA(isa);
}
- PushByte(dbg_line, 0); // End of file_names.
-
- // Set lnt header length.
- UpdateWord(dbg_line, lnt_hdr_length, dbg_line->size() - lnt_hdr_length - 4);
-
- // Generate Line Number Program code, one long program for all methods.
- LineTableGenerator line_table_generator(LINE_BASE, LINE_RANGE, OPCODE_BASE,
- dbg_line, 0, 1);
-
- DefaultSrcMap pc2java_map;
- for (size_t i = 0; i < method_info.size(); ++i) {
- const OatWriter::DebugInfo &dbg = method_info[i];
- const char* file_name = (dbg.src_file_name_ == nullptr) ? "null" : dbg.src_file_name_;
- size_t file_index = files[file_name];
- DCHECK_NE(file_index, 0U) << file_name;
-
- cunit_low_pc = std::min(cunit_low_pc, dbg.low_pc_);
- cunit_high_pc = std::max(cunit_high_pc, dbg.high_pc_);
-
- // Start a new TAG: subroutine (2).
- PushByte(dbg_info, 2);
-
- // Enter name, low_pc, high_pc.
- Push32(dbg_info, PushStr(dbg_str, dbg.method_name_));
- Push32(dbg_info, dbg.low_pc_ + text_section_offset);
- Push32(dbg_info, dbg.high_pc_ + text_section_offset);
-
- GetLineInfoForJava(dbg.dbgstream_, dbg.compiled_method_->GetSrcMappingTable(),
- &pc2java_map, dbg.low_pc_);
- pc2java_map.DeltaFormat({dbg.low_pc_, 1}, dbg.high_pc_);
- if (!pc2java_map.empty()) {
- line_table_generator.SetFile(file_index);
- line_table_generator.SetAddr(dbg.low_pc_ + text_section_offset);
- line_table_generator.SetLine(1);
- for (auto& src_map_elem : pc2java_map) {
- line_table_generator.PutDelta(src_map_elem.from_, src_map_elem.to_);
+ DefaultSrcMap dex2line_map;
+ for (size_t i = 0; i < method_infos.size(); i++) {
+ const OatWriter::DebugInfo& method_info = method_infos[i];
+
+ // Addresses in the line table should be unique and increasing.
+ if (method_info.deduped_) {
+ continue;
+ }
+
+ // Get and deduplicate directory and filename.
+ int file_index = 0; // 0 - primary source file of the compilation.
+ if (method_info.src_file_name_ != nullptr) {
+ std::string file_name(method_info.src_file_name_);
+ size_t file_name_slash = file_name.find_last_of('/');
+ std::string class_name(method_info.class_descriptor_);
+ size_t class_name_slash = class_name.find_last_of('/');
+ std::string full_path(file_name);
+
+ // Guess directory from package name.
+ int directory_index = 0; // 0 - current directory of the compilation.
+ if (file_name_slash == std::string::npos && // Just filename.
+ class_name.front() == 'L' && // Type descriptor for a class.
+ class_name_slash != std::string::npos) { // Has package name.
+ std::string package_name = class_name.substr(1, class_name_slash - 1);
+ auto it = directories_map.find(package_name);
+ if (it == directories_map.end()) {
+ directory_index = 1 + directories.size();
+ directories_map.emplace(package_name, directory_index);
+ directories.push_back(package_name);
+ } else {
+ directory_index = it->second;
+ }
+ full_path = package_name + "/" + file_name;
+ }
+
+ // Add file entry.
+ auto it2 = files_map.find(full_path);
+ if (it2 == files_map.end()) {
+ file_index = 1 + files.size();
+ files_map.emplace(full_path, file_index);
+ files.push_back(dwarf::DebugLineWriter<>::FileEntry {
+ file_name,
+ directory_index,
+ 0, // Modification time - NA.
+ 0, // File size - NA.
+ });
+ } else {
+ file_index = it2->second;
}
- pc2java_map.clear();
+ }
+ opcodes.SetFile(file_index);
+
+ // Generate mapping opcodes from PC to Java lines.
+ dex2line_map.clear();
+ GetLineInfoForJava(method_info.dbgstream_, &dex2line_map);
+ uint32_t low_pc = text_section_offset + method_info.low_pc_;
+ if (file_index != 0 && !dex2line_map.empty()) {
+ bool first = true;
+ for (SrcMapElem pc2dex : method_info.compiled_method_->GetSrcMappingTable()) {
+ uint32_t pc = pc2dex.from_;
+ int dex = pc2dex.to_;
+ auto dex2line = dex2line_map.Find(static_cast<uint32_t>(dex));
+ if (dex2line.first) {
+ int line = dex2line.second;
+ if (first) {
+ first = false;
+ if (pc > 0) {
+ // Assume that any preceding code is prologue.
+ int first_line = dex2line_map.front().to_;
+ // Prologue is not a sensible place for a breakpoint.
+ opcodes.NegateStmt();
+ opcodes.AddRow(low_pc, first_line);
+ opcodes.NegateStmt();
+ opcodes.SetPrologueEnd();
+ }
+ opcodes.AddRow(low_pc + pc, line);
+ } else if (line != opcodes.CurrentLine()) {
+ opcodes.AddRow(low_pc + pc, line);
+ }
+ }
+ }
+ } else {
+ // line 0 - instruction cannot be attributed to any source line.
+ opcodes.AddRow(low_pc, 0);
}
}
- // End Sequence should have the highest address set.
- line_table_generator.SetAddr(cunit_high_pc + text_section_offset);
- line_table_generator.EndSequence();
+ opcodes.AdvancePC(text_section_offset + cunit_high_pc);
+ opcodes.EndSequence();
- // set lnt length
- UpdateWord(dbg_line, lnt_length, dbg_line->size() - lnt_length - 4);
+ dwarf::DebugLineWriter<> dbg_line_writer(dbg_line);
+ dbg_line_writer.WriteTable(directories, files, opcodes);
}
- // One byte terminator
+ // One byte terminator.
PushByte(dbg_info, 0);
- // Fill in cunit's low_pc and high_pc.
- UpdateWord(dbg_info, cunit_low_pc_pos, cunit_low_pc + text_section_offset);
- UpdateWord(dbg_info, cunit_low_pc_pos + 4, cunit_high_pc + text_section_offset);
-
// We have now walked all the methods. Fill in lengths.
UpdateWord(dbg_info, cunit_length, dbg_info->size() - cunit_length - 4);
}
@@ -690,8 +634,11 @@ static void WriteDebugSymbols(const CompilerDriver* compiler_driver,
ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr>* symtab =
builder->GetSymtabBuilder();
for (auto it = method_info.begin(); it != method_info.end(); ++it) {
- symtab->AddSymbol(it->method_name_, &builder->GetTextBuilder(), it->low_pc_, true,
- it->high_pc_ - it->low_pc_, STB_GLOBAL, STT_FUNC);
+ uint32_t low_pc = it->low_pc_;
+ // Add in code delta, e.g., thumb bit 0 for Thumb2 code.
+ low_pc += it->compiled_method_->CodeDelta();
+ symtab->AddSymbol(it->method_name_, &builder->GetTextBuilder(), low_pc,
+ true, it->high_pc_ - it->low_pc_, 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.
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index 04f0db6572..880ac15327 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -1069,10 +1069,12 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor {
}
const uint32_t quick_code_start = quick_code_offset -
- writer_->oat_header_->GetExecutableOffset();
+ writer_->oat_header_->GetExecutableOffset() - thumb_offset;
const DexFile::CodeItem *code_item = it.GetMethodCodeItem();
- writer_->method_info_.push_back(DebugInfo(name,
- dex_file_->GetSourceFile(dex_file_->GetClassDef(class_def_index_)),
+ const DexFile::ClassDef& class_def = dex_file_->GetClassDef(class_def_index_);
+ writer_->method_info_.push_back(DebugInfo(name, deduped,
+ dex_file_->GetClassDescriptor(class_def),
+ dex_file_->GetSourceFile(class_def),
quick_code_start, quick_code_start + code_size,
code_item == nullptr ? nullptr : dex_file_->GetDebugInfoStream(code_item),
compiled_method));
diff --git a/compiler/oat_writer.h b/compiler/oat_writer.h
index 676d628450..4538694c00 100644
--- a/compiler/oat_writer.h
+++ b/compiler/oat_writer.h
@@ -114,14 +114,18 @@ class OatWriter {
~OatWriter();
struct DebugInfo {
- DebugInfo(const std::string& method_name, const char* src_file_name,
- uint32_t low_pc, uint32_t high_pc, const uint8_t* dbgstream,
- CompiledMethod* compiled_method)
- : method_name_(method_name), src_file_name_(src_file_name),
- low_pc_(low_pc), high_pc_(high_pc), dbgstream_(dbgstream),
- compiled_method_(compiled_method) {
+ DebugInfo(const std::string& method_name, bool deduped,
+ const char* class_descriptor, const char* src_file_name,
+ uint32_t low_pc, uint32_t high_pc,
+ const uint8_t* dbgstream, CompiledMethod* compiled_method)
+ : method_name_(method_name), deduped_(deduped),
+ class_descriptor_(class_descriptor), src_file_name_(src_file_name),
+ low_pc_(low_pc), high_pc_(high_pc),
+ dbgstream_(dbgstream), compiled_method_(compiled_method) {
}
std::string method_name_; // Note: this name is a pretty-printed name.
+ bool deduped_;
+ const char* class_descriptor_;
const char* src_file_name_;
uint32_t low_pc_;
uint32_t high_pc_;
diff --git a/runtime/dwarf.h b/runtime/dwarf.h
index 7daa5f1485..b491f4767c 100644
--- a/runtime/dwarf.h
+++ b/runtime/dwarf.h
@@ -18,6 +18,7 @@
#define ART_RUNTIME_DWARF_H_
namespace art {
+namespace dwarf {
// Based on the Dwarf 4 specification at dwarfstd.com and issues marked
// for inclusion in Dwarf 5 on same. Values not specified in the Dwarf 4
@@ -657,6 +658,7 @@ enum CallFrameInstruction : uint8_t {
DW_CFA_hi_user = 0x3f
};
+} // namespace dwarf
} // namespace art
#endif // ART_RUNTIME_DWARF_H_
diff --git a/runtime/elf_file.cc b/runtime/elf_file.cc
index 3490bcf862..bc5cf9b1ff 100644
--- a/runtime/elf_file.cc
+++ b/runtime/elf_file.cc
@@ -1665,7 +1665,6 @@ struct PACKED(1) DebugLineHeader {
uint16_t version_;
uint32_t header_length_; // TODO 32-bit specific size
uint8_t minimum_instruction_lenght_;
- uint8_t maximum_operations_per_instruction_;
uint8_t default_is_stmt_;
int8_t line_base_;
uint8_t line_range_;
@@ -1691,7 +1690,7 @@ struct PACKED(1) DebugLineHeader {
return length_field + length;
} else if (!IsStandardOpcode(op)) {
return op + 1;
- } else if (*op == DW_LNS_fixed_advance_pc) {
+ } else if (*op == dwarf::DW_LNS_fixed_advance_pc) {
return op + 1 + sizeof(uint16_t);
} else {
uint8_t num_args = GetStandardOpcodeLengths()[*op - 1];
@@ -1774,8 +1773,8 @@ class DebugLineInstructionIterator FINAL {
};
static bool FixupDebugLine(off_t base_offset_delta, DebugLineInstructionIterator* iter) {
- while (iter->Next()) {
- if (iter->IsExtendedOpcode() && iter->GetOpcode() == DW_LNE_set_address) {
+ for (; iter->GetInstruction(); iter->Next()) {
+ if (iter->IsExtendedOpcode() && iter->GetOpcode() == dwarf::DW_LNE_set_address) {
*reinterpret_cast<uint32_t*>(iter->GetArguments()) += base_offset_delta;
}
}
@@ -1792,39 +1791,39 @@ struct PACKED(1) DebugInfoHeader {
// Returns -1 if it is variable length, which we will just disallow for now.
static int32_t FormLength(uint32_t att) {
switch (att) {
- case DW_FORM_data1:
- case DW_FORM_flag:
- case DW_FORM_flag_present:
- case DW_FORM_ref1:
+ case dwarf::DW_FORM_data1:
+ case dwarf::DW_FORM_flag:
+ case dwarf::DW_FORM_flag_present:
+ case dwarf::DW_FORM_ref1:
return 1;
- case DW_FORM_data2:
- case DW_FORM_ref2:
+ case dwarf::DW_FORM_data2:
+ case dwarf::DW_FORM_ref2:
return 2;
- case DW_FORM_addr: // TODO 32-bit only
- case DW_FORM_ref_addr: // TODO 32-bit only
- case DW_FORM_sec_offset: // TODO 32-bit only
- case DW_FORM_strp: // TODO 32-bit only
- case DW_FORM_data4:
- case DW_FORM_ref4:
+ case dwarf::DW_FORM_addr: // TODO 32-bit only
+ case dwarf::DW_FORM_ref_addr: // TODO 32-bit only
+ case dwarf::DW_FORM_sec_offset: // TODO 32-bit only
+ case dwarf::DW_FORM_strp: // TODO 32-bit only
+ case dwarf::DW_FORM_data4:
+ case dwarf::DW_FORM_ref4:
return 4;
- case DW_FORM_data8:
- case DW_FORM_ref8:
- case DW_FORM_ref_sig8:
+ case dwarf::DW_FORM_data8:
+ case dwarf::DW_FORM_ref8:
+ case dwarf::DW_FORM_ref_sig8:
return 8;
- case DW_FORM_block:
- case DW_FORM_block1:
- case DW_FORM_block2:
- case DW_FORM_block4:
- case DW_FORM_exprloc:
- case DW_FORM_indirect:
- case DW_FORM_ref_udata:
- case DW_FORM_sdata:
- case DW_FORM_string:
- case DW_FORM_udata:
+ case dwarf::DW_FORM_block:
+ case dwarf::DW_FORM_block1:
+ case dwarf::DW_FORM_block2:
+ case dwarf::DW_FORM_block4:
+ case dwarf::DW_FORM_exprloc:
+ case dwarf::DW_FORM_indirect:
+ case dwarf::DW_FORM_ref_udata:
+ case dwarf::DW_FORM_sdata:
+ case dwarf::DW_FORM_string:
+ case dwarf::DW_FORM_udata:
default:
return -1;
}
@@ -2047,13 +2046,13 @@ class DebugInfoIterator {
static bool FixupDebugInfo(off_t base_address_delta, DebugInfoIterator* iter) {
do {
- if (iter->GetCurrentTag()->GetAttrSize(DW_AT_low_pc) != sizeof(int32_t) ||
- iter->GetCurrentTag()->GetAttrSize(DW_AT_high_pc) != sizeof(int32_t)) {
+ if (iter->GetCurrentTag()->GetAttrSize(dwarf::DW_AT_low_pc) != sizeof(int32_t) ||
+ iter->GetCurrentTag()->GetAttrSize(dwarf::DW_AT_high_pc) != sizeof(int32_t)) {
LOG(ERROR) << "DWARF information with 64 bit pointers is not supported yet.";
return false;
}
- uint32_t* PC_low = reinterpret_cast<uint32_t*>(iter->GetPointerToField(DW_AT_low_pc));
- uint32_t* PC_high = reinterpret_cast<uint32_t*>(iter->GetPointerToField(DW_AT_high_pc));
+ uint32_t* PC_low = reinterpret_cast<uint32_t*>(iter->GetPointerToField(dwarf::DW_AT_low_pc));
+ uint32_t* PC_high = reinterpret_cast<uint32_t*>(iter->GetPointerToField(dwarf::DW_AT_high_pc));
if (PC_low != nullptr && PC_high != nullptr) {
*PC_low += base_address_delta;
*PC_high += base_address_delta;