summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeeraj Singh <neerajsi@microsoft.com>2021-11-30 08:01:51 (GMT)
committerNeeraj Singh <neerajsi@microsoft.com>2021-12-02 05:57:29 (GMT)
commit27a6223aecfc6914f49c13ee737c8ce59b09c55b (patch)
treee117848c288f4d46c77c8b0b7efc35bc917ef48a
parent594cf2b96458448b7bfe721bb1d9786fcf90bc0d (diff)
downloadcv2pdb-27a6223aecfc6914f49c13ee737c8ce59b09c55b.zip
cv2pdb-27a6223aecfc6914f49c13ee737c8ce59b09c55b.tar.gz
cv2pdb-27a6223aecfc6914f49c13ee737c8ce59b09c55b.tar.bz2
more pre-DWARF5 refactoring: unit headers, location cursor, range cursor
Read the compilation unit header byte-by-byte rather than by casting the data to a structure. Add the currentBaseAddress contextual info to the compilation unit data. Move the LOCCursor into readDwarf.cpp. Implement a RangeCursor similar to the LOCCursor. Add more debug printing.
-rw-r--r--src/cv2pdb.h5
-rw-r--r--src/dwarf2pdb.cpp165
-rw-r--r--src/dwarflines.cpp13
-rw-r--r--src/readDwarf.cpp112
-rw-r--r--src/readDwarf.h100
5 files changed, 243 insertions, 152 deletions
diff --git a/src/cv2pdb.h b/src/cv2pdb.h
index 1c0b3b2..4b58140 100644
--- a/src/cv2pdb.h
+++ b/src/cv2pdb.h
@@ -279,11 +279,6 @@ public:
// Default lower bound for the current compilation unit. This depends on
// the language of the current unit.
unsigned currentDefaultLowerBound;
-
- // Value of the DW_AT_low_pc attribute for the current compilation unit.
- // Specify the default base address for use in location lists and range
- // lists.
- uint32_t currentBaseAddress;
};
#endif //__CV2PDB_H__
diff --git a/src/dwarf2pdb.cpp b/src/dwarf2pdb.cpp
index 88670e2..3750702 100644
--- a/src/dwarf2pdb.cpp
+++ b/src/dwarf2pdb.cpp
@@ -419,7 +419,7 @@ public:
attr.type = ExprLoc;
attr.expr.len = LEB128(ptr);
attr.expr.ptr = ptr;
- cfa = decodeLocation(img, attr);
+ cfa = decodeLocation(attr);
ptr += attr.expr.len;
break;
}
@@ -458,7 +458,7 @@ public:
attr.type = Block;
attr.block.len = LEB128(ptr);
attr.block.ptr = ptr;
- cfa = decodeLocation(img, attr); // TODO: push cfa on stack
+ cfa = decodeLocation(attr); // TODO: push cfa on stack
ptr += attr.expr.len;
break;
}
@@ -511,61 +511,14 @@ Location findBestCFA(const PEImage& img, const CFIIndex* index, unsigned int pcl
return ebp;
}
-// Location list entry
-class LOCEntry
-{
-public:
- unsigned long beg_offset;
- unsigned long end_offset;
- Location loc;
-
- bool eol() const { return beg_offset == 0 && end_offset == 0; }
-};
-
-// Location list cursor
-class LOCCursor
-{
-public:
- LOCCursor(const PEImage& image, unsigned long off)
- : img (image)
- , end(img.debug_loc.endByte())
- , ptr(img.debug_loc.byteAt(off))
- {
- default_address_size = img.isX64() ? 8 : 4;
- }
-
- const PEImage& img;
- byte* end;
- byte* ptr;
- byte default_address_size;
-
- bool readNext(LOCEntry& entry)
- {
- if(ptr >= end)
- return false;
- entry.beg_offset = (unsigned long) RDsize(ptr, default_address_size);
- entry.end_offset = (unsigned long) RDsize(ptr, default_address_size);
- if (entry.eol())
- return true;
-
- DWARF_Attribute attr;
- attr.type = Block;
- attr.block.len = RD2(ptr);
- attr.block.ptr = ptr;
- entry.loc = decodeLocation(img, attr);
- ptr += attr.expr.len;
- return true;
- }
-};
-
Location findBestFBLoc(const DIECursor& parent, unsigned long fblocoff)
{
int regebp = parent.img->isX64() ? 6 : 5;
- LOCCursor cursor(*parent.img, fblocoff);
+ LOCCursor cursor(parent, fblocoff);
LOCEntry entry;
Location longest = { Location::RegRel, DW_REG_CFA, 0 };
unsigned long longest_range = 0;
- while(cursor.readNext(entry) && !entry.eol())
+ while(cursor.readNext(entry))
{
if(entry.loc.is_regrel() && entry.loc.reg == regebp)
return entry.loc;
@@ -745,7 +698,7 @@ bool CV2PDB::addDWARFProc(DWARF_InfoData& procid, DIECursor cursor)
addStackVar("local_var", 0x1001, 8);
#endif
- Location frameBase = decodeLocation(img, procid.frame_base, 0, DW_AT_frame_base);
+ Location frameBase = decodeLocation(procid.frame_base, 0, DW_AT_frame_base);
if (frameBase.is_abs()) // pointer into location list in .debug_loc? assume CFA
frameBase = findBestFBLoc(cursor, frameBase.off);
@@ -765,7 +718,7 @@ bool CV2PDB::addDWARFProc(DWARF_InfoData& procid, DIECursor cursor)
if (id.location.type == ExprLoc || id.location.type == Block || id.location.type == SecOffset)
{
Location loc = id.location.type == SecOffset ? findBestFBLoc(cursor, id.location.sec_offset)
- : decodeLocation(img, id.location, &frameBase);
+ : decodeLocation(id.location, &frameBase);
if (loc.is_regrel())
appendStackVar(id.name, getTypeByDWARFPtr(id.type), loc, cfa);
}
@@ -795,28 +748,12 @@ bool CV2PDB::addDWARFProc(DWARF_InfoData& procid, DIECursor cursor)
id.pchi = 0;
// TODO: handle base address selection
- byte *r = img.debug_ranges.byteAt(id.ranges);
- byte *rend = img.debug_ranges.endByte();
- while (r < rend)
+ RangeEntry range;
+ RangeCursor rangeCursor(cursor, id.ranges);
+ while (rangeCursor.readNext(range))
{
- uint64_t pclo, pchi;
-
- if (img.isX64())
- {
- pclo = RD8(r);
- pchi = RD8(r);
- }
- else
- {
- pclo = RD4(r);
- pchi = RD4(r);
- }
- if (pclo == 0 && pchi == 0)
- break;
- if (pclo >= pchi)
- continue;
- id.pclo = min(id.pclo, pclo + currentBaseAddress);
- id.pchi = max(id.pchi, pchi + currentBaseAddress);
+ id.pclo = min(id.pclo, range.pclo);
+ id.pchi = max(id.pchi, range.pchi);
}
}
@@ -836,7 +773,7 @@ bool CV2PDB::addDWARFProc(DWARF_InfoData& procid, DIECursor cursor)
if (id.name && (id.location.type == ExprLoc || id.location.type == Block))
{
Location loc = id.location.type == SecOffset ? findBestFBLoc(cursor, id.location.sec_offset)
- : decodeLocation(img, id.location, &frameBase);
+ : decodeLocation(id.location, &frameBase);
if (loc.is_regrel())
appendStackVar(id.name, getTypeByDWARFPtr(id.type), loc, cfa);
}
@@ -872,7 +809,7 @@ int CV2PDB::addDWARFFields(DWARF_InfoData& structid, DIECursor cursor, int baseo
int off = 0;
if (!isunion)
{
- Location loc = decodeLocation(img, id.member_location, 0, DW_AT_data_member_location);
+ Location loc = decodeLocation(id.member_location, 0, DW_AT_data_member_location);
if (loc.is_abs())
{
off = loc.off;
@@ -917,7 +854,7 @@ int CV2PDB::addDWARFFields(DWARF_InfoData& structid, DIECursor cursor, int baseo
else if (id.tag == DW_TAG_inheritance)
{
int off = 0;
- Location loc = decodeLocation(img, id.member_location, 0, DW_AT_data_member_location);
+ Location loc = decodeLocation(id.member_location, 0, DW_AT_data_member_location);
if (loc.is_abs())
{
cvid = S_CONSTANT_V2;
@@ -1350,11 +1287,18 @@ bool CV2PDB::mapTypes()
{
int typeID = nextUserType;
unsigned long off = 0;
+
+ if (debug & DbgBasic)
+ fprintf(stderr, "%s:%d: mapTypes()\n", __FUNCTION__, __LINE__);
+
while (off < img.debug_info.length)
{
- DWARF_CompilationUnit* cu = (DWARF_CompilationUnit*)img.debug_info.byteAt(off);
+ DWARF_CompilationUnitInfo cu{};
+ byte* ptr = cu.read(img, &off);
+ if (!ptr)
+ continue;
- DIECursor cursor(cu, (byte*)cu + sizeof(*cu));
+ DIECursor cursor(&cu, ptr);
DWARF_InfoData id;
while (cursor.readNext(id))
{
@@ -1392,8 +1336,6 @@ bool CV2PDB::mapTypes()
typeID++;
}
}
-
- off += sizeof(cu->unit_length) + cu->unit_length;
}
if (debug & DbgBasic)
@@ -1416,9 +1358,12 @@ bool CV2PDB::createTypes()
unsigned long off = 0;
while (off < img.debug_info.length)
{
- DWARF_CompilationUnit* cu = (DWARF_CompilationUnit*)img.debug_info.byteAt(off);
+ DWARF_CompilationUnitInfo cu{};
+ byte* ptr = cu.read(img, &off);
+ if (!ptr)
+ continue;
- DIECursor cursor(cu, (byte*)cu + sizeof(DWARF_CompilationUnit));
+ DIECursor cursor(&cu, ptr);
DWARF_InfoData id;
while (cursor.readNext(id))
{
@@ -1504,28 +1449,13 @@ bool CV2PDB::createTypes()
else if (id.ranges != ~0)
{
entry_point = ~0;
- byte* r = (byte*)img.debug_ranges.byteAt(id.ranges);
- byte* rend = (byte*)img.debug_ranges.endByte();
- while (r < rend)
+ RangeEntry range;
+ RangeCursor rangeCursor(cursor, id.ranges);
+ while (rangeCursor.readNext(range))
{
- uint64_t pclo, pchi;
-
- if (img.isX64())
- {
- pclo = RD8(r);
- pchi = RD8(r);
- }
- else
- {
- pclo = RD4(r);
- pchi = RD4(r);
- }
- if (pclo == 0 && pchi == 0)
- break;
- if (pclo >= pchi)
- continue;
- entry_point = min(entry_point, pclo + currentBaseAddress);
+ entry_point = min(entry_point, range.pclo);
}
+
if (entry_point == ~0)
entry_point = 0;
}
@@ -1545,7 +1475,8 @@ bool CV2PDB::createTypes()
break;
case DW_TAG_compile_unit:
- currentBaseAddress = id.pclo;
+ // Set the implicit base address for range lists.
+ cu.base_address = id.pclo;
switch (id.language)
{
case DW_LANG_Ada83:
@@ -1569,22 +1500,24 @@ bool CV2PDB::createTypes()
{
if (id.ranges > 0 && id.ranges < img.debug_ranges.length)
{
- unsigned char* r = img.debug_ranges.byteAt(id.ranges);
- unsigned char* rend = img.debug_ranges.endByte();
- while (r < rend)
+ RangeEntry range;
+ RangeCursor rangeCursor(cursor, id.ranges);
+ while (rangeCursor.readNext(range))
{
- unsigned long pclo = RD4(r);
- unsigned long pchi = RD4(r);
- if (pclo == 0 && pchi == 0)
- break;
- //printf("%s %s %x - %x\n", dir, name, pclo, pchi);
- if (!addDWARFSectionContrib(mod, pclo, pchi))
+ if (debug & DbgPdbContrib)
+ fprintf(stderr, "%s:%d: Adding a section contrib: %I64x-%I64x\n", __FUNCTION__, __LINE__,
+ range.pclo, range.pchi);
+
+ if (!addDWARFSectionContrib(mod, range.pclo, range.pchi))
return false;
}
}
else
{
- //printf("%s %s %x - %x\n", dir, name, pclo, pchi);
+ if (debug & DbgPdbContrib)
+ fprintf(stderr, "%s:%d: Adding a section contrib: %x-%x\n", __FUNCTION__, __LINE__,
+ id.pclo, id.pchi);
+
if (!addDWARFSectionContrib(mod, id.pclo, id.pchi))
return false;
}
@@ -1608,7 +1541,7 @@ bool CV2PDB::createTypes()
}
else
{
- Location loc = decodeLocation(img, id.location);
+ Location loc = decodeLocation(id.location);
if (loc.is_abs())
{
segOff = loc.off;
@@ -1647,8 +1580,6 @@ bool CV2PDB::createTypes()
assert(mapOffsetToType[id.entryPtr] == cvtype);
}
}
-
- off += sizeof(cu->unit_length) + cu->unit_length;
}
return true;
diff --git a/src/dwarflines.cpp b/src/dwarflines.cpp
index 2e0570d..dd48995 100644
--- a/src/dwarflines.cpp
+++ b/src/dwarflines.cpp
@@ -169,8 +169,13 @@ bool addLineInfo(const PEImage& img, mspdb::Mod* mod, DWARF_LineState& state)
bool interpretDWARFLines(const PEImage& img, mspdb::Mod* mod, DebugLevel debug_)
{
- DWARF_CompilationUnit* cu = (DWARF_CompilationUnit*)img.debug_info.startByte();
- int ptrsize = cu ? cu->address_size : 4;
+ DWARF_CompilationUnitInfo cu{};
+
+ if (!cu.read(img, 0)) {
+ return false;
+ }
+
+ int ptrsize = cu.address_size;
debug = debug_;
@@ -280,7 +285,7 @@ bool interpretDWARFLines(const PEImage& img, mspdb::Mod* mod, DebugLevel debug_)
{
case DW_FORM_line_strp:
{
- size_t offset = cu->isDWARF64() ? RD8(p) : RD4(p);
+ size_t offset = cu.isDWARF64() ? RD8(p) : RD4(p);
state.include_dirs.push_back((const char*)img.debug_line_str.byteAt(offset));
break;
}
@@ -322,7 +327,7 @@ bool interpretDWARFLines(const PEImage& img, mspdb::Mod* mod, DebugLevel debug_)
{
case DW_FORM_line_strp:
{
- size_t offset = cu->isDWARF64() ? RD8(p) : RD4(p);
+ size_t offset = cu.isDWARF64() ? RD8(p) : RD4(p);
fname.file_name = (const char*)img.debug_line_str.byteAt(offset);
break;
}
diff --git a/src/readDwarf.cpp b/src/readDwarf.cpp
index f712b29..12fc84d 100644
--- a/src/readDwarf.cpp
+++ b/src/readDwarf.cpp
@@ -34,6 +34,41 @@ void DIECursor::setContext(PEImage* img_, DebugLevel debug_)
debug = debug_;
}
+byte* DWARF_CompilationUnitInfo::read(const PEImage& img, unsigned long *off)
+{
+ byte* ptr = img.debug_info.byteAt(*off);
+
+ start_ptr = ptr;
+ cu_offset = *off;
+ is_dwarf64 = false;
+ base_address = 0;
+ unit_length = RD4(ptr);
+ if (unit_length == ~0) {
+ // DWARF64 doesn't make sense in the context of the PE format since the
+ // section size is limited to 32 bits.
+ fprintf(stderr, "%s:%d: WARNING: DWARF64 compilation unit at offset=%x is not supported\n", __FUNCTION__, __LINE__,
+ cu_offset);
+
+ uint64_t len64 = RD8(ptr);
+ *off = img.debug_info.sectOff(ptr + (intptr_t)len64);
+ return nullptr;
+ }
+
+ end_ptr = ptr + unit_length;
+ *off = img.debug_info.sectOff(end_ptr);
+ version = RD2(ptr);
+ if (version >= 5) {
+ fprintf(stderr, "%s:%d: WARNING: Unsupported dwarf version %d for compilation unit at offset=%x\n", __FUNCTION__, __LINE__,
+ version, cu_offset);
+
+ return nullptr;
+ }
+
+ debug_abbrev_offset = RD4(ptr);
+ address_size = *ptr++;
+ return ptr;
+}
+
static Location mkInReg(unsigned reg)
{
Location l;
@@ -61,7 +96,7 @@ static Location mkRegRel(int reg, int off)
return l;
}
-Location decodeLocation(const PEImage& img, const DWARF_Attribute& attr, const Location* frameBase, int at)
+Location decodeLocation(const DWARF_Attribute& attr, const Location* frameBase, int at)
{
static Location invalid = { Location::Invalid };
@@ -343,7 +378,66 @@ void mergeSpecification(DWARF_InfoData& id, const DIECursor& parent)
id.merge(idspec);
}
-DIECursor::DIECursor(DWARF_CompilationUnit* cu_, byte* ptr_)
+LOCCursor::LOCCursor(const DIECursor& parent, unsigned long off)
+ : parent(parent)
+ , end(parent.img->debug_loc.endByte())
+ , ptr(parent.img->debug_loc.byteAt(off))
+{
+}
+
+bool LOCCursor::readNext(LOCEntry& entry)
+{
+ if (ptr >= end)
+ return false;
+
+ if (parent.debug & DbgDwarfLocLists)
+ fprintf(stderr, "%s:%d: loclist off=%x DIEoff=%x:\n", __FUNCTION__, __LINE__,
+ parent.img->debug_loc.sectOff(ptr), parent.entryOff);
+
+ entry.beg_offset = (unsigned long) parent.RDAddr(ptr);
+ entry.end_offset = (unsigned long) parent.RDAddr(ptr);
+ if (!entry.beg_offset && !entry.end_offset)
+ return false;
+
+ DWARF_Attribute attr;
+ attr.type = Block;
+ attr.block.len = RD2(ptr);
+ attr.block.ptr = ptr;
+ entry.loc = decodeLocation(attr);
+ ptr += attr.expr.len;
+ return true;
+}
+
+RangeCursor::RangeCursor(const DIECursor& parent, unsigned long off)
+ : parent(parent)
+ , end(parent.img->debug_ranges.endByte())
+ , ptr(parent.img->debug_ranges.byteAt(off))
+{
+}
+
+bool RangeCursor::readNext(RangeEntry& entry)
+{
+ while (ptr < end) {
+ if (parent.debug & DbgDwarfRangeLists)
+ fprintf(stderr, "%s:%d: rangelist off=%x DIEoff=%x:\n", __FUNCTION__, __LINE__,
+ parent.img->debug_ranges.sectOff(ptr), parent.entryOff);
+
+ entry.pclo = parent.RDAddr(ptr);
+ entry.pchi = parent.RDAddr(ptr);
+ if (!entry.pclo && !entry.pchi)
+ return false;
+
+ if (entry.pclo >= entry.pchi)
+ continue;
+
+ entry.addBase(parent.cu->base_address);
+ return true;
+ }
+
+ return false;
+}
+
+DIECursor::DIECursor(DWARF_CompilationUnitInfo* cu_, byte* ptr_)
{
cu = cu_;
ptr = ptr_;
@@ -414,7 +508,7 @@ bool DIECursor::readNext(DWARF_InfoData& id, bool stopAtNull)
if (level == -1)
return false; // we were already at the end of the subtree
- if (ptr >= ((byte*)cu + sizeof(cu->unit_length) + cu->unit_length))
+ if (ptr >= cu->end_ptr)
return false; // root of the tree does not have a null terminator, but we know the length
id.entryPtr = ptr;
@@ -447,7 +541,7 @@ bool DIECursor::readNext(DWARF_InfoData& id, bool stopAtNull)
id.hasChild = *abbrev++;
if (debug & DbgDwarfAttrRead)
- fprintf(stderr, "%s:%d: offs=%d level=%d tag=%d abbrev=%d\n", __FUNCTION__, __LINE__,
+ fprintf(stderr, "%s:%d: offs=%x level=%d tag=%d abbrev=%d\n", __FUNCTION__, __LINE__,
entryOff, level, id.tag, id.code);
int attr, form;
@@ -488,11 +582,11 @@ bool DIECursor::readNext(DWARF_InfoData& id, bool stopAtNull)
case DW_FORM_strp: a.type = String; a.string = (const char*)img->debug_str.byteAt(RDsize(ptr, cu->isDWARF64() ? 8 : 4)); break;
case DW_FORM_flag: a.type = Flag; a.flag = (*ptr++ != 0); break;
case DW_FORM_flag_present: a.type = Flag; a.flag = true; break;
- case DW_FORM_ref1: a.type = Ref; a.ref = (byte*)cu + *ptr++; break;
- case DW_FORM_ref2: a.type = Ref; a.ref = (byte*)cu + RD2(ptr); break;
- case DW_FORM_ref4: a.type = Ref; a.ref = (byte*)cu + RD4(ptr); break;
- case DW_FORM_ref8: a.type = Ref; a.ref = (byte*)cu + RD8(ptr); break;
- case DW_FORM_ref_udata: a.type = Ref; a.ref = (byte*)cu + LEB128(ptr); break;
+ case DW_FORM_ref1: a.type = Ref; a.ref = cu->start_ptr + *ptr++; break;
+ case DW_FORM_ref2: a.type = Ref; a.ref = cu->start_ptr + RD2(ptr); break;
+ case DW_FORM_ref4: a.type = Ref; a.ref = cu->start_ptr + RD4(ptr); break;
+ case DW_FORM_ref8: a.type = Ref; a.ref = cu->start_ptr + RD8(ptr); break;
+ case DW_FORM_ref_udata: a.type = Ref; a.ref = cu->start_ptr + LEB128(ptr); break;
case DW_FORM_ref_addr: a.type = Ref; a.ref = img->debug_info.byteAt(cu->isDWARF64() ? RD8(ptr) : RD4(ptr)); break;
case DW_FORM_ref_sig8: a.type = Invalid; ptr += 8; break;
case DW_FORM_exprloc: a.type = ExprLoc; a.expr.len = LEB128(ptr); a.expr.ptr = ptr; ptr += a.expr.len; break;
diff --git a/src/readDwarf.h b/src/readDwarf.h
index bb78285..3bc7d09 100644
--- a/src/readDwarf.h
+++ b/src/readDwarf.h
@@ -17,10 +17,12 @@ enum DebugLevel : unsigned {
DbgPdbTypes = 0x2,
DbgPdbSyms = 0x4,
DbgPdbLines = 0x8,
- DbgDwarfTagRead = 0x10,
- DbgDwarfAttrRead = 0x20,
- DbgDwarfLocLists = 0x40,
- DbgDwarfLines = 0x80
+ DbgPdbContrib = 0x10,
+ DbgDwarfTagRead = 0x100,
+ DbgDwarfAttrRead = 0x200,
+ DbgDwarfLocLists = 0x400,
+ DbgDwarfRangeLists = 0x800,
+ DbgDwarfLines = 0x1000
};
DEFINE_ENUM_FLAG_OPERATORS(DebugLevel);
@@ -57,7 +59,7 @@ inline int SLEB128(byte* &p)
return x;
}
-inline unsigned int RD2(byte* &p)
+inline unsigned short RD2(byte* &p)
{
unsigned int x = *p++;
x |= *p++ << 8;
@@ -122,17 +124,30 @@ struct DWARF_Attribute
///////////////////////////////////////////////////////////////////////////////
-#include "pshpack1.h"
-
-struct DWARF_CompilationUnit
+struct DWARF_CompilationUnitInfo
{
- unsigned int unit_length; // 12 byte in DWARF-64
+ uint32_t unit_length; // 12 byte in DWARF-64
unsigned short version;
- unsigned int debug_abbrev_offset; // 8 byte in DWARF-64
byte address_size;
+ byte unit_type;
+ unsigned int debug_abbrev_offset; // 8 byte in DWARF-64
- bool isDWARF64() const { return unit_length == ~0; }
- int refSize() const { return unit_length == ~0 ? 8 : 4; }
+ // Value of the DW_AT_low_pc attribute for the current compilation unit.
+ // Specify the default base address for use in location lists and range
+ // lists.
+ uint32_t base_address;
+
+ // Offset within the debug_info section
+ uint32_t cu_offset;
+ byte* start_ptr;
+ byte* end_ptr;
+
+ bool is_dwarf64;
+
+ byte* read(const PEImage& img, unsigned long *off);
+
+ bool isDWARF64() const { return is_dwarf64; }
+ int refSize() const { return isDWARF64() ? 8 : 4; }
};
struct DWARF_FileName
@@ -260,6 +275,8 @@ struct DWARF_TypeForm
unsigned int type, form;
};
+#include "pshpack1.h"
+
struct DWARF_LineNumberProgramHeader
{
unsigned int unit_length; // 12 byte in DWARF-64
@@ -310,6 +327,8 @@ struct DWARF2_LineNumberProgramHeader
// DWARF_FileNames file_names[] // zero byte terminated
};
+#include "poppack.h"
+
struct DWARF_LineState
{
// hdr info
@@ -372,7 +391,6 @@ struct DWARF_LineState
}
};
-#include "poppack.h"
///////////////////////////////////////////////////////////////////////////////
@@ -398,13 +416,61 @@ struct Location
bool is_regrel() const { return type == RegRel; }
};
-typedef std::unordered_map<std::pair<unsigned, unsigned>, byte*> abbrevMap_t;
+// Location list entry
+class LOCEntry
+{
+public:
+ unsigned long beg_offset;
+ unsigned long end_offset;
+ Location loc;
+};
+// Location list cursor
+class LOCCursor
+{
+public:
+ LOCCursor(const DIECursor& parent, unsigned long off);
+
+ const DIECursor& parent;
+ byte* end;
+ byte* ptr;
+
+ bool readNext(LOCEntry& entry);
+};
+
+// Range list entry
+class RangeEntry
+{
+public:
+ uint64_t pclo;
+ uint64_t pchi;
+
+ void addBase(uint64_t base)
+ {
+ pclo += base;
+ pchi += base;
+ }
+};
+
+// Range list cursor
+class RangeCursor
+{
+public:
+ RangeCursor(const DIECursor& parent, unsigned long off);
+
+ const DIECursor& parent;
+ byte *end;
+ byte *ptr;
+
+ bool readNext(RangeEntry& entry);
+};
+
+typedef std::unordered_map<std::pair<unsigned, unsigned>, byte*> abbrevMap_t;
// Attempts to partially evaluate DWARF location expressions.
// The only supported expressions are those, whose result may be represented
// as either an absolute value, a register, or a register-relative address.
-Location decodeLocation(const PEImage& img, const DWARF_Attribute& attr, const Location* frameBase = 0, int at = 0);
+Location decodeLocation(const DWARF_Attribute& attr, const Location* frameBase = 0, int at = 0);
void mergeAbstractOrigin(DWARF_InfoData& id, const DIECursor& parent);
void mergeSpecification(DWARF_InfoData& id, const DIECursor& parent);
@@ -413,7 +479,7 @@ void mergeSpecification(DWARF_InfoData& id, const DIECursor& parent);
class DIECursor
{
public:
- DWARF_CompilationUnit* cu;
+ DWARF_CompilationUnitInfo* cu;
byte* ptr;
unsigned int entryOff;
int level;
@@ -431,7 +497,7 @@ public:
static void setContext(PEImage* img_, DebugLevel debug_);
// Create a new DIECursor
- DIECursor(DWARF_CompilationUnit* cu_, byte* ptr);
+ DIECursor(DWARF_CompilationUnitInfo* cu_, byte* ptr);
// Create a child DIECursor
DIECursor(const DIECursor& parent, byte* ptr_);