summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/debug/dwarf/dwarf_test.cc6
-rw-r--r--compiler/debug/elf_debug_writer.cc8
-rw-r--r--libelffile/dwarf/headers.h37
-rw-r--r--libelffile/elf/elf_debug_reader.h59
-rw-r--r--tools/create_minidebuginfo/create_minidebuginfo.cc2
5 files changed, 83 insertions, 29 deletions
diff --git a/compiler/debug/dwarf/dwarf_test.cc b/compiler/debug/dwarf/dwarf_test.cc
index 8897e45584..8fdc7ca63a 100644
--- a/compiler/debug/dwarf/dwarf_test.cc
+++ b/compiler/debug/dwarf/dwarf_test.cc
@@ -131,7 +131,7 @@ TEST_F(DwarfTest, DebugFrame) {
CheckObjdumpOutput(is64bit, "-debug-frame");
}
-TEST_F(DwarfTest, DISABLED_DebugFrame64) {
+TEST_F(DwarfTest, DebugFrame64) {
constexpr bool is64bit = true;
DebugFrameOpCodeWriter<> initial_opcodes;
WriteCIE(is64bit, Reg(16), initial_opcodes, &debug_frame_data_);
@@ -143,7 +143,7 @@ TEST_F(DwarfTest, DISABLED_DebugFrame64) {
0x0200000000000000,
ArrayRef<const uint8_t>(*opcodes.data()),
&debug_frame_data_);
- DW_CHECK("FDE cie=00000000 pc=100000000000000..300000000000000");
+ DW_CHECK("FDE cie=00000000 pc=100000000000000...300000000000000");
CheckObjdumpOutput(is64bit, "-debug-frame");
}
@@ -158,7 +158,7 @@ TEST_F(DwarfTest, x86_64_RegisterMapping) {
opcodes.RelOffset(Reg::X86_64Core(i), 0);
}
DW_CHECK("FDE");
- DW_CHECK_NEXT("DWARF32");
+ DW_CHECK_NEXT("DWARF64");
DW_CHECK_NEXT("DW_CFA_nop:"); // TODO: Why is a nop here.
DW_CHECK_NEXT("DW_CFA_offset: RAX 0");
DW_CHECK_NEXT("DW_CFA_offset: RCX 0");
diff --git a/compiler/debug/elf_debug_writer.cc b/compiler/debug/elf_debug_writer.cc
index 765a81d4f8..d0ca6db005 100644
--- a/compiler/debug/elf_debug_writer.cc
+++ b/compiler/debug/elf_debug_writer.cc
@@ -215,8 +215,8 @@ std::vector<uint8_t> MakeElfFileForJIT(
reader.VisitDebugFrame([&](const Reader::CIE* cie ATTRIBUTE_UNUSED) {
num_cies++;
}, [&](const Reader::FDE* fde, const Reader::CIE* cie ATTRIBUTE_UNUSED) {
- DCHECK_EQ(fde->sym_addr, method_info.code_address);
- DCHECK_EQ(fde->sym_size, method_info.code_size);
+ DCHECK_EQ(fde->sym_addr(), method_info.code_address);
+ DCHECK_EQ(fde->sym_size(), method_info.code_size);
num_fdes++;
});
DCHECK_EQ(num_syms, 1u);
@@ -308,8 +308,8 @@ std::vector<uint8_t> PackElfFileForJIT(
}
}, [&](const Reader::FDE* fde, const Reader::CIE* cie ATTRIBUTE_UNUSED) {
DCHECK(copied_cie);
- DCHECK_EQ(fde->cie_pointer, 0);
- if (!is_removed_symbol(fde->sym_addr)) {
+ DCHECK_EQ(fde->cie_pointer(), 0);
+ if (!is_removed_symbol(fde->sym_addr())) {
debug_frame->WriteFully(fde->data(), fde->size());
}
});
diff --git a/libelffile/dwarf/headers.h b/libelffile/dwarf/headers.h
index d77012ffe3..b48d089bc4 100644
--- a/libelffile/dwarf/headers.h
+++ b/libelffile/dwarf/headers.h
@@ -46,22 +46,26 @@ void WriteCIE(bool is64bit,
Writer<> writer(buffer);
size_t cie_header_start_ = writer.data()->size();
- writer.PushUint32(0); // Length placeholder.
- writer.PushUint32(0xFFFFFFFF); // CIE id.
- writer.PushUint8(1); // Version.
- writer.PushString("zR");
+ if (is64bit) {
+ writer.PushUint32(0xFFFFFFFF);
+ writer.PushUint64(0); // Length placeholder.
+ writer.PushUint64(0xFFFFFFFFFFFFFFFFull); // CIE id.
+ } else {
+ writer.PushUint32(0); // Length placeholder.
+ writer.PushUint32(0xFFFFFFFF); // CIE id.
+ }
+ writer.PushUint8(3); // Version.
+ writer.PushString(""); // Augmentation.
writer.PushUleb128(DebugFrameOpCodeWriter<Vector>::kCodeAlignmentFactor);
writer.PushSleb128(DebugFrameOpCodeWriter<Vector>::kDataAlignmentFactor);
writer.PushUleb128(return_address_register.num()); // ubyte in DWARF2.
- writer.PushUleb128(1); // z: Augmentation data size.
+ writer.PushData(opcodes.data());
+ writer.Pad(is64bit ? 8 : 4);
if (is64bit) {
- writer.PushUint8(DW_EH_PE_absptr | DW_EH_PE_udata8); // R: Pointer encoding.
+ writer.UpdateUint64(cie_header_start_ + 4, writer.data()->size() - cie_header_start_ - 12);
} else {
- writer.PushUint8(DW_EH_PE_absptr | DW_EH_PE_udata4); // R: Pointer encoding.
+ writer.UpdateUint32(cie_header_start_, writer.data()->size() - cie_header_start_ - 4);
}
- writer.PushData(opcodes.data());
- writer.Pad(is64bit ? 8 : 4);
- writer.UpdateUint32(cie_header_start_, writer.data()->size() - cie_header_start_ - 4);
}
// Write frame description entry (FDE) to .debug_frame or .eh_frame section.
@@ -74,20 +78,27 @@ void WriteFDE(bool is64bit,
/*inout*/ std::vector<uint8_t>* buffer) {
Writer<> writer(buffer);
size_t fde_header_start = writer.data()->size();
- writer.PushUint32(0); // Length placeholder.
- writer.PushUint32(cie_pointer);
// Relocate code_address if it has absolute value.
if (is64bit) {
+ writer.PushUint32(0xFFFFFFFF);
+ writer.PushUint64(0); // Length placeholder.
+ writer.PushUint64(cie_pointer);
writer.PushUint64(code_address);
writer.PushUint64(code_size);
} else {
+ writer.PushUint32(0); // Length placeholder.
+ writer.PushUint32(cie_pointer);
writer.PushUint32(code_address);
writer.PushUint32(code_size);
}
writer.PushUleb128(0); // Augmentation data size.
writer.PushData(opcodes.data(), opcodes.size());
writer.Pad(is64bit ? 8 : 4);
- writer.UpdateUint32(fde_header_start, writer.data()->size() - fde_header_start - 4);
+ if (is64bit) {
+ writer.UpdateUint64(fde_header_start + 4, writer.data()->size() - fde_header_start - 12);
+ } else {
+ writer.UpdateUint32(fde_header_start, writer.data()->size() - fde_header_start - 4);
+ }
}
// Write compilation unit (CU) to .debug_info section.
diff --git a/libelffile/elf/elf_debug_reader.h b/libelffile/elf/elf_debug_reader.h
index 266c638473..54aade7fe7 100644
--- a/libelffile/elf/elf_debug_reader.h
+++ b/libelffile/elf/elf_debug_reader.h
@@ -43,11 +43,41 @@ class ElfDebugReader {
// Call Frame Information.
struct CFI {
- uint32_t length; // Length excluding the size of this field.
- int32_t cie_pointer; // Offset in the section or -1 for CIE.
-
const uint8_t* data() const { return reinterpret_cast<const uint8_t*>(this); }
- size_t size() const { return sizeof(uint32_t) + length; }
+ const uint32_t* data_u32() const { return reinterpret_cast<const uint32_t*>(this); }
+ uint32_t* data_u32() { return reinterpret_cast<uint32_t*>(this); }
+
+ bool is_64bit() const {
+ return data_u32()[0] == 0xFFFFFFFF;
+ }
+
+ size_t size() const {
+ const uint32_t* s = data_u32();
+ if (is_64bit()) {
+ return 12 + (static_cast<uint64_t>(s[2]) << 32) + s[1];
+ }
+ return 4 + s[0];
+ }
+
+ // Offset in the section or -1 for CIE.
+ int64_t cie_pointer() const {
+ const uint32_t* s = data_u32();
+ if (is_64bit()) {
+ return static_cast<int64_t>((static_cast<uint64_t>(s[4]) << 32) + s[3]);
+ }
+ return static_cast<int32_t>(s[1]);
+ }
+
+ void set_cie_pointer(uint64_t cie_pointer) {
+ uint32_t* s = data_u32();
+ if (is_64bit()) {
+ s[3] = cie_pointer & 0xFFFFFFFF;
+ s[4] = cie_pointer >> 32;
+ } else {
+ s[1] = static_cast<uint32_t>(cie_pointer);
+ }
+ }
+
} PACKED(1);
// Common Information Entry.
@@ -56,8 +86,21 @@ class ElfDebugReader {
// Frame Description Entry.
struct FDE : public CFI {
- Elf_Addr sym_addr;
- Elf_Addr sym_size;
+ Elf_Addr sym_addr() const {
+ const uint32_t* s = this->data_u32();
+ if (this->is_64bit()) {
+ return (static_cast<uint64_t>(s[6]) << 32) + s[5];
+ }
+ return s[2];
+ }
+
+ Elf_Addr sym_size() const {
+ const uint32_t* s = this->data_u32();
+ if (this->is_64bit()) {
+ return (static_cast<uint64_t>(s[8]) << 32) + s[7];
+ }
+ return s[3];
+ }
} PACKED(1);
explicit ElfDebugReader(ArrayRef<const uint8_t> file) : file_(file) {
@@ -157,11 +200,11 @@ class ElfDebugReader {
for (size_t offset = 0; offset < debug_frame->sh_size;) {
const CFI* entry = Read<CFI>(debug_frame->sh_offset + offset);
DCHECK_LE(entry->size(), debug_frame->sh_size - offset);
- if (entry->cie_pointer == -1) {
+ if (entry->cie_pointer() == -1) {
visit_cie(Read<CIE>(debug_frame->sh_offset + offset));
} else {
const FDE* fde = Read<FDE>(debug_frame->sh_offset + offset);
- visit_fde(fde, Read<CIE>(debug_frame->sh_offset + fde->cie_pointer));
+ visit_fde(fde, Read<CIE>(debug_frame->sh_offset + fde->cie_pointer()));
}
offset += entry->size();
}
diff --git a/tools/create_minidebuginfo/create_minidebuginfo.cc b/tools/create_minidebuginfo/create_minidebuginfo.cc
index 506661a377..14cd6a8619 100644
--- a/tools/create_minidebuginfo/create_minidebuginfo.cc
+++ b/tools/create_minidebuginfo/create_minidebuginfo.cc
@@ -122,7 +122,7 @@ static void WriteMinidebugInfo(const std::vector<uint8_t>& input, std::vector<ui
const FDE* fde = entry.first;
const CIE* cie = entry.second;
FDE new_header = *fde;
- new_header.cie_pointer = new_cie_offset[cie];
+ new_header.set_cie_pointer(new_cie_offset[cie]);
debug_frame->WriteFully(&new_header, sizeof(FDE));
debug_frame->WriteFully(fde->data() + sizeof(FDE), fde->size() - sizeof(FDE));
}