summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeeraj Singh <neerajsi@microsoft.com>2021-11-30 05:03:58 (GMT)
committerNeeraj Singh <neerajsi@microsoft.com>2021-12-02 05:50:55 (GMT)
commit594cf2b96458448b7bfe721bb1d9786fcf90bc0d (patch)
tree5ac177e11023451c8ab8c511dffb4dd204ee57ff
parent28d3fad41817310b8fc2fd6d9e46137249d65fad (diff)
downloadcv2pdb-594cf2b96458448b7bfe721bb1d9786fcf90bc0d.zip
cv2pdb-594cf2b96458448b7bfe721bb1d9786fcf90bc0d.tar.gz
cv2pdb-594cf2b96458448b7bfe721bb1d9786fcf90bc0d.tar.bz2
carry contextual information with the DIECursor
DWARF5 has more contextual information that is associated with the compilation unit. As a preparation for using such information, carry it with the DIECursor and eliminate places where we're passing in the parent compilation unit. Also add the RDAddr helper to read a target-address according to the specification in the compilation unit.
-rw-r--r--src/cv2pdb.h19
-rw-r--r--src/dwarf2pdb.cpp108
-rw-r--r--src/readDwarf.cpp21
-rw-r--r--src/readDwarf.h20
4 files changed, 91 insertions, 77 deletions
diff --git a/src/cv2pdb.h b/src/cv2pdb.h
index 26b2143..1c0b3b2 100644
--- a/src/cv2pdb.h
+++ b/src/cv2pdb.h
@@ -15,7 +15,6 @@
#include <windows.h>
#include <map>
-#include <unordered_map>
extern "C" {
#include "mscvpdb.h"
@@ -172,17 +171,17 @@ public:
bool writeDWARFImage(const TCHAR* opath);
bool addDWARFSectionContrib(mspdb::Mod* mod, unsigned long pclo, unsigned long pchi);
- bool addDWARFProc(DWARF_InfoData& id, DWARF_CompilationUnit* cu, DIECursor cursor);
- int addDWARFStructure(DWARF_InfoData& id, DWARF_CompilationUnit* cu, DIECursor cursor);
- int addDWARFFields(DWARF_InfoData& structid, DWARF_CompilationUnit* cu, DIECursor cursor, int off);
- int addDWARFArray(DWARF_InfoData& arrayid, DWARF_CompilationUnit* cu, DIECursor cursor);
+ bool addDWARFProc(DWARF_InfoData& id, DIECursor cursor);
+ int addDWARFStructure(DWARF_InfoData& id, DIECursor cursor);
+ int addDWARFFields(DWARF_InfoData& structid, DIECursor cursor, int off);
+ int addDWARFArray(DWARF_InfoData& arrayid, DIECursor cursor);
int addDWARFBasicType(const char*name, int encoding, int byte_size);
- int addDWARFEnum(DWARF_InfoData& enumid, DWARF_CompilationUnit* cu, DIECursor cursor);
- int getTypeByDWARFPtr(DWARF_CompilationUnit* cu, byte* ptr);
- int getDWARFTypeSize(DWARF_CompilationUnit* cu, byte* ptr);
- void getDWARFArrayBounds(DWARF_InfoData& arrayid, DWARF_CompilationUnit* cu, DIECursor cursor,
+ int addDWARFEnum(DWARF_InfoData& enumid, DIECursor cursor);
+ int getTypeByDWARFPtr(byte* ptr);
+ int getDWARFTypeSize(const DIECursor& parent, byte* ptr);
+ void getDWARFArrayBounds(DWARF_InfoData& arrayid, DIECursor cursor,
int& basetype, int& lowerBound, int& upperBound);
- void getDWARFSubrangeInfo(DWARF_InfoData& subrangeid, DWARF_CompilationUnit* cu,
+ void getDWARFSubrangeInfo(DWARF_InfoData& subrangeid, const DIECursor& parent,
int& basetype, int& lowerBound, int& upperBound);
int getDWARFBasicType(int encoding, int byte_size);
diff --git a/src/dwarf2pdb.cpp b/src/dwarf2pdb.cpp
index f58067d..88670e2 100644
--- a/src/dwarf2pdb.cpp
+++ b/src/dwarf2pdb.cpp
@@ -558,10 +558,10 @@ public:
}
};
-Location findBestFBLoc(const PEImage& img, unsigned long fblocoff)
+Location findBestFBLoc(const DIECursor& parent, unsigned long fblocoff)
{
- int regebp = img.isX64() ? 6 : 5;
- LOCCursor cursor(img, fblocoff);
+ int regebp = parent.img->isX64() ? 6 : 5;
+ LOCCursor cursor(*parent.img, fblocoff);
LOCEntry entry;
Location longest = { Location::RegRel, DW_REG_CFA, 0 };
unsigned long longest_range = 0;
@@ -690,7 +690,7 @@ void CV2PDB::appendLexicalBlock(DWARF_InfoData& id, unsigned int proclo)
cbUdtSymbols += len;
}
-bool CV2PDB::addDWARFProc(DWARF_InfoData& procid, DWARF_CompilationUnit* cu, DIECursor cursor)
+bool CV2PDB::addDWARFProc(DWARF_InfoData& procid, DIECursor cursor)
{
unsigned int pclo = procid.pclo - codeSegOff;
unsigned int pchi = procid.pchi - codeSegOff;
@@ -747,11 +747,11 @@ bool CV2PDB::addDWARFProc(DWARF_InfoData& procid, DWARF_CompilationUnit* cu, DIE
Location frameBase = decodeLocation(img, procid.frame_base, 0, DW_AT_frame_base);
if (frameBase.is_abs()) // pointer into location list in .debug_loc? assume CFA
- frameBase = findBestFBLoc(img, frameBase.off);
+ frameBase = findBestFBLoc(cursor, frameBase.off);
Location cfa = findBestCFA(img, cfi_index, procid.pclo, procid.pchi);
- if (cu)
+ if (cursor.cu)
{
bool endarg = false;
DWARF_InfoData id;
@@ -764,10 +764,10 @@ bool CV2PDB::addDWARFProc(DWARF_InfoData& procid, DWARF_CompilationUnit* cu, DIE
{
if (id.location.type == ExprLoc || id.location.type == Block || id.location.type == SecOffset)
{
- Location loc = id.location.type == SecOffset ? findBestFBLoc(img, id.location.sec_offset)
+ Location loc = id.location.type == SecOffset ? findBestFBLoc(cursor, id.location.sec_offset)
: decodeLocation(img, id.location, &frameBase);
if (loc.is_regrel())
- appendStackVar(id.name, getTypeByDWARFPtr(cu, id.type), loc, cfa);
+ appendStackVar(id.name, getTypeByDWARFPtr(id.type), loc, cfa);
}
}
}
@@ -835,10 +835,10 @@ bool CV2PDB::addDWARFProc(DWARF_InfoData& procid, DWARF_CompilationUnit* cu, DIE
{
if (id.name && (id.location.type == ExprLoc || id.location.type == Block))
{
- Location loc = id.location.type == SecOffset ? findBestFBLoc(img, id.location.sec_offset)
+ Location loc = id.location.type == SecOffset ? findBestFBLoc(cursor, id.location.sec_offset)
: decodeLocation(img, id.location, &frameBase);
if (loc.is_regrel())
- appendStackVar(id.name, getTypeByDWARFPtr(cu, id.type), loc, cfa);
+ appendStackVar(id.name, getTypeByDWARFPtr(id.type), loc, cfa);
}
}
cursor.gotoSibling();
@@ -855,7 +855,7 @@ bool CV2PDB::addDWARFProc(DWARF_InfoData& procid, DWARF_CompilationUnit* cu, DIE
return true;
}
-int CV2PDB::addDWARFFields(DWARF_InfoData& structid, DWARF_CompilationUnit* cu, DIECursor cursor, int baseoff)
+int CV2PDB::addDWARFFields(DWARF_InfoData& structid, DIECursor cursor, int baseoff)
{
bool isunion = structid.tag == DW_TAG_union_type;
int nfields = 0;
@@ -886,20 +886,20 @@ int CV2PDB::addDWARFFields(DWARF_InfoData& structid, DWARF_CompilationUnit* cu,
{
checkDWARFTypeAlloc(kMaxNameLen + 100);
codeview_fieldtype* dfieldtype = (codeview_fieldtype*)(dwarfTypes + cbDwarfTypes);
- cbDwarfTypes += addFieldMember(dfieldtype, 0, baseoff + off, getTypeByDWARFPtr(cu, id.type), id.name);
+ cbDwarfTypes += addFieldMember(dfieldtype, 0, baseoff + off, getTypeByDWARFPtr(id.type), id.name);
nfields++;
}
else if (id.type)
{
// if it doesn't have a name, and it's a struct or union, embed it directly
- DIECursor membercursor(cu, id.type);
+ DIECursor membercursor(cursor, id.type);
DWARF_InfoData memberid;
if (membercursor.readNext(memberid))
{
if (memberid.abstract_origin)
- mergeAbstractOrigin(memberid, cu);
+ mergeAbstractOrigin(memberid, cursor);
if (memberid.specification)
- mergeSpecification(memberid, cu);
+ mergeSpecification(memberid, cursor);
int cvtype = -1;
switch (memberid.tag)
@@ -907,7 +907,7 @@ int CV2PDB::addDWARFFields(DWARF_InfoData& structid, DWARF_CompilationUnit* cu,
case DW_TAG_class_type:
case DW_TAG_structure_type:
case DW_TAG_union_type:
- nfields += addDWARFFields(memberid, cu, membercursor, baseoff + off);
+ nfields += addDWARFFields(memberid, membercursor, baseoff + off);
break;
}
}
@@ -929,7 +929,7 @@ int CV2PDB::addDWARFFields(DWARF_InfoData& structid, DWARF_CompilationUnit* cu,
codeview_fieldtype* bc = (codeview_fieldtype*)(dwarfTypes + cbDwarfTypes);
bc->bclass_v2.id = LF_BCLASS_V2;
bc->bclass_v2.offset = baseoff + off;
- bc->bclass_v2.type = getTypeByDWARFPtr(cu, id.type);
+ bc->bclass_v2.type = getTypeByDWARFPtr(id.type);
bc->bclass_v2.attribute = 3; // public
cbDwarfTypes += sizeof(bc->bclass_v2);
for (; cbDwarfTypes & 3; cbDwarfTypes++)
@@ -942,13 +942,13 @@ int CV2PDB::addDWARFFields(DWARF_InfoData& structid, DWARF_CompilationUnit* cu,
return nfields;
}
-int CV2PDB::addDWARFStructure(DWARF_InfoData& structid, DWARF_CompilationUnit* cu, DIECursor cursor)
+int CV2PDB::addDWARFStructure(DWARF_InfoData& structid, DIECursor cursor)
{
//printf("Adding struct %s, entryoff %d, abbrev %d\n", structid.name, structid.entryOff, structid.abbrev);
int fieldlistType = 0;
int nfields = 0;
- if (cu)
+ if (cursor.cu)
{
checkDWARFTypeAlloc(100);
codeview_reftype* fl = (codeview_reftype*) (dwarfTypes + cbDwarfTypes);
@@ -970,7 +970,7 @@ int CV2PDB::addDWARFStructure(DWARF_InfoData& structid, DWARF_CompilationUnit* c
nfields++;
}
#endif
- nfields += addDWARFFields(structid, cu, cursor, 0);
+ nfields += addDWARFFields(structid, cursor, 0);
fl = (codeview_reftype*) (dwarfTypes + flbegin);
fl->fieldlist.len = cbDwarfTypes - flbegin - 2;
fieldlistType = nextDwarfType++;
@@ -990,19 +990,18 @@ int CV2PDB::addDWARFStructure(DWARF_InfoData& structid, DWARF_CompilationUnit* c
return cvtype;
}
-void CV2PDB::getDWARFArrayBounds(DWARF_InfoData& arrayid, DWARF_CompilationUnit* cu,
- DIECursor cursor, int& basetype, int& lowerBound, int& upperBound)
+void CV2PDB::getDWARFArrayBounds(DWARF_InfoData& arrayid, DIECursor cursor, int& basetype, int& lowerBound, int& upperBound)
{
DWARF_InfoData id;
// TODO: handle multi-dimensional arrays
- if (cu)
+ if (cursor.cu)
{
while (cursor.readNext(id, true))
{
if (id.tag == DW_TAG_subrange_type)
{
- getDWARFSubrangeInfo(id, cu, basetype, lowerBound, upperBound);
+ getDWARFSubrangeInfo(id, cursor, basetype, lowerBound, upperBound);
return;
}
cursor.gotoSibling();
@@ -1010,10 +1009,10 @@ void CV2PDB::getDWARFArrayBounds(DWARF_InfoData& arrayid, DWARF_CompilationUnit*
}
// In case of error, return plausible defaults
- getDWARFSubrangeInfo(id, NULL, basetype, lowerBound, upperBound);
+ getDWARFSubrangeInfo(id, cursor, basetype, lowerBound, upperBound);
}
-void CV2PDB::getDWARFSubrangeInfo(DWARF_InfoData& subrangeid, DWARF_CompilationUnit* cu,
+void CV2PDB::getDWARFSubrangeInfo(DWARF_InfoData& subrangeid, const DIECursor& parent,
int& basetype, int& lowerBound, int& upperBound)
{
// In case of error, return plausible defaults. Assume the array
@@ -1022,10 +1021,10 @@ void CV2PDB::getDWARFSubrangeInfo(DWARF_InfoData& subrangeid, DWARF_CompilationU
lowerBound = currentDefaultLowerBound;
upperBound = lowerBound;
- if (!cu || subrangeid.tag != DW_TAG_subrange_type)
+ if (!parent.cu || subrangeid.tag != DW_TAG_subrange_type)
return;
- basetype = getTypeByDWARFPtr(cu, subrangeid.type);
+ basetype = getTypeByDWARFPtr(subrangeid.type);
if (subrangeid.has_lower_bound)
lowerBound = subrangeid.lower_bound;
upperBound = subrangeid.upper_bound;
@@ -1093,20 +1092,19 @@ int CV2PDB::getDWARFBasicType(int encoding, int byte_size)
return translateType(t);
}
-int CV2PDB::addDWARFArray(DWARF_InfoData& arrayid, DWARF_CompilationUnit* cu,
- DIECursor cursor)
+int CV2PDB::addDWARFArray(DWARF_InfoData& arrayid, DIECursor cursor)
{
int basetype, upperBound, lowerBound;
- getDWARFArrayBounds(arrayid, cu, cursor, basetype, lowerBound, upperBound);
+ getDWARFArrayBounds(arrayid, cursor, basetype, lowerBound, upperBound);
checkUserTypeAlloc(kMaxNameLen + 100);
codeview_type* cvt = (codeview_type*) (userTypes + cbUserTypes);
cvt->array_v2.id = v3 ? LF_ARRAY_V3 : LF_ARRAY_V2;
- cvt->array_v2.elemtype = getTypeByDWARFPtr(cu, arrayid.type);
+ cvt->array_v2.elemtype = getTypeByDWARFPtr(arrayid.type);
cvt->array_v2.idxtype = basetype;
int len = (BYTE*)&cvt->array_v2.arrlen - (BYTE*)cvt;
- int size = (upperBound - lowerBound + 1) * getDWARFTypeSize(cu, arrayid.type);
+ int size = (upperBound - lowerBound + 1) * getDWARFTypeSize(cursor, arrayid.type);
len += write_numeric_leaf(size, &cvt->array_v2.arrlen);
((BYTE*)cvt)[len++] = 0; // empty name
for (; len & 3; len++)
@@ -1190,7 +1188,7 @@ int CV2PDB::addDWARFBasicType(const char*name, int encoding, int byte_size)
return cvtype;
}
-int CV2PDB::addDWARFEnum(DWARF_InfoData& enumid, DWARF_CompilationUnit* cu, DIECursor cursor)
+int CV2PDB::addDWARFEnum(DWARF_InfoData& enumid, DIECursor cursor)
{
/* Enumerated types are described in CodeView with two components:
@@ -1298,7 +1296,7 @@ int CV2PDB::addDWARFEnum(DWARF_InfoData& enumid, DWARF_CompilationUnit* cu, DIEC
/* Now the LF_FIELDLIST is ready, create the LF_ENUM type record itself. */
checkUserTypeAlloc();
int basetype = (enumid.type != 0)
- ? getTypeByDWARFPtr(cu, enumid.type)
+ ? getTypeByDWARFPtr(enumid.type)
: getDWARFBasicType(enumid.encoding, enumid.byte_size);
dtype = (codeview_type*)(userTypes + cbUserTypes);
const char* name = (enumid.name ? enumid.name : "__noname");
@@ -1309,7 +1307,7 @@ int CV2PDB::addDWARFEnum(DWARF_InfoData& enumid, DWARF_CompilationUnit* cu, DIEC
return enumType;
}
-int CV2PDB::getTypeByDWARFPtr(DWARF_CompilationUnit* cu, byte* ptr)
+int CV2PDB::getTypeByDWARFPtr(byte* ptr)
{
std::unordered_map<byte*, int>::iterator it = mapOffsetToType.find(ptr);
if(it == mapOffsetToType.end())
@@ -1317,10 +1315,10 @@ int CV2PDB::getTypeByDWARFPtr(DWARF_CompilationUnit* cu, byte* ptr)
return it->second;
}
-int CV2PDB::getDWARFTypeSize(DWARF_CompilationUnit* cu, byte* typePtr)
+int CV2PDB::getDWARFTypeSize(const DIECursor& parent, byte* typePtr)
{
DWARF_InfoData id;
- DIECursor cursor(cu, typePtr);
+ DIECursor cursor(parent, typePtr);
if (!cursor.readNext(id))
return 0;
@@ -1333,16 +1331,16 @@ int CV2PDB::getDWARFTypeSize(DWARF_CompilationUnit* cu, byte* typePtr)
case DW_TAG_ptr_to_member_type:
case DW_TAG_reference_type:
case DW_TAG_pointer_type:
- return cu->address_size;
+ return cursor.cu->address_size;
case DW_TAG_array_type:
{
int basetype, upperBound, lowerBound;
- getDWARFArrayBounds(id, cu, cursor, basetype, lowerBound, upperBound);
- return (upperBound - lowerBound + 1) * getDWARFTypeSize(cu, id.type);
+ getDWARFArrayBounds(id, cursor, basetype, lowerBound, upperBound);
+ return (upperBound - lowerBound + 1) * getDWARFTypeSize(cursor, id.type);
}
default:
if(id.type)
- return getDWARFTypeSize(cu, id.type);
+ return getDWARFTypeSize(cursor, id.type);
break;
}
return 0;
@@ -1356,7 +1354,7 @@ bool CV2PDB::mapTypes()
{
DWARF_CompilationUnit* cu = (DWARF_CompilationUnit*)img.debug_info.byteAt(off);
- DIECursor cursor(cu, (byte*)cu + sizeof(DWARF_CompilationUnit));
+ DIECursor cursor(cu, (byte*)cu + sizeof(*cu));
DWARF_InfoData id;
while (cursor.readNext(id))
{
@@ -1429,9 +1427,9 @@ bool CV2PDB::createTypes()
cursor.entryOff, cursor.level, id.code, id.tag);
if (id.abstract_origin)
- mergeAbstractOrigin(id, cu);
+ mergeAbstractOrigin(id, cursor);
if (id.specification)
- mergeSpecification(id, cu);
+ mergeSpecification(id, cursor);
int cvtype = -1;
switch (id.tag)
@@ -1440,36 +1438,36 @@ bool CV2PDB::createTypes()
cvtype = addDWARFBasicType(id.name, id.encoding, id.byte_size);
break;
case DW_TAG_typedef:
- cvtype = appendModifierType(getTypeByDWARFPtr(cu, id.type), 0);
+ cvtype = appendModifierType(getTypeByDWARFPtr(id.type), 0);
addUdtSymbol(cvtype, id.name);
break;
case DW_TAG_pointer_type:
- cvtype = appendPointerType(getTypeByDWARFPtr(cu, id.type), pointerAttr);
+ cvtype = appendPointerType(getTypeByDWARFPtr(id.type), pointerAttr);
break;
case DW_TAG_const_type:
- cvtype = appendModifierType(getTypeByDWARFPtr(cu, id.type), 1);
+ cvtype = appendModifierType(getTypeByDWARFPtr(id.type), 1);
break;
case DW_TAG_reference_type:
- cvtype = appendPointerType(getTypeByDWARFPtr(cu, id.type), pointerAttr | 0x20);
+ cvtype = appendPointerType(getTypeByDWARFPtr(id.type), pointerAttr | 0x20);
break;
case DW_TAG_subrange_type:
// It seems we cannot materialize bounds for scalar types in
// CodeView, so just redirect to a mere base type.
- cvtype = appendModifierType(getTypeByDWARFPtr(cu, id.type), 0);
+ cvtype = appendModifierType(getTypeByDWARFPtr(id.type), 0);
break;
case DW_TAG_class_type:
case DW_TAG_structure_type:
case DW_TAG_union_type:
- cvtype = addDWARFStructure(id, cu, cursor.getSubtreeCursor());
+ cvtype = addDWARFStructure(id, cursor.getSubtreeCursor());
break;
case DW_TAG_array_type:
- cvtype = addDWARFArray(id, cu, cursor.getSubtreeCursor());
+ cvtype = addDWARFArray(id, cursor.getSubtreeCursor());
break;
case DW_TAG_enumeration_type:
- cvtype = addDWARFEnum(id, cu, cursor.getSubtreeCursor());
+ cvtype = addDWARFEnum(id, cursor.getSubtreeCursor());
break;
case DW_TAG_subroutine_type:
@@ -1542,7 +1540,7 @@ bool CV2PDB::createTypes()
}
if (id.pclo && id.pchi)
- addDWARFProc(id, cu, cursor.getSubtreeCursor());
+ addDWARFProc(id, cursor.getSubtreeCursor());
}
break;
@@ -1621,7 +1619,7 @@ bool CV2PDB::createTypes()
}
if (seg >= 0)
{
- int type = getTypeByDWARFPtr(cu, id.type);
+ int type = getTypeByDWARFPtr(id.type);
if (dllimport)
{
checkDWARFTypeAlloc(100);
diff --git a/src/readDwarf.cpp b/src/readDwarf.cpp
index 4d35cf2..f712b29 100644
--- a/src/readDwarf.cpp
+++ b/src/readDwarf.cpp
@@ -315,31 +315,31 @@ Location decodeLocation(const PEImage& img, const DWARF_Attribute& attr, const L
return stack[0];
}
-void mergeAbstractOrigin(DWARF_InfoData& id, DWARF_CompilationUnit* cu)
+void mergeAbstractOrigin(DWARF_InfoData& id, const DIECursor& parent)
{
- DIECursor specCursor(cu, id.abstract_origin);
+ DIECursor specCursor(parent, id.abstract_origin);
DWARF_InfoData idspec;
specCursor.readNext(idspec);
// assert seems invalid, combination DW_TAG_member and DW_TAG_variable found in the wild
// assert(id.tag == idspec.tag);
if (idspec.abstract_origin)
- mergeAbstractOrigin(idspec, cu);
+ mergeAbstractOrigin(idspec, parent);
if (idspec.specification)
- mergeSpecification(idspec, cu);
+ mergeSpecification(idspec, parent);
id.merge(idspec);
}
-void mergeSpecification(DWARF_InfoData& id, DWARF_CompilationUnit* cu)
+void mergeSpecification(DWARF_InfoData& id, const DIECursor& parent)
{
- DIECursor specCursor(cu, id.specification);
+ DIECursor specCursor(parent, id.specification);
DWARF_InfoData idspec;
specCursor.readNext(idspec);
//assert seems invalid, combination DW_TAG_member and DW_TAG_variable found in the wild
//assert(id.tag == idspec.tag);
if (idspec.abstract_origin)
- mergeAbstractOrigin(idspec, cu);
+ mergeAbstractOrigin(idspec, parent);
if (idspec.specification)
- mergeSpecification(idspec, cu);
+ mergeSpecification(idspec, parent);
id.merge(idspec);
}
@@ -352,6 +352,11 @@ DIECursor::DIECursor(DWARF_CompilationUnit* cu_, byte* ptr_)
sibling = 0;
}
+DIECursor::DIECursor(const DIECursor& parent, byte* ptr_)
+ : DIECursor(parent)
+{
+ ptr = ptr_;
+}
void DIECursor::gotoSibling()
{
diff --git a/src/readDwarf.h b/src/readDwarf.h
index 41724f6..bb78285 100644
--- a/src/readDwarf.h
+++ b/src/readDwarf.h
@@ -8,9 +8,9 @@
#include <unordered_map>
#include "mspdb.h"
-class PEImage;
-
typedef unsigned char byte;
+class PEImage;
+class DIECursor;
enum DebugLevel : unsigned {
DbgBasic = 0x1,
@@ -406,8 +406,8 @@ typedef std::unordered_map<std::pair<unsigned, unsigned>, byte*> abbrevMap_t;
// 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);
-void mergeAbstractOrigin(DWARF_InfoData& id, DWARF_CompilationUnit* cu);
-void mergeSpecification(DWARF_InfoData& id, DWARF_CompilationUnit* cu);
+void mergeAbstractOrigin(DWARF_InfoData& id, const DIECursor& parent);
+void mergeSpecification(DWARF_InfoData& id, const DIECursor& parent);
// Debug Information Entry Cursor
class DIECursor
@@ -433,6 +433,9 @@ public:
// Create a new DIECursor
DIECursor(DWARF_CompilationUnit* cu_, byte* ptr);
+ // Create a child DIECursor
+ DIECursor(const DIECursor& parent, byte* ptr_);
+
// Goto next sibling DIE. If the last read DIE had any children, they will be skipped over.
void gotoSibling();
@@ -447,6 +450,15 @@ public:
// If stopAtNull is true, readNext() will stop upon reaching a null DIE (end of the current tree level).
// Otherwise, it will skip null DIEs and stop only at the end of the subtree for which this DIECursor was created.
bool readNext(DWARF_InfoData& id, bool stopAtNull = false);
+
+ // Read an address from p according to the ambient pointer size.
+ uint64_t RDAddr(byte* &p) const
+ {
+ if (cu->address_size == 4)
+ return RD4(p);
+
+ return RD8(p);
+ }
};
// iterate over DWARF debug_line information