summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Schuetze <r.sagitario@gmx.de>2018-04-21 06:53:57 (GMT)
committerRainer Schuetze <r.sagitario@gmx.de>2018-04-21 06:53:57 (GMT)
commitef038f3d24fe51e9338e7240f1f5a750386ba962 (patch)
treef3c25653e9eb27cdf6337e2ca6a4e303a566e3e2
parent5b9f385b546de9006acb9f81dca14a9cef354e6f (diff)
downloadcv2pdb-ef038f3d24fe51e9338e7240f1f5a750386ba962.zip
cv2pdb-ef038f3d24fe51e9338e7240f1f5a750386ba962.tar.gz
cv2pdb-ef038f3d24fe51e9338e7240f1f5a750386ba962.tar.bz2
DWARF:
- fix code only executed in debug builds - fix evaluation of DW_OP_const1u/DW_OP_const1s not advancing pointer - add support for local variables with location list via DW_FORM_sec_offset
-rw-r--r--src/dwarf2pdb.cpp59
-rw-r--r--src/readDwarf.cpp12
-rw-r--r--src/readDwarf.h8
3 files changed, 44 insertions, 35 deletions
diff --git a/src/dwarf2pdb.cpp b/src/dwarf2pdb.cpp
index 58cd936..0c8aa33 100644
--- a/src/dwarf2pdb.cpp
+++ b/src/dwarf2pdb.cpp
@@ -334,8 +334,9 @@ public:
class CFACursor
{
public:
- CFACursor(const CFIEntry& cfientry, unsigned long location)
- : entry (cfientry)
+ CFACursor(const PEImage& image, const CFIEntry& cfientry, unsigned long location)
+ : img (image)
+ , entry (cfientry)
{
loc = location;
cfa = { Location::RegRel, DW_REG_CFA, 0 };
@@ -418,7 +419,7 @@ public:
attr.type = ExprLoc;
attr.expr.len = LEB128(ptr);
attr.expr.ptr = ptr;
- cfa = decodeLocation(attr);
+ cfa = decodeLocation(img, attr);
ptr += attr.expr.len;
break;
}
@@ -457,7 +458,7 @@ public:
attr.type = Block;
attr.block.len = LEB128(ptr);
attr.block.ptr = ptr;
- cfa = decodeLocation(attr); // TODO: push cfa on stack
+ cfa = decodeLocation(img, attr); // TODO: push cfa on stack
ptr += attr.expr.len;
break;
}
@@ -474,6 +475,7 @@ public:
return true;
}
+ const PEImage& img;
const CFIEntry& entry;
byte* beg;
byte* end;
@@ -498,12 +500,15 @@ Location findBestCFA(const PEImage& img, const CFIIndex* index, unsigned int pcl
CFICursor cursor(img);
cursor.ptr = fde_ptr;
- assert(cursor.readNext(entry));
- CFACursor cfa(entry, pclo);
- while(cfa.processNext()) {}
- cfa.setInstructions(entry.instructions, entry.instructions_length);
- while(!cfa.beforeRestore() && cfa.processNext()) {}
- return cfa.cfa;
+ if (cursor.readNext(entry))
+ {
+ CFACursor cfa(img, entry, pclo);
+ while (cfa.processNext()) {}
+ cfa.setInstructions(entry.instructions, entry.instructions_length);
+ while (!cfa.beforeRestore() && cfa.processNext()) {}
+ return cfa.cfa;
+ }
+ return ebp;
}
// Location list entry
@@ -522,15 +527,15 @@ public:
class LOCCursor
{
public:
- LOCCursor(const PEImage& img, DWARF_CompilationUnit* cu, unsigned long off)
- : beg((byte*)img.debug_loc)
+ LOCCursor(const PEImage& image, unsigned long off)
+ : img (image)
, end((byte*)img.debug_loc + img.debug_loc_length)
- , ptr(beg + off)
+ , ptr((byte*)img.debug_loc + off)
{
default_address_size = img.isX64() ? 8 : 4;
}
- byte* beg;
+ const PEImage& img;
byte* end;
byte* ptr;
byte default_address_size;
@@ -548,16 +553,16 @@ public:
attr.type = Block;
attr.block.len = RD2(ptr);
attr.block.ptr = ptr;
- entry.loc = decodeLocation(attr);
+ entry.loc = decodeLocation(img, attr);
ptr += attr.expr.len;
return true;
}
};
-Location findBestFBLoc(const PEImage& img, DWARF_CompilationUnit* cu, unsigned long fblocoff)
+Location findBestFBLoc(const PEImage& img, unsigned long fblocoff)
{
int regebp = img.isX64() ? 6 : 5;
- LOCCursor cursor(img, cu, fblocoff);
+ LOCCursor cursor(img, fblocoff);
LOCEntry entry;
Location longest = { Location::RegRel, DW_REG_CFA, 0 };
unsigned long longest_range = 0;
@@ -738,9 +743,9 @@ bool CV2PDB::addDWARFProc(DWARF_InfoData& procid, DWARF_CompilationUnit* cu, DIE
addStackVar("local_var", 0x1001, 8);
#endif
- Location frameBase = decodeLocation(procid.frame_base, 0, DW_AT_frame_base);
+ 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, cu, frameBase.off);
+ frameBase = findBestFBLoc(img, frameBase.off);
Location cfa = findBestCFA(img, cfi_index, procid.pclo, procid.pchi);
@@ -753,11 +758,12 @@ bool CV2PDB::addDWARFProc(DWARF_InfoData& procid, DWARF_CompilationUnit* cu, DIE
DIECursor prev = cursor;
while (cursor.readNext(id, true))
{
- if (id.tag == DW_TAG_formal_parameter)
+ if (id.tag == DW_TAG_formal_parameter && id.name)
{
- if (id.name && (id.location.type == ExprLoc || id.location.type == Block))
+ if (id.location.type == ExprLoc || id.location.type == Block || id.location.type == SecOffset)
{
- Location loc = decodeLocation(id.location, &frameBase);
+ Location loc = id.location.type == SecOffset ? findBestFBLoc(img, id.location.sec_offset)
+ : decodeLocation(img, id.location, &frameBase);
if (loc.is_regrel())
appendStackVar(id.name, getTypeByDWARFPtr(cu, id.type), loc, cfa);
}
@@ -827,7 +833,8 @@ bool CV2PDB::addDWARFProc(DWARF_InfoData& procid, DWARF_CompilationUnit* cu, DIE
{
if (id.name && (id.location.type == ExprLoc || id.location.type == Block))
{
- Location loc = decodeLocation(id.location, &frameBase);
+ Location loc = id.location.type == SecOffset ? findBestFBLoc(img, id.location.sec_offset)
+ : decodeLocation(img, id.location, &frameBase);
if (loc.is_regrel())
appendStackVar(id.name, getTypeByDWARFPtr(cu, id.type), loc, cfa);
}
@@ -888,7 +895,7 @@ int CV2PDB::addDWARFStructure(DWARF_InfoData& structid, DWARF_CompilationUnit* c
int off = 0;
if (!isunion)
{
- Location loc = decodeLocation(id.member_location, 0, DW_AT_data_member_location);
+ Location loc = decodeLocation(img, id.member_location, 0, DW_AT_data_member_location);
if (loc.is_abs())
{
off = loc.off;
@@ -907,7 +914,7 @@ int CV2PDB::addDWARFStructure(DWARF_InfoData& structid, DWARF_CompilationUnit* c
else if(id.tag == DW_TAG_inheritance)
{
int off;
- Location loc = decodeLocation(id.member_location, 0, DW_AT_data_member_location);
+ Location loc = decodeLocation(img, id.member_location, 0, DW_AT_data_member_location);
if (loc.is_abs())
{
cvid = S_CONSTANT_V2;
@@ -1510,7 +1517,7 @@ bool CV2PDB::createTypes()
}
else
{
- Location loc = decodeLocation(id.location);
+ Location loc = decodeLocation(img, id.location);
if (loc.is_abs())
{
segOff = loc.off;
diff --git a/src/readDwarf.cpp b/src/readDwarf.cpp
index c91776c..6f5d04d 100644
--- a/src/readDwarf.cpp
+++ b/src/readDwarf.cpp
@@ -38,7 +38,7 @@ static Location mkRegRel(int reg, int off)
return l;
}
-Location decodeLocation(const DWARF_Attribute& attr, const Location* frameBase, int at)
+Location decodeLocation(const PEImage& img, const DWARF_Attribute& attr, const Location* frameBase, int at)
{
static Location invalid = { Location::Invalid };
@@ -47,8 +47,10 @@ Location decodeLocation(const DWARF_Attribute& attr, const Location* frameBase,
if (attr.type != ExprLoc && attr.type != Block) // same memory layout
return invalid;
+
+ byte*p = attr.expr.ptr;
+ byte*end = attr.expr.ptr + attr.expr.len;
- byte* p = attr.expr.ptr;
Location stack[256];
int stackDepth = 0;
if (at == DW_AT_data_member_location)
@@ -56,7 +58,7 @@ Location decodeLocation(const DWARF_Attribute& attr, const Location* frameBase,
for (;;)
{
- if (p >= attr.expr.ptr + attr.expr.len)
+ if (p >= end)
break;
int op = *p++;
@@ -79,10 +81,10 @@ Location decodeLocation(const DWARF_Attribute& attr, const Location* frameBase,
stack[stackDepth++] = mkInReg(LEB128(p));
break;
- case DW_OP_const1u: stack[stackDepth++] = mkAbs(*p); break;
+ case DW_OP_const1u: stack[stackDepth++] = mkAbs(*p++); break;
case DW_OP_const2u: stack[stackDepth++] = mkAbs(RD2(p)); break;
case DW_OP_const4u: stack[stackDepth++] = mkAbs(RD4(p)); break;
- case DW_OP_const1s: stack[stackDepth++] = mkAbs((char)*p); break;
+ case DW_OP_const1s: stack[stackDepth++] = mkAbs((char)*p++); break;
case DW_OP_const2s: stack[stackDepth++] = mkAbs((short)RD2(p)); break;
case DW_OP_const4s: stack[stackDepth++] = mkAbs((int)RD4(p)); break;
case DW_OP_constu: stack[stackDepth++] = mkAbs(LEB128(p)); break;
diff --git a/src/readDwarf.h b/src/readDwarf.h
index a259e3c..532d1c2 100644
--- a/src/readDwarf.h
+++ b/src/readDwarf.h
@@ -349,12 +349,12 @@ struct Location
bool is_regrel() const { return type == RegRel; }
};
-// Attemots to partially evaluate DWARF location expressions.
+class PEImage;
+
+// 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 DWARF_Attribute& attr, const Location* frameBase = 0, int at = 0);
-
-class PEImage;
+Location decodeLocation(const PEImage& img, const DWARF_Attribute& attr, const Location* frameBase = 0, int at = 0);
// Debug Information Entry Cursor
class DIECursor