[PATCH] Initial DWARF64 support for .debug_line
Ed Maste
emaste at freebsd.org
Mon Oct 21 09:22:50 PDT 2013
Other DWARF sections still need to be done, as well as 64-bit offsets in DataExtractor also needed (as described DebugFrame).
http://llvm.org/bugs/show_bug.cgi?id=17411
http://llvm-reviews.chandlerc.com/D1988
Files:
lib/DebugInfo/DWARFDebugLine.cpp
lib/DebugInfo/DWARFDebugLine.h
Index: lib/DebugInfo/DWARFDebugLine.cpp
===================================================================
--- lib/DebugInfo/DWARFDebugLine.cpp
+++ lib/DebugInfo/DWARFDebugLine.cpp
@@ -18,9 +18,9 @@
void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const {
OS << "Line table prologue:\n"
- << format(" total_length: 0x%8.8x\n", TotalLength)
+ << format(" total_length: 0x%8.8" PRIx64 "\n", TotalLength)
<< format(" version: %u\n", Version)
- << format("prologue_length: 0x%8.8x\n", PrologueLength)
+ << format("prologue_length: 0x%8.8" PRIx64 "\n", PrologueLength)
<< format("min_inst_length: %u\n", MinInstLength)
<< format("default_is_stmt: %u\n", DefaultIsStmt)
<< format(" line_base: %i\n", LineBase)
@@ -165,16 +165,23 @@
bool
DWARFDebugLine::parsePrologue(DataExtractor debug_line_data,
uint32_t *offset_ptr, Prologue *prologue) {
- const uint32_t prologue_offset = *offset_ptr;
+ const uint64_t prologue_offset = *offset_ptr;
prologue->clear();
prologue->TotalLength = debug_line_data.getU32(offset_ptr);
+ if (prologue->TotalLength == UINT32_MAX) {
+ prologue->IsDWARF64 = true;
+ prologue->TotalLength = debug_line_data.getU64(offset_ptr);
+ } else if (prologue->TotalLength >= 0xffffff00) {
+ return false;
+ }
prologue->Version = debug_line_data.getU16(offset_ptr);
if (prologue->Version != 2)
return false;
- prologue->PrologueLength = debug_line_data.getU32(offset_ptr);
- const uint32_t end_prologue_offset = prologue->PrologueLength + *offset_ptr;
+ prologue->PrologueLength = debug_line_data.getUnsigned(offset_ptr,
+ prologue->sizeofPrologueLength());
+ const uint64_t end_prologue_offset = prologue->PrologueLength + *offset_ptr;
prologue->MinInstLength = debug_line_data.getU8(offset_ptr);
prologue->DefaultIsStmt = debug_line_data.getU8(offset_ptr);
prologue->LineBase = debug_line_data.getU8(offset_ptr);
@@ -209,10 +216,15 @@
}
}
- if (*offset_ptr != end_prologue_offset) {
- fprintf(stderr, "warning: parsing line table prologue at 0x%8.8x should"
- " have ended at 0x%8.8x but it ended at 0x%8.8x\n",
- prologue_offset, end_prologue_offset, *offset_ptr);
+ if (prologue->IsDWARF64 && end_prologue_offset - *offset_ptr == 12) {
+ fprintf(stderr, "warning: apparent 64-bit DWARF GNU as prologue length bug"
+ " detected (prologue length 12 bytes too long)\n");
+ // Could correct the field: prologue->PrologueLength -= 12;
+ } else if (*offset_ptr != end_prologue_offset) {
+ fprintf(stderr, "warning: parsing line table prologue at 0x%8.8" PRIx64
+ " should have ended at 0x%8.8" PRIx64
+ " but it ended at 0x%8.8" PRIx64 "\n",
+ prologue_offset, end_prologue_offset, (uint64_t)*offset_ptr);
return false;
}
return true;
@@ -233,7 +245,7 @@
}
const uint32_t end_offset = debug_line_offset + prologue->TotalLength +
- sizeof(prologue->TotalLength);
+ prologue->sizeofTotalLength();
state.reset();
Index: lib/DebugInfo/DWARFDebugLine.h
===================================================================
--- lib/DebugInfo/DWARFDebugLine.h
+++ lib/DebugInfo/DWARFDebugLine.h
@@ -34,17 +34,20 @@
struct Prologue {
Prologue()
- : TotalLength(0), Version(0), PrologueLength(0), MinInstLength(0),
- DefaultIsStmt(0), LineBase(0), LineRange(0), OpcodeBase(0) {}
+ : IsDWARF64(0), TotalLength(0), Version(0), PrologueLength(0),
+ MinInstLength(0), DefaultIsStmt(0), LineBase(0), LineRange(0),
+ OpcodeBase(0) {}
+ // Prologue represents 64-bit DWARF
+ bool IsDWARF64;
// The size in bytes of the statement information for this compilation unit
// (not including the total_length field itself).
- uint32_t TotalLength;
+ uint64_t TotalLength;
// Version identifier for the statement information format.
uint16_t Version;
// The number of bytes following the prologue_length field to the beginning
// of the first byte of the statement program itself.
- uint32_t PrologueLength;
+ uint64_t PrologueLength;
// The size in bytes of the smallest target machine instruction. Statement
// program opcodes that alter the address register first multiply their
// operands by this value.
@@ -61,20 +64,28 @@
std::vector<const char*> IncludeDirectories;
std::vector<FileNameEntry> FileNames;
+ uint32_t sizeofTotalLength() const {
+ return IsDWARF64 ? 12 : 4;
+ }
+ uint32_t sizeofPrologueLength() const {
+ return IsDWARF64 ? 8 : 4;
+ }
+
// Length of the prologue in bytes.
uint32_t getLength() const {
- return PrologueLength + sizeof(TotalLength) + sizeof(Version) +
- sizeof(PrologueLength);
+ return PrologueLength + sizeofTotalLength() + sizeof(Version) +
+ sizeofPrologueLength();
}
// Length of the line table data in bytes (not including the prologue).
uint32_t getStatementTableLength() const {
- return TotalLength + sizeof(TotalLength) - getLength();
+ return TotalLength + sizeofTotalLength() - getLength();
}
int32_t getMaxLineIncrementForSpecialOpcode() const {
return LineBase + (int8_t)LineRange - 1;
}
void dump(raw_ostream &OS) const;
void clear() {
+ IsDWARF64 = false;
TotalLength = Version = PrologueLength = 0;
MinInstLength = LineBase = LineRange = OpcodeBase = 0;
StandardOpcodeLengths.clear();
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1988.1.patch
Type: text/x-patch
Size: 5690 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131021/7c1b74ea/attachment.bin>
More information about the llvm-commits
mailing list