summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarc Aldorasi <marc@groundctl.com>2019-02-04 18:36:59 (GMT)
committerMarc Aldorasi <marc@groundctl.com>2019-02-04 18:36:59 (GMT)
commitd212e047054d92cd71bf326ab5d01b28b29a6c5a (patch)
tree8677dadea3462d446fe8fe83df48545317027852 /src
parent14641495119635e26aabad1dbccc79a6dd1fc94c (diff)
downloadcv2pdb-d212e047054d92cd71bf326ab5d01b28b29a6c5a.zip
cv2pdb-d212e047054d92cd71bf326ab5d01b28b29a6c5a.tar.gz
cv2pdb-d212e047054d92cd71bf326ab5d01b28b29a6c5a.tar.bz2
Try harder to get function entry points
Diffstat (limited to 'src')
-rw-r--r--src/dwarf2pdb.cpp47
-rw-r--r--src/readDwarf.cpp8
-rw-r--r--src/readDwarf.h4
3 files changed, 56 insertions, 3 deletions
diff --git a/src/dwarf2pdb.cpp b/src/dwarf2pdb.cpp
index 962c880..2e2d13a 100644
--- a/src/dwarf2pdb.cpp
+++ b/src/dwarf2pdb.cpp
@@ -1476,10 +1476,51 @@ bool CV2PDB::createTypes()
break;
case DW_TAG_subprogram:
- if (id.name && id.pclo && id.pchi)
+ if (id.name)
{
- addDWARFProc(id, cu, cursor.getSubtreeCursor());
- int rc = mod->AddPublic2(id.name, img.codeSegment + 1, id.pclo - codeSegOff, 0);
+ unsigned long entry_point = 0;
+ if (id.pcentry)
+ {
+ 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)
+ {
+ 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 (entry_point == ~0)
+ entry_point = 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());
}
break;
diff --git a/src/readDwarf.cpp b/src/readDwarf.cpp
index 8df2c5b..04d287b 100644
--- a/src/readDwarf.cpp
+++ b/src/readDwarf.cpp
@@ -486,6 +486,14 @@ bool DIECursor::readNext(DWARF_InfoData& id, bool stopAtNull)
else
assert(false);
break;
+ case DW_AT_entry_pc:
+ if (a.type == Addr)
+ id.pcentry = a.addr;
+ else if (a.type == Const)
+ id.pcentry = id.pclo + a.cons;
+ else
+ assert(false);
+ break;
case DW_AT_ranges:
if (a.type == SecOffset)
id.ranges = a.sec_offset;
diff --git a/src/readDwarf.h b/src/readDwarf.h
index f004aa6..8e69532 100644
--- a/src/readDwarf.h
+++ b/src/readDwarf.h
@@ -153,6 +153,7 @@ struct DWARF_InfoData
unsigned long pclo;
unsigned long pchi;
unsigned long ranges; // -1u when attribute is not present
+ unsigned long pcentry;
byte* type;
byte* containing_type;
byte* specification;
@@ -185,6 +186,7 @@ struct DWARF_InfoData
pclo = 0;
pchi = 0;
ranges = ~0;
+ pcentry = 0;
type = 0;
containing_type = 0;
specification = 0;
@@ -212,6 +214,8 @@ struct DWARF_InfoData
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;