summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Aldorasi <marc@groundctl.com>2019-02-04 19:42:35 (GMT)
committerMarc Aldorasi <marc@groundctl.com>2019-02-04 19:42:35 (GMT)
commit813d775e3826a17876b86087b703c70b1503a9ac (patch)
tree9868b085453e8e17233ad50dab1e6988e480a2fb
parentd212e047054d92cd71bf326ab5d01b28b29a6c5a (diff)
downloadcv2pdb-813d775e3826a17876b86087b703c70b1503a9ac.zip
cv2pdb-813d775e3826a17876b86087b703c70b1503a9ac.tar.gz
cv2pdb-813d775e3826a17876b86087b703c70b1503a9ac.tar.bz2
Exclude artificial functions and inherit attributes from abstract origins
-rw-r--r--src/dwarf2pdb.cpp75
-rw-r--r--src/readDwarf.cpp20
-rw-r--r--src/readDwarf.h48
3 files changed, 88 insertions, 55 deletions
diff --git a/src/dwarf2pdb.cpp b/src/dwarf2pdb.cpp
index 2e2d13a..191619b 100644
--- a/src/dwarf2pdb.cpp
+++ b/src/dwarf2pdb.cpp
@@ -894,6 +894,8 @@ int CV2PDB::addDWARFFields(DWARF_InfoData& structid, DWARF_CompilationUnit* cu,
DWARF_InfoData memberid;
if (membercursor.readNext(memberid))
{
+ if (memberid.abstract_origin)
+ mergeAbstractOrigin(memberid, cu);
if (memberid.specification)
mergeSpecification(memberid, cu);
@@ -1416,6 +1418,8 @@ bool CV2PDB::createTypes()
//printf("0x%08x, level = %d, id.code = %d, id.tag = %d\n",
// (unsigned char*)cu + id.entryOff - (unsigned char*)img.debug_info, cursor.level, id.code, id.tag);
+ if (id.abstract_origin)
+ mergeAbstractOrigin(id, cu);
if (id.specification)
mergeSpecification(id, cu);
@@ -1478,46 +1482,49 @@ bool CV2PDB::createTypes()
case DW_TAG_subprogram:
if (id.name)
{
- unsigned long entry_point = 0;
- if (id.pcentry)
+ if (!id.is_artificial)
{
- entry_point = id.pcentry;
- }
- else if (id.pclo)
- {
- entry_point = id.pclo;
- }
- else if (id.ranges != ~0)
- {
- entry_point = ~0;
- byte* r = (byte*)img.debug_ranges + id.ranges;
- byte* rend = (byte*)img.debug_ranges + img.debug_ranges_length;
- while (r < rend)
+ unsigned long entry_point = 0;
+ if (id.pcentry)
{
- uint64_t pclo, pchi;
-
- if (img.isX64())
- {
- pclo = RD8(r);
- pchi = RD8(r);
- }
- else
+ entry_point = id.pcentry;
+ }
+ else if (id.pclo)
+ {
+ entry_point = id.pclo;
+ }
+ else if (id.ranges != ~0)
+ {
+ entry_point = ~0;
+ byte* r = (byte*)img.debug_ranges + id.ranges;
+ byte* rend = (byte*)img.debug_ranges + img.debug_ranges_length;
+ while (r < rend)
{
- pclo = RD4(r);
- pchi = RD4(r);
+ 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);
}
- if (pclo == 0 && pchi == 0)
- break;
- if (pclo >= pchi)
- continue;
- entry_point = min(entry_point, pclo + currentBaseAddress);
+ if (entry_point == ~0)
+ entry_point = 0;
}
- if (entry_point == ~0)
- entry_point = 0;
- }
- if (entry_point)
- mod->AddPublic2(id.name, img.codeSegment + 1, entry_point - codeSegOff, 0);
+ if (entry_point)
+ mod->AddPublic2(id.name, img.codeSegment + 1, entry_point - codeSegOff, 0);
+ }
if (id.pclo && id.pchi)
addDWARFProc(id, cu, cursor.getSubtreeCursor());
diff --git a/src/readDwarf.cpp b/src/readDwarf.cpp
index 04d287b..04a19fe 100644
--- a/src/readDwarf.cpp
+++ b/src/readDwarf.cpp
@@ -292,6 +292,20 @@ Location decodeLocation(const PEImage& img, const DWARF_Attribute& attr, const L
return stack[0];
}
+void mergeAbstractOrigin(DWARF_InfoData& id, DWARF_CompilationUnit* cu)
+{
+ DIECursor specCursor(cu, 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);
+ if (idspec.specification)
+ mergeSpecification(idspec, cu);
+ id.merge(idspec);
+}
+
void mergeSpecification(DWARF_InfoData& id, DWARF_CompilationUnit* cu)
{
DIECursor specCursor(cu, id.specification);
@@ -299,6 +313,10 @@ void mergeSpecification(DWARF_InfoData& id, DWARF_CompilationUnit* cu)
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);
+ if (idspec.specification)
+ mergeSpecification(idspec, cu);
id.merge(idspec);
}
@@ -521,6 +539,7 @@ bool DIECursor::readNext(DWARF_InfoData& id, bool stopAtNull)
break;
case DW_AT_containing_type: assert(a.type == Ref); id.containing_type = a.ref; break;
case DW_AT_specification: assert(a.type == Ref); id.specification = a.ref; break;
+ case DW_AT_abstract_origin: assert(a.type == Ref); id.abstract_origin = a.ref; break;
case DW_AT_data_member_location: id.member_location = a; break;
case DW_AT_location: id.location = a; break;
case DW_AT_frame_base: id.frame_base = a; break;
@@ -543,6 +562,7 @@ bool DIECursor::readNext(DWARF_InfoData& id, bool stopAtNull)
break;
}
break;
+ case DW_AT_artificial: assert(a.type == Flag); id.is_artificial = true; break;
}
}
diff --git a/src/readDwarf.h b/src/readDwarf.h
index 8e69532..fd09090 100644
--- a/src/readDwarf.h
+++ b/src/readDwarf.h
@@ -157,6 +157,7 @@ struct DWARF_InfoData
byte* type;
byte* containing_type;
byte* specification;
+ byte* abstract_origin;
unsigned long inlined;
bool external;
DWARF_Attribute location;
@@ -168,6 +169,7 @@ struct DWARF_InfoData
unsigned language;
unsigned long const_value;
bool has_const_value;
+ bool is_artificial;
void clear()
{
@@ -190,6 +192,7 @@ struct DWARF_InfoData
type = 0;
containing_type = 0;
specification = 0;
+ abstract_origin = 0;
inlined = 0;
external = 0;
member_location.type = Invalid;
@@ -201,31 +204,33 @@ struct DWARF_InfoData
language = 0;
const_value = 0;
has_const_value = false;
+ is_artificial = false;
}
void merge(const DWARF_InfoData& id)
{
- if (id.name) name = id.name;
- if (id.linkage_name) linkage_name = id.linkage_name;
- if (id.dir) dir = id.dir;
- if (id.byte_size) byte_size = id.byte_size;
- if (id.sibling) sibling = id.sibling;
- if (id.encoding) encoding = id.encoding;
- if (id.pclo) pclo = id.pclo;
- if (id.pchi) pchi = id.pchi;
- if (id.ranges != ~0) ranges = id.ranges;
- if (id.pcentry)
- pcentry = id.pcentry;
- if (id.type) type = id.type;
- if (id.containing_type) containing_type = id.containing_type;
- if (id.specification) specification = id.specification;
- if (id.inlined) inlined = id.inlined;
- if (id.external) external = id.external;
- if (id.member_location.type != Invalid) member_location = id.member_location;
- if (id.location.type != Invalid) location = id.location;
- if (id.frame_base.type != Invalid) frame_base = id.frame_base;
- if (id.upper_bound) upper_bound = id.upper_bound;
- if (id.lower_bound) lower_bound = id.lower_bound;
+ if (!name) name = id.name;
+ if (!linkage_name) linkage_name = id.linkage_name;
+ if (!dir) dir = id.dir;
+ if (!byte_size) byte_size = id.byte_size;
+ if (!sibling) sibling = id.sibling;
+ if (!encoding) encoding = id.encoding;
+ if (!pclo) pclo = id.pclo;
+ if (!pchi) pchi = id.pchi;
+ if (ranges == ~0) ranges = id.ranges;
+ if (!pcentry) pcentry = id.pcentry;
+ if (!type) type = id.type;
+ if (!containing_type) containing_type = id.containing_type;
+ if (!specification) specification = id.specification;
+ if (!abstract_origin) abstract_origin = id.abstract_origin;
+ if (!inlined) inlined = id.inlined;
+ if (!external) external = id.external;
+ if (member_location.type == Invalid) member_location = id.member_location;
+ if (location.type == Invalid) location = id.location;
+ if (frame_base.type == Invalid) frame_base = id.frame_base;
+ if (!upper_bound) upper_bound = id.upper_bound;
+ if (!lower_bound) lower_bound = id.lower_bound;
+ if (!is_artificial) is_artificial = id.is_artificial;
}
};
@@ -363,6 +368,7 @@ class PEImage;
// 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);
// Debug Information Entry Cursor