mirror of
https://github.com/reactos/reactos.git
synced 2025-05-23 19:14:48 +00:00
[CMAKE]
* Add yet another awesome rossym/kdbg feature: struct printing using the command "dt". Brought to you by the Arty. svn path=/trunk/; revision=52571
This commit is contained in:
parent
81a39fdab6
commit
31ee5fc3a7
12 changed files with 495 additions and 92 deletions
|
@ -12,6 +12,10 @@
|
|||
|
||||
#define ROSSYM_SECTION_NAME ".rossym"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _ROSSYM_HEADER {
|
||||
unsigned long SymbolsOffset;
|
||||
unsigned long SymbolsLength;
|
||||
|
@ -86,6 +90,18 @@ typedef struct _ROSSYM_LINEINFO {
|
|||
ROSSYM_PARAMETER Parameters[16];
|
||||
} ROSSYM_LINEINFO, *PROSSYM_LINEINFO;
|
||||
|
||||
typedef struct _ROSSYM_AGGREGATE_MEMBER {
|
||||
PCHAR Name, Type;
|
||||
ULONG BaseOffset, Size;
|
||||
ULONG FirstBit, Bits;
|
||||
ULONG TypeId;
|
||||
} ROSSYM_AGGREGATE_MEMBER, *PROSSYM_AGGREGATE_MEMBER;
|
||||
|
||||
typedef struct _ROSSYM_AGGREGATE {
|
||||
ULONG NumElements;
|
||||
PROSSYM_AGGREGATE_MEMBER Elements;
|
||||
} ROSSYM_AGGREGATE, *PROSSYM_AGGREGATE;
|
||||
|
||||
typedef struct _ROSSYM_CALLBACKS {
|
||||
PVOID (*AllocMemProc)(ULONG_PTR Size);
|
||||
VOID (*FreeMemProc)(PVOID Area);
|
||||
|
@ -132,6 +148,13 @@ BOOLEAN RosSymGetAddressInformation(PROSSYM_INFO RosSymInfo,
|
|||
#endif
|
||||
VOID RosSymFreeInfo(PROSSYM_LINEINFO RosSymLineInfo);
|
||||
VOID RosSymDelete(PROSSYM_INFO RosSymInfo);
|
||||
BOOLEAN
|
||||
RosSymAggregate(PROSSYM_INFO RosSymInfo, PCHAR Type, PROSSYM_AGGREGATE Aggregate);
|
||||
VOID RosSymFreeAggregate(PROSSYM_AGGREGATE Aggregate);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* REACTOS_ROSSYM_H_INCLUDED */
|
||||
|
||||
|
|
|
@ -19,6 +19,19 @@ typedef long long s64int;
|
|||
typedef ulong size_t;
|
||||
#endif
|
||||
|
||||
DECLSPEC_NORETURN
|
||||
NTSYSAPI
|
||||
VOID
|
||||
NTAPI
|
||||
RtlRaiseStatus(IN NTSTATUS Status);
|
||||
|
||||
#undef assert
|
||||
#define assert(x) do { \
|
||||
if (!(x)) { \
|
||||
werrstr("(%s:%d) assertion " #x " failed\n", __FILE__, __LINE__); \
|
||||
RtlRaiseStatus(STATUS_ASSERTION_FAILURE); \
|
||||
} \
|
||||
} while (0)
|
||||
#define offsetof(x,y) FIELD_OFFSET(x,y)
|
||||
#define nil (0)
|
||||
|
||||
|
@ -32,7 +45,13 @@ void *RosSymRealloc(void *mem, ulong newsize);
|
|||
void xfree(void *v);
|
||||
|
||||
#define werrstr(str, ...) DPRINT(str "\n" ,##__VA_ARGS__)
|
||||
//#define werrstr(x, ...) printf("(%s:%d) " x "\n",__FILE__,__LINE__,##__VA_ARGS__)
|
||||
#if 0
|
||||
#ifdef NDEBUG
|
||||
#define werrstr(x, ...)
|
||||
#else
|
||||
#define werrstr(x, ...) printf("(%s:%d) " x "\n",__FILE__,__LINE__,##__VA_ARGS__)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define malloc(x) RosSymAllocMem(x)
|
||||
#define mallocz(x,y) RosSymAllocMemZero(x,y)
|
||||
|
|
|
@ -483,5 +483,6 @@ struct DwarfStack
|
|||
DwarfAbbrev *dwarfgetabbrev(Dwarf*, ulong, ulong);
|
||||
|
||||
int dwarfgetinfounit(Dwarf*, ulong, DwarfBlock*);
|
||||
void dwarfdumpsym(Dwarf *d, DwarfSym *s);
|
||||
|
||||
#define MAXIMUM_DWARF_NAME_SIZE 64
|
||||
|
|
|
@ -83,7 +83,7 @@ parseabbrevs(Dwarf *d, ulong off, DwarfAbbrev *abbrev, DwarfAttr *attr, int *pna
|
|||
if(num == 0)
|
||||
break;
|
||||
tag = dwarfget128(&b);
|
||||
DPRINT("num %d tag %x @ %x", num, tag, b.p - d->abbrev.data);
|
||||
werrstr("abbrev: num %d tag %x @ %x", num, tag, b.p - d->abbrev.data);
|
||||
haskids = dwarfget1(&b);
|
||||
for(i=0;; i++){
|
||||
name = dwarfget128(&b);
|
||||
|
@ -120,11 +120,12 @@ findabbrev(DwarfAbbrev *a, int na, ulong num)
|
|||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<na; i++)
|
||||
if(a[i].num == num)
|
||||
for(i=0; i<na; i++) {
|
||||
if(a[i].num == num) {
|
||||
return &a[i];
|
||||
assert(0);
|
||||
werrstr("abbrev not found");
|
||||
}
|
||||
}
|
||||
werrstr("abbrev not found (%x)", na);
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
@ -133,7 +134,7 @@ dwarfgetabbrev(Dwarf *d, ulong off, ulong num)
|
|||
{
|
||||
DwarfAbbrev *a;
|
||||
int na;
|
||||
|
||||
werrstr("want num %d\n", num);
|
||||
if((na = loadabbrevs(d, off, &a)) < 0){
|
||||
werrstr("loadabbrevs: %r");
|
||||
return nil;
|
||||
|
|
|
@ -128,9 +128,11 @@ dwarflookupnameinunit(Dwarf *d, ulong unit, char *name, DwarfSym *s)
|
|||
DwarfSym compunit = { };
|
||||
if(dwarfenumunit(d, unit, &compunit) < 0)
|
||||
return -1;
|
||||
while(dwarfnextsymat(d, &compunit, s) == 1)
|
||||
while(dwarfnextsymat(d, &compunit, s) == 0) {
|
||||
werrstr("got %s looking for %s\n", s->attrs.name, name);
|
||||
if(s->attrs.name && strcmp(s->attrs.name, name) == 0)
|
||||
return 0;
|
||||
}
|
||||
werrstr("symbol '%s' not found", name);
|
||||
return -1;
|
||||
}
|
||||
|
@ -188,7 +190,10 @@ dwarfseeksym(Dwarf *d, ulong unit, ulong off, DwarfSym *s)
|
|||
DwarfSym compunit = { };
|
||||
if(dwarfenumunit(d, unit, &compunit) < 0)
|
||||
return -1;
|
||||
werrstr("dwarfseeksym: unit %x off %x\n", unit, off);
|
||||
s->b.d = d;
|
||||
s->b.p = d->info.data + unit + off;
|
||||
s->b.ep = compunit.b.ep;
|
||||
if(dwarfnextsymat(d, &compunit, s) == -1)
|
||||
return -1;
|
||||
werrstr("dwarfseeksym: unit %x off %x, tag %x", unit, off, s->attrs.tag);
|
||||
|
@ -238,7 +243,7 @@ dwarfenumunit(Dwarf *d, ulong unit, DwarfSym *s)
|
|||
return -1;
|
||||
}
|
||||
s->b.ep = s->b.p+len;
|
||||
if((i=dwarfget2(&s->b)) != 2)
|
||||
if((i=dwarfget2(&s->b)) > 4)
|
||||
goto badheader;
|
||||
aoff = dwarfget4(&s->b);
|
||||
s->b.addrsize = dwarfget1(&s->b);
|
||||
|
@ -258,15 +263,19 @@ dwarfnextsym(Dwarf *d, DwarfSym *s)
|
|||
ulong num;
|
||||
DwarfAbbrev *a;
|
||||
|
||||
werrstr("sym at %x (left %x)\n", s->b.p - d->info.data, s->b.ep - s->b.p);
|
||||
|
||||
num = dwarfget128(&s->b);
|
||||
werrstr("abbrev num %x\n", num);
|
||||
s->num = num;
|
||||
if(num == 0){
|
||||
return -1;
|
||||
}
|
||||
|
||||
a = dwarfgetabbrev(d, s->aoff, num);
|
||||
werrstr("a %p\n", a);
|
||||
if(a == nil){
|
||||
werrstr("getabbrev %ud %ud for %ud,%ud", s->aoff, num, s->unit);
|
||||
werrstr("getabbrev %x %x for %x", s->aoff, num, s->unit);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -277,6 +286,7 @@ dwarfnextsym(Dwarf *d, DwarfSym *s)
|
|||
if (s->attrs.haskids) {
|
||||
DwarfSym childSkip = { };
|
||||
s->childoff = s->b.p - d->info.data;
|
||||
werrstr("Set childoff at %x\n", s->childoff);
|
||||
int r = dwarfnextsymat(d, s, &childSkip);
|
||||
while (r == 0) {
|
||||
r = dwarfnextsym(d, &childSkip);
|
||||
|
@ -316,6 +326,7 @@ dwarfnextsymat(Dwarf *d, DwarfSym *parent, DwarfSym *child)
|
|||
if (!child->b.d) {
|
||||
child->b = parent->b;
|
||||
child->b.p = parent->childoff + parent->b.d->info.data;
|
||||
werrstr("Rewound to childoff %x\n", parent->childoff);
|
||||
}
|
||||
|
||||
return dwarfnextsym(d, child);
|
||||
|
@ -323,76 +334,78 @@ dwarfnextsymat(Dwarf *d, DwarfSym *parent, DwarfSym *child)
|
|||
|
||||
typedef struct Parse Parse;
|
||||
struct Parse {
|
||||
const char *namestr;
|
||||
int name;
|
||||
int off;
|
||||
int haveoff;
|
||||
int type;
|
||||
};
|
||||
|
||||
#define ATTR(x) (#x)+9, x
|
||||
#define OFFSET(x) offsetof(DwarfAttrs, x), offsetof(DwarfAttrs, have.x)
|
||||
|
||||
static Parse plist[] = { /* Font Tab 4 */
|
||||
{ DwarfAttrAbstractOrigin, OFFSET(abstractorigin), TReference },
|
||||
{ DwarfAttrAccessibility, OFFSET(accessibility), TConstant },
|
||||
{ DwarfAttrAddrClass, OFFSET(addrclass), TConstant },
|
||||
{ DwarfAttrArtificial, OFFSET(isartificial), TFlag },
|
||||
{ DwarfAttrBaseTypes, OFFSET(basetypes), TReference },
|
||||
{ DwarfAttrBitOffset, OFFSET(bitoffset), TConstant },
|
||||
{ DwarfAttrBitSize, OFFSET(bitsize), TConstant },
|
||||
{ DwarfAttrByteSize, OFFSET(bytesize), TConstant },
|
||||
{ DwarfAttrCalling, OFFSET(calling), TConstant },
|
||||
{ DwarfAttrCommonRef, OFFSET(commonref), TReference },
|
||||
{ DwarfAttrCompDir, OFFSET(compdir), TString },
|
||||
{ DwarfAttrConstValue, OFFSET(constvalue), TString|TConstant|TBlock },
|
||||
{ DwarfAttrContainingType, OFFSET(containingtype), TReference },
|
||||
{ DwarfAttrCount, OFFSET(count), TConstant|TReference },
|
||||
{ DwarfAttrDataMemberLoc, OFFSET(datamemberloc), TBlock|TConstant|TReference },
|
||||
{ DwarfAttrDeclColumn, OFFSET(declcolumn), TConstant },
|
||||
{ DwarfAttrDeclFile, OFFSET(declfile), TConstant },
|
||||
{ DwarfAttrDeclLine, OFFSET(declline), TConstant },
|
||||
{ DwarfAttrDeclaration, OFFSET(isdeclaration), TFlag },
|
||||
{ DwarfAttrDefaultValue, OFFSET(defaultvalue), TReference },
|
||||
{ DwarfAttrDiscr, OFFSET(discr), TReference },
|
||||
{ DwarfAttrDiscrList, OFFSET(discrlist), TBlock },
|
||||
{ DwarfAttrDiscrValue, OFFSET(discrvalue), TConstant },
|
||||
{ DwarfAttrEncoding, OFFSET(encoding), TConstant },
|
||||
{ DwarfAttrExternal, OFFSET(isexternal), TFlag },
|
||||
{ DwarfAttrFrameBase, OFFSET(framebase), TBlock|TConstant },
|
||||
{ DwarfAttrFriend, OFFSET(friend), TReference },
|
||||
{ DwarfAttrHighpc, OFFSET(highpc), TAddress },
|
||||
{ DwarfAttrEntrypc, OFFSET(entrypc), TAddress },
|
||||
{ DwarfAttrIdentifierCase, OFFSET(identifiercase), TConstant },
|
||||
{ DwarfAttrImport, OFFSET(import), TReference },
|
||||
{ DwarfAttrInline, OFFSET(inlined), TConstant },
|
||||
{ DwarfAttrIsOptional, OFFSET(isoptional), TFlag },
|
||||
{ DwarfAttrLanguage, OFFSET(language), TConstant },
|
||||
{ DwarfAttrLocation, OFFSET(location), TReference|TBlock },
|
||||
{ DwarfAttrLowerBound, OFFSET(lowerbound), TConstant|TReference },
|
||||
{ DwarfAttrLowpc, OFFSET(lowpc), TAddress },
|
||||
{ DwarfAttrMacroInfo, OFFSET(macroinfo), TConstant },
|
||||
{ DwarfAttrName, OFFSET(name), TString },
|
||||
{ DwarfAttrNamelistItem, OFFSET(namelistitem), TBlock },
|
||||
{ DwarfAttrOrdering, OFFSET(ordering), TConstant },
|
||||
{ DwarfAttrPriority, OFFSET(priority), TReference },
|
||||
{ DwarfAttrProducer, OFFSET(producer), TString },
|
||||
{ DwarfAttrPrototyped, OFFSET(isprototyped), TFlag },
|
||||
{ DwarfAttrRanges, OFFSET(ranges), TReference },
|
||||
{ DwarfAttrReturnAddr, OFFSET(returnaddr), TBlock|TConstant },
|
||||
{ DwarfAttrSegment, OFFSET(segment), TBlock|TConstant },
|
||||
{ DwarfAttrSibling, OFFSET(sibling), TReference },
|
||||
{ DwarfAttrSpecification, OFFSET(specification), TReference },
|
||||
{ DwarfAttrStartScope, OFFSET(startscope), TConstant },
|
||||
{ DwarfAttrStaticLink, OFFSET(staticlink), TBlock|TConstant },
|
||||
{ DwarfAttrStmtList, OFFSET(stmtlist), TConstant },
|
||||
{ DwarfAttrStrideSize, OFFSET(stridesize), TConstant },
|
||||
{ DwarfAttrStringLength, OFFSET(stringlength), TBlock|TConstant },
|
||||
{ DwarfAttrType, OFFSET(type), TReference },
|
||||
{ DwarfAttrUpperBound, OFFSET(upperbound), TConstant|TReference },
|
||||
{ DwarfAttrUseLocation, OFFSET(uselocation), TBlock|TConstant },
|
||||
{ DwarfAttrVarParam, OFFSET(isvarparam), TFlag },
|
||||
{ DwarfAttrVirtuality, OFFSET(virtuality), TConstant },
|
||||
{ DwarfAttrVisibility, OFFSET(visibility), TConstant },
|
||||
{ DwarfAttrVtableElemLoc, OFFSET(vtableelemloc), TBlock|TReference },
|
||||
{ ATTR(DwarfAttrAbstractOrigin), OFFSET(abstractorigin), TReference },
|
||||
{ ATTR(DwarfAttrAccessibility), OFFSET(accessibility), TConstant },
|
||||
{ ATTR(DwarfAttrAddrClass), OFFSET(addrclass), TConstant },
|
||||
{ ATTR(DwarfAttrBaseTypes), OFFSET(basetypes), TReference },
|
||||
{ ATTR(DwarfAttrBitOffset), OFFSET(bitoffset), TConstant },
|
||||
{ ATTR(DwarfAttrBitSize), OFFSET(bitsize), TConstant },
|
||||
{ ATTR(DwarfAttrByteSize), OFFSET(bytesize), TConstant },
|
||||
{ ATTR(DwarfAttrCalling), OFFSET(calling), TConstant },
|
||||
{ ATTR(DwarfAttrCommonRef), OFFSET(commonref), TReference },
|
||||
{ ATTR(DwarfAttrCompDir), OFFSET(compdir), TString },
|
||||
{ ATTR(DwarfAttrConstValue), OFFSET(constvalue), TString|TConstant|TBlock },
|
||||
{ ATTR(DwarfAttrContainingType), OFFSET(containingtype), TReference },
|
||||
{ ATTR(DwarfAttrCount), OFFSET(count), TConstant|TReference },
|
||||
{ ATTR(DwarfAttrDataMemberLoc), OFFSET(datamemberloc), TBlock|TConstant|TReference },
|
||||
{ ATTR(DwarfAttrDeclColumn), OFFSET(declcolumn), TConstant },
|
||||
{ ATTR(DwarfAttrDeclFile), OFFSET(declfile), TConstant },
|
||||
{ ATTR(DwarfAttrDeclLine), OFFSET(declline), TConstant },
|
||||
{ ATTR(DwarfAttrDefaultValue), OFFSET(defaultvalue), TReference },
|
||||
{ ATTR(DwarfAttrDiscr), OFFSET(discr), TReference },
|
||||
{ ATTR(DwarfAttrDiscrList), OFFSET(discrlist), TBlock },
|
||||
{ ATTR(DwarfAttrDiscrValue), OFFSET(discrvalue), TConstant },
|
||||
{ ATTR(DwarfAttrEncoding), OFFSET(encoding), TConstant },
|
||||
{ ATTR(DwarfAttrFrameBase), OFFSET(framebase), TBlock|TConstant },
|
||||
{ ATTR(DwarfAttrFriend), OFFSET(friend), TReference },
|
||||
{ ATTR(DwarfAttrHighpc), OFFSET(highpc), TAddress },
|
||||
{ ATTR(DwarfAttrEntrypc), OFFSET(entrypc), TAddress },
|
||||
{ ATTR(DwarfAttrIdentifierCase), OFFSET(identifiercase), TConstant },
|
||||
{ ATTR(DwarfAttrImport), OFFSET(import), TReference },
|
||||
{ ATTR(DwarfAttrInline), OFFSET(inlined), TConstant },
|
||||
{ ATTR(DwarfAttrArtificial), OFFSET(isartificial), TFlag },
|
||||
{ ATTR(DwarfAttrDeclaration), OFFSET(isdeclaration), TFlag },
|
||||
{ ATTR(DwarfAttrExternal), OFFSET(isexternal), TFlag },
|
||||
{ ATTR(DwarfAttrIsOptional), OFFSET(isoptional), TFlag },
|
||||
{ ATTR(DwarfAttrPrototyped), OFFSET(isprototyped), TFlag },
|
||||
{ ATTR(DwarfAttrVarParam), OFFSET(isvarparam), TFlag },
|
||||
{ ATTR(DwarfAttrLanguage), OFFSET(language), TConstant },
|
||||
{ ATTR(DwarfAttrLocation), OFFSET(location), TReference|TBlock },
|
||||
{ ATTR(DwarfAttrLowerBound), OFFSET(lowerbound), TConstant|TReference },
|
||||
{ ATTR(DwarfAttrLowpc), OFFSET(lowpc), TAddress },
|
||||
{ ATTR(DwarfAttrMacroInfo), OFFSET(macroinfo), TConstant },
|
||||
{ ATTR(DwarfAttrName), OFFSET(name), TString },
|
||||
{ ATTR(DwarfAttrNamelistItem), OFFSET(namelistitem), TBlock },
|
||||
{ ATTR(DwarfAttrOrdering), OFFSET(ordering), TConstant },
|
||||
{ ATTR(DwarfAttrPriority), OFFSET(priority), TReference },
|
||||
{ ATTR(DwarfAttrProducer), OFFSET(producer), TString },
|
||||
{ ATTR(DwarfAttrRanges), OFFSET(ranges), TReference },
|
||||
{ ATTR(DwarfAttrReturnAddr), OFFSET(returnaddr), TBlock|TConstant },
|
||||
{ ATTR(DwarfAttrSegment), OFFSET(segment), TBlock|TConstant },
|
||||
{ ATTR(DwarfAttrSibling), OFFSET(sibling), TReference },
|
||||
{ ATTR(DwarfAttrSpecification), OFFSET(specification), TReference },
|
||||
{ ATTR(DwarfAttrStartScope), OFFSET(startscope), TConstant },
|
||||
{ ATTR(DwarfAttrStaticLink), OFFSET(staticlink), TBlock|TConstant },
|
||||
{ ATTR(DwarfAttrStmtList), OFFSET(stmtlist), TConstant },
|
||||
{ ATTR(DwarfAttrStrideSize), OFFSET(stridesize), TConstant },
|
||||
{ ATTR(DwarfAttrStringLength), OFFSET(stringlength), TBlock|TConstant },
|
||||
{ ATTR(DwarfAttrType), OFFSET(type), TReference },
|
||||
{ ATTR(DwarfAttrUpperBound), OFFSET(upperbound), TConstant|TReference },
|
||||
{ ATTR(DwarfAttrUseLocation), OFFSET(uselocation), TBlock|TConstant },
|
||||
{ ATTR(DwarfAttrVirtuality), OFFSET(virtuality), TConstant },
|
||||
{ ATTR(DwarfAttrVisibility), OFFSET(visibility), TConstant },
|
||||
{ ATTR(DwarfAttrVtableElemLoc), OFFSET(vtableelemloc), TBlock|TReference },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -417,6 +430,7 @@ parseattrs(Dwarf *d, DwarfBuf *b, ulong tag, ulong unit, DwarfAbbrev *a, DwarfAt
|
|||
for(i=0; i<a->nattr; i++){
|
||||
n = a->attr[i].name;
|
||||
f = a->attr[i].form;
|
||||
werrstr("struct: (@%x) n %x f %x (%d %d)\n", b->p - d->info.data, n, f, ptab[n].haveoff, ptab[n].off);
|
||||
if(n < 0 || n >= DwarfAttrMax || ptab[n].name==0) {
|
||||
if (skipform(d, b, f) < 0) {
|
||||
if(++nbad == 1)
|
||||
|
@ -436,11 +450,12 @@ parseattrs(Dwarf *d, DwarfBuf *b, ulong tag, ulong unit, DwarfAbbrev *a, DwarfAt
|
|||
got = TFlag;
|
||||
else if((ptab[n].type&TString) && getstring(d, b, f, v) >= 0)
|
||||
got = TString;
|
||||
else if((ptab[n].type&TBlock) && getblock(b, f, v) >= 0)
|
||||
else if((ptab[n].type&TBlock) && getblock(b, f, v) >= 0) {
|
||||
got = TBlock;
|
||||
else {
|
||||
} else {
|
||||
werrstr("Skipping form %x\n", f);
|
||||
if(skipform(d, b, f) < 0){
|
||||
if(++nbad == 1)
|
||||
//if(++nbad == 1)
|
||||
werrstr("dwarf parse attrs: cannot skip form %d", f);
|
||||
return -1;
|
||||
}
|
||||
|
@ -451,6 +466,10 @@ parseattrs(Dwarf *d, DwarfBuf *b, ulong tag, ulong unit, DwarfAbbrev *a, DwarfAt
|
|||
#endif
|
||||
*((uchar*)attrs+ptab[n].haveoff) = got;
|
||||
}
|
||||
|
||||
if (attrs->have.name)
|
||||
werrstr("%s: tag %x kids %d (last %x)\n", attrs->name, attrs->tag, attrs->haskids, b->p - b->d->info.data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -651,6 +670,7 @@ int dwarfgetarg(Dwarf *d, const char *name, DwarfBuf *buf, ulong cfa, PROSSYM_RE
|
|||
int ret = 0;
|
||||
DwarfStack stack = { };
|
||||
stackinit(&stack);
|
||||
stackpush(&stack, cfa);
|
||||
while (buf->p < buf->ep) {
|
||||
int opcode = dwarfget1(buf);
|
||||
werrstr("opcode %x", opcode);
|
||||
|
@ -951,6 +971,25 @@ int dwarfargvalue(Dwarf *d, DwarfSym *proc, ulong pc, ulong cfa, PROSSYM_REGISTE
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
dwarfdumpsym(Dwarf *d, DwarfSym *s)
|
||||
{
|
||||
int i, j;
|
||||
werrstr("tag %x\n", s->attrs.tag);
|
||||
for (j = 0; plist[j].name; j++) {
|
||||
char *have = ((char*)&s->attrs) + plist[j].haveoff;
|
||||
char *attr = ((char*)&s->attrs) + plist[j].off;
|
||||
if (*have == TString) {
|
||||
char *str = *((char **)attr);
|
||||
werrstr("%s: %s\n", plist[j].namestr, str);
|
||||
} else if (*have == TReference) {
|
||||
DwarfVal *val = ((DwarfVal*)attr);
|
||||
werrstr("%s: %x:%x\n", plist[j].namestr, val->b.data, val->b.len);
|
||||
} else if (*have)
|
||||
werrstr("%s: (%x)\n", plist[j].namestr, *have);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
dwarfgetparams(Dwarf *d, DwarfSym *s, ulong pc, int pnum, DwarfParam *paramblocks)
|
||||
{
|
||||
|
|
|
@ -30,10 +30,10 @@ dwarfopen(Pe *pe)
|
|||
if(pe->loadsection(pe, ".debug_abbrev", &d->abbrev) < 0
|
||||
|| pe->loadsection(pe, ".debug_aranges", &d->aranges) < 0
|
||||
|| pe->loadsection(pe, ".debug_line", &d->line) < 0
|
||||
|| pe->loadsection(pe, ".debug_pubnames", &d->pubnames) < 0
|
||||
|| pe->loadsection(pe, ".debug_info", &d->info) < 0
|
||||
|| pe->loadsection(pe, ".debug_loc", &d->loc) < 0)
|
||||
goto err;
|
||||
pe->loadsection(pe, ".debug_pubnames", &d->pubnames);
|
||||
pe->loadsection(pe, ".debug_frame", &d->frame);
|
||||
pe->loadsection(pe, ".debug_ranges", &d->ranges);
|
||||
pe->loadsection(pe, ".debug_str", &d->str);
|
||||
|
|
|
@ -128,4 +128,136 @@ RosSymGetAddressInformation
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
VOID
|
||||
RosSymFreeAggregate(PROSSYM_AGGREGATE Aggregate)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < Aggregate->NumElements; i++) {
|
||||
free(Aggregate->Elements[i].Name);
|
||||
free(Aggregate->Elements[i].Type);
|
||||
}
|
||||
free(Aggregate->Elements);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
RosSymAggregate(PROSSYM_INFO RosSymInfo, PCHAR Type, PROSSYM_AGGREGATE Aggregate)
|
||||
{
|
||||
char *tchar;
|
||||
ulong unit, typeoff = 0;
|
||||
DwarfSym type = { };
|
||||
// Get the first unit
|
||||
if (dwarfaddrtounit(RosSymInfo, RosSymInfo->pe->codestart + RosSymInfo->pe->imagebase, &unit) == -1)
|
||||
return FALSE;
|
||||
|
||||
if (Type[0] == '#') {
|
||||
for (tchar = Type + 1; *tchar; tchar++) {
|
||||
typeoff *= 10;
|
||||
typeoff += *tchar - '0';
|
||||
}
|
||||
if (dwarfseeksym(RosSymInfo, unit, typeoff, &type) == -1)
|
||||
return FALSE;
|
||||
} else if (dwarflookupnameinunit(RosSymInfo, unit, Type, &type) != 0 ||
|
||||
(type.attrs.tag != TagStructType && type.attrs.tag != TagUnionType))
|
||||
return FALSE;
|
||||
|
||||
DwarfSym element = { }, inner = { };
|
||||
int count = 0;
|
||||
|
||||
werrstr("type %s (want %s) type %x\n", type.attrs.name, Type, type.attrs.type);
|
||||
|
||||
if (type.attrs.have.type) {
|
||||
if (dwarfseeksym(RosSymInfo, unit, type.attrs.type, &inner) == -1)
|
||||
return FALSE;
|
||||
type = inner;
|
||||
}
|
||||
|
||||
werrstr("finding members %d\n", type.attrs.haskids);
|
||||
while (dwarfnextsymat(RosSymInfo, &type, &element) != -1) {
|
||||
if (element.attrs.have.name)
|
||||
werrstr("%x %s\n", element.attrs.tag, element.attrs.name);
|
||||
if (element.attrs.tag == TagMember) count++;
|
||||
}
|
||||
|
||||
werrstr("%d members\n", count);
|
||||
|
||||
if (!count) return FALSE;
|
||||
memset(&element, 0, sizeof(element));
|
||||
Aggregate->NumElements = count;
|
||||
Aggregate->Elements = malloc(sizeof(ROSSYM_AGGREGATE_MEMBER) * count);
|
||||
count = 0;
|
||||
werrstr("Enumerating %s\n", Type);
|
||||
while (dwarfnextsymat(RosSymInfo, &type, &element) != -1) {
|
||||
memset(&Aggregate->Elements[count], 0, sizeof(*Aggregate->Elements));
|
||||
if (element.attrs.tag == TagMember) {
|
||||
if (element.attrs.have.name) {
|
||||
Aggregate->Elements[count].Name = malloc(strlen(element.attrs.name) + 1);
|
||||
strcpy(Aggregate->Elements[count].Name, element.attrs.name);
|
||||
}
|
||||
Aggregate->Elements[count].TypeId = element.attrs.type;
|
||||
// Seek our range in loc
|
||||
DwarfBuf locbuf;
|
||||
DwarfBuf instream = { };
|
||||
|
||||
locbuf.d = RosSymInfo;
|
||||
locbuf.addrsize = RosSymInfo->addrsize;
|
||||
|
||||
if (element.attrs.have.datamemberloc) {
|
||||
instream = locbuf;
|
||||
instream.p = element.attrs.datamemberloc.b.data;
|
||||
instream.ep = element.attrs.datamemberloc.b.data + element.attrs.datamemberloc.b.len;
|
||||
werrstr("datamemberloc type %x %p:%x\n",
|
||||
element.attrs.have.datamemberloc,
|
||||
element.attrs.datamemberloc.b.data, element.attrs.datamemberloc.b.len);
|
||||
}
|
||||
|
||||
if (dwarfgetarg(RosSymInfo, element.attrs.name, &instream, 0, NULL, &Aggregate->Elements[count].BaseOffset) == -1)
|
||||
Aggregate->Elements[count].BaseOffset = -1;
|
||||
werrstr("tag %x name %s base %x type %x\n",
|
||||
element.attrs.tag, element.attrs.name,
|
||||
Aggregate->Elements[count].BaseOffset,
|
||||
Aggregate->Elements[count].TypeId);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
for (count = 0; count < Aggregate->NumElements; count++) {
|
||||
memset(&type, 0, sizeof(type));
|
||||
memset(&inner, 0, sizeof(inner));
|
||||
werrstr("seeking type %x (%s) from %s\n",
|
||||
Aggregate->Elements[count].TypeId,
|
||||
Aggregate->Elements[count].Type,
|
||||
Aggregate->Elements[count].Name);
|
||||
dwarfseeksym(RosSymInfo, unit, Aggregate->Elements[count].TypeId, &type);
|
||||
while (type.attrs.have.type && type.attrs.tag != TagPointerType) {
|
||||
if (dwarfseeksym(RosSymInfo, unit, type.attrs.type, &inner) == -1)
|
||||
return FALSE;
|
||||
type = inner;
|
||||
}
|
||||
//dwarfdumpsym(RosSymInfo, &type);
|
||||
if (type.attrs.have.name) {
|
||||
Aggregate->Elements[count].Type = malloc(strlen(type.attrs.name) + 1);
|
||||
strcpy(Aggregate->Elements[count].Type, type.attrs.name);
|
||||
} else {
|
||||
char strbuf[128] = {'#'}, *bufptr = strbuf + 1;
|
||||
ulong idcopy = Aggregate->Elements[count].TypeId;
|
||||
ulong mult = 1;
|
||||
while (mult * 10 < idcopy) mult *= 10;
|
||||
while (mult > 0) {
|
||||
*bufptr++ = '0' + ((idcopy / mult) % 10);
|
||||
mult /= 10;
|
||||
}
|
||||
Aggregate->Elements[count].Type = malloc(strlen(strbuf) + 1);
|
||||
strcpy(Aggregate->Elements[count].Type, strbuf);
|
||||
}
|
||||
if (type.attrs.tag == TagPointerType)
|
||||
Aggregate->Elements[count].Size = RosSymInfo->addrsize;
|
||||
else
|
||||
Aggregate->Elements[count].Size = type.attrs.bytesize;
|
||||
if (type.attrs.have.bitsize)
|
||||
Aggregate->Elements[count].Bits = type.attrs.bitsize;
|
||||
if (type.attrs.have.bitoffset)
|
||||
Aggregate->Elements[count].FirstBit = type.attrs.bitoffset;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -146,6 +146,8 @@ RosSymCreateFromFile(PVOID FileContext, PROSSYM_INFO *RosSymInfo)
|
|||
pe->sect = SectionHeaders;
|
||||
pe->imagebase = pe->loadbase = NtHeaders.OptionalHeader.ImageBase;
|
||||
pe->imagesize = NtHeaders.OptionalHeader.SizeOfImage;
|
||||
pe->codestart = NtHeaders.OptionalHeader.BaseOfCode;
|
||||
pe->datastart = NtHeaders.OptionalHeader.BaseOfData;
|
||||
pe->loadsection = loaddisksection;
|
||||
*RosSymInfo = dwarfopen(pe);
|
||||
|
||||
|
|
|
@ -17,18 +17,18 @@ PeSect *pesection(Pe *pe, const char *name)
|
|||
int i;
|
||||
ANSI_STRING WantName;
|
||||
RtlInitAnsiString(&WantName, name);
|
||||
DPRINT("Searching for section %s\n", name);
|
||||
werrstr("Searching for section %s\n", name);
|
||||
for (i = 0; i < pe->nsections; i++) {
|
||||
PANSI_STRING AnsiString = ANSI_NAME_STRING(&pe->sect[i]);
|
||||
if (WantName.Length == AnsiString->Length &&
|
||||
!memcmp(AnsiString->Buffer, name, WantName.Length)) {
|
||||
DPRINT("Found %s (%d) @ %x (%x)\n", name, i,
|
||||
werrstr("Found %s (%d) @ %x (%x)\n", name, i,
|
||||
((PCHAR)pe->imagebase)+pe->sect[i].VirtualAddress,
|
||||
pe->sect[i].SizeOfRawData);
|
||||
return &pe->sect[i];
|
||||
}
|
||||
}
|
||||
DPRINT("%s not found\n", name);
|
||||
werrstr("%s not found\n", name);
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
@ -84,11 +84,11 @@ loadmemsection(Pe *pe, char *name, DwarfBlock *b)
|
|||
|
||||
if((s = pesection(pe, name)) == nil)
|
||||
return -1;
|
||||
DPRINT("Loading section %s (ImageBase %x RVA %x)\n", name, pe->fd, s->VirtualAddress);
|
||||
werrstr("Loading section %s (ImageBase %x RVA %x)\n", name, pe->fd, s->VirtualAddress);
|
||||
b->data = RosSymAllocMem(s->SizeOfRawData);
|
||||
b->len = s->SizeOfRawData;
|
||||
PCHAR DataSource = ((char *)pe->fd) + s->VirtualAddress;
|
||||
DPRINT("Copying to %x from %x (%x)\n", DataSource, b->data, b->len);
|
||||
werrstr("Copying to %x from %x (%x)\n", DataSource, b->data, b->len);
|
||||
RtlCopyMemory(b->data, DataSource, s->SizeOfRawData);
|
||||
|
||||
return s->SizeOfRawData;
|
||||
|
@ -121,16 +121,16 @@ void xfree(void *v) {
|
|||
|
||||
ulong pefindrva(struct _IMAGE_SECTION_HEADER *SectionHeaders, int NumberOfSections, ulong TargetPhysical) {
|
||||
int i;
|
||||
DPRINT("Finding RVA for Physical %x\n", TargetPhysical);
|
||||
werrstr("Finding RVA for Physical %x\n", TargetPhysical);
|
||||
for (i = 0; i < NumberOfSections; i++) {
|
||||
DPRINT("Section %d name %s Raw %x Virt %x\n",
|
||||
werrstr("Section %d name %s Raw %x Virt %x\n",
|
||||
i,
|
||||
ANSI_NAME_STRING(&SectionHeaders[i])->Buffer,
|
||||
SectionHeaders[i].PointerToRawData,
|
||||
SectionHeaders[i].VirtualAddress);
|
||||
if (TargetPhysical >= SectionHeaders[i].PointerToRawData &&
|
||||
TargetPhysical < SectionHeaders[i].PointerToRawData + SectionHeaders[i].SizeOfRawData) {
|
||||
DPRINT("RVA %x\n", TargetPhysical - SectionHeaders[i].PointerToRawData + SectionHeaders[i].VirtualAddress);
|
||||
werrstr("RVA %x\n", TargetPhysical - SectionHeaders[i].PointerToRawData + SectionHeaders[i].VirtualAddress);
|
||||
return TargetPhysical - SectionHeaders[i].PointerToRawData + SectionHeaders[i].VirtualAddress;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ typedef struct _Pe {
|
|||
u32int (*e4)(const unsigned char *data);
|
||||
u64int (*e8)(const unsigned char *data);
|
||||
ulong imagebase, imagesize, loadbase;
|
||||
ulong codestart, datastart;
|
||||
int (*loadsection)(struct _Pe *pe, char *name, struct DwarfBlock *b);
|
||||
int nsections;
|
||||
struct _IMAGE_SECTION_HEADER *sect;
|
||||
|
|
|
@ -90,6 +90,10 @@ static BOOLEAN KdbpCmdSet(ULONG Argc, PCHAR Argv[]);
|
|||
static BOOLEAN KdbpCmdHelp(ULONG Argc, PCHAR Argv[]);
|
||||
static BOOLEAN KdbpCmdDmesg(ULONG Argc, PCHAR Argv[]);
|
||||
|
||||
#ifdef __ROS_CMAKE__
|
||||
static BOOLEAN KdbpCmdPrintStruct(ULONG Argc, PCHAR Argv[]);
|
||||
#endif
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
static BOOLEAN KdbUseIntelSyntax = FALSE; /* Set to TRUE for intel syntax */
|
||||
|
@ -135,6 +139,9 @@ static const struct
|
|||
{ "sregs", "sregs", "Display status registers.", KdbpCmdRegs },
|
||||
{ "dregs", "dregs", "Display debug registers.", KdbpCmdRegs },
|
||||
{ "bt", "bt [*frameaddr|thread id]", "Prints current backtrace or from given frame addr", KdbpCmdBackTrace },
|
||||
#ifdef __ROS_CMAKE__
|
||||
{ "dt", "dt [mod] [type] [addr]", "Print a struct. Addr is optional.", KdbpCmdPrintStruct },
|
||||
#endif
|
||||
|
||||
/* Flow control */
|
||||
{ NULL, NULL, "Flow control", NULL },
|
||||
|
@ -453,6 +460,142 @@ KdbpCmdEvalExpression(
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef __ROS_CMAKE__
|
||||
|
||||
/*!\brief Print a struct
|
||||
*/
|
||||
static VOID
|
||||
KdbpPrintStructInternal
|
||||
(PROSSYM_INFO Info,
|
||||
PCHAR Indent,
|
||||
BOOLEAN DoRead,
|
||||
PVOID BaseAddress,
|
||||
PROSSYM_AGGREGATE Aggregate)
|
||||
{
|
||||
ULONG i;
|
||||
ULONGLONG Result;
|
||||
PROSSYM_AGGREGATE_MEMBER Member;
|
||||
ULONG IndentLen = strlen(Indent);
|
||||
ROSSYM_AGGREGATE MemberAggregate = { };
|
||||
|
||||
for (i = 0; i < Aggregate->NumElements; i++) {
|
||||
Member = &Aggregate->Elements[i];
|
||||
KdbpPrint("%s%p+%x: %s", Indent, ((PCHAR)BaseAddress) + Member->BaseOffset, Member->Size, Member->Name ? Member->Name : "<anoymous>");
|
||||
if (DoRead) {
|
||||
if (!strcmp(Member->Type, "_UNICODE_STRING")) {
|
||||
KdbpPrint("\"%wZ\"\n", ((PCHAR)BaseAddress) + Member->BaseOffset);
|
||||
continue;
|
||||
} else if (!strcmp(Member->Type, "PUNICODE_STRING")) {
|
||||
KdbpPrint("\"%wZ\"\n", *(((PUNICODE_STRING*)((PCHAR)BaseAddress) + Member->BaseOffset)));
|
||||
continue;
|
||||
}
|
||||
switch (Member->Size) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 8: {
|
||||
Result = 0;
|
||||
if (NT_SUCCESS(KdbpSafeReadMemory(&Result, ((PCHAR)BaseAddress) + Member->BaseOffset, Member->Size))) {
|
||||
if (Member->Bits) {
|
||||
Result >>= Member->FirstBit;
|
||||
Result &= ((1 << Member->Bits) - 1);
|
||||
}
|
||||
KdbpPrint(" %lx\n", Result);
|
||||
}
|
||||
else goto readfail;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (Member->Size < 8) {
|
||||
if (NT_SUCCESS(KdbpSafeReadMemory(&Result, ((PCHAR)BaseAddress) + Member->BaseOffset, Member->Size))) {
|
||||
int j;
|
||||
for (j = 0; j < Member->Size; j++) {
|
||||
KdbpPrint(" %02x", (int)(Result & 0xff));
|
||||
Result >>= 8;
|
||||
}
|
||||
} else goto readfail;
|
||||
} else {
|
||||
KdbpPrint(" %s @ %p {\n", Member->Type, ((PCHAR)BaseAddress) + Member->BaseOffset);
|
||||
Indent[IndentLen] = ' ';
|
||||
if (RosSymAggregate(Info, Member->Type, &MemberAggregate)) {
|
||||
KdbpPrintStructInternal(Info, Indent, DoRead, ((PCHAR)BaseAddress) + Member->BaseOffset, &MemberAggregate);
|
||||
RosSymFreeAggregate(&MemberAggregate);
|
||||
}
|
||||
Indent[IndentLen] = 0;
|
||||
KdbpPrint("%s}\n", Indent);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
readfail:
|
||||
if (Member->Size <= 8) {
|
||||
KdbpPrint(" ??\n");
|
||||
} else {
|
||||
KdbpPrint(" %s @ %x {\n", Member->Type, Member->BaseOffset);
|
||||
Indent[IndentLen] = ' ';
|
||||
if (RosSymAggregate(Info, Member->Type, &MemberAggregate)) {
|
||||
KdbpPrintStructInternal(Info, Indent, DoRead, BaseAddress, &MemberAggregate);
|
||||
RosSymFreeAggregate(&MemberAggregate);
|
||||
}
|
||||
Indent[IndentLen] = 0;
|
||||
KdbpPrint("%s}\n", Indent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PROSSYM_INFO KdbpSymFindCachedFile(PUNICODE_STRING ModName);
|
||||
|
||||
static BOOLEAN
|
||||
KdbpCmdPrintStruct(
|
||||
ULONG Argc,
|
||||
PCHAR Argv[])
|
||||
{
|
||||
int i;
|
||||
ULONGLONG Result = 0;
|
||||
PVOID BaseAddress = 0;
|
||||
ROSSYM_AGGREGATE Aggregate = { };
|
||||
UNICODE_STRING ModName = { };
|
||||
ANSI_STRING AnsiName = { };
|
||||
CHAR Indent[100] = { };
|
||||
if (Argc < 3) goto end;
|
||||
AnsiName.Length = AnsiName.MaximumLength = strlen(Argv[1]);
|
||||
AnsiName.Buffer = Argv[1];
|
||||
RtlAnsiStringToUnicodeString(&ModName, &AnsiName, TRUE);
|
||||
PROSSYM_INFO Info = KdbpSymFindCachedFile(&ModName);
|
||||
|
||||
if (!Info || !RosSymAggregate(Info, Argv[2], &Aggregate)) {
|
||||
DPRINT1("Could not get aggregate\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// Get an argument for location if it was given
|
||||
if (Argc > 3) {
|
||||
ULONG len;
|
||||
PCHAR ArgStart = Argv[3];
|
||||
DPRINT1("Trying to get expression\n");
|
||||
for (i = 3; i < Argc - 1; i++)
|
||||
{
|
||||
len = strlen(Argv[i]);
|
||||
Argv[i][len] = ' ';
|
||||
}
|
||||
|
||||
/* Evaluate the expression */
|
||||
DPRINT1("Arg: %s\n", ArgStart);
|
||||
if (KdbpEvaluateExpression(ArgStart, strlen(ArgStart), &Result)) {
|
||||
BaseAddress = (PVOID)(ULONG_PTR)Result;
|
||||
DPRINT1("BaseAddress: %p\n", BaseAddress);
|
||||
}
|
||||
}
|
||||
DPRINT1("BaseAddress %p\n", BaseAddress);
|
||||
KdbpPrintStructInternal(Info, Indent, !!BaseAddress, BaseAddress, &Aggregate);
|
||||
end:
|
||||
RosSymFreeAggregate(&Aggregate);
|
||||
RtlFreeUnicodeString(&ModName);
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!\brief Display list of active debug channels
|
||||
*/
|
||||
static BOOLEAN
|
||||
|
|
|
@ -359,7 +359,7 @@ KdbSymGetAddressInformation(
|
|||
*
|
||||
* \sa KdbpSymAddCachedFile
|
||||
*/
|
||||
static PROSSYM_INFO
|
||||
PROSSYM_INFO
|
||||
KdbpSymFindCachedFile(
|
||||
IN PUNICODE_STRING FileName)
|
||||
{
|
||||
|
@ -405,7 +405,7 @@ KdbpSymAddCachedFile(
|
|||
{
|
||||
PIMAGE_SYMBOL_INFO_CACHE CacheEntry;
|
||||
|
||||
DPRINT("Adding symbol file: RosSymInfo = %p\n", RosSymInfo);
|
||||
DPRINT("Adding symbol file: %wZ RosSymInfo = %p\n", FileName, RosSymInfo);
|
||||
|
||||
/* allocate entry */
|
||||
CacheEntry = ExAllocatePoolWithTag(NonPagedPool, sizeof (IMAGE_SYMBOL_INFO_CACHE), TAG_KDBS);
|
||||
|
@ -416,6 +416,7 @@ KdbpSymAddCachedFile(
|
|||
CacheEntry->FileName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
|
||||
FileName->Length,
|
||||
TAG_KDBS);
|
||||
CacheEntry->FileName.MaximumLength = FileName->Length;
|
||||
RtlCopyUnicodeString(&CacheEntry->FileName, FileName);
|
||||
ASSERT(CacheEntry->FileName.Buffer);
|
||||
CacheEntry->RefCount = 1;
|
||||
|
@ -476,7 +477,7 @@ KdbpSymRemoveCachedFile(
|
|||
*
|
||||
* \sa KdbpSymUnloadModuleSymbols
|
||||
*/
|
||||
static VOID
|
||||
VOID
|
||||
KdbpSymLoadModuleSymbols(
|
||||
IN PUNICODE_STRING FileName,
|
||||
OUT PROSSYM_INFO *RosSymInfo)
|
||||
|
@ -508,7 +509,7 @@ KdbpSymLoadModuleSymbols(
|
|||
/* Open the file */
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
FileName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
|
@ -519,10 +520,10 @@ KdbpSymLoadModuleSymbols(
|
|||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT);
|
||||
FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Could not open image file: %wZ\n", FileName);
|
||||
DPRINT("Could not open image file(%x): %wZ\n", Status, FileName);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -548,8 +549,17 @@ KdbpSymLoadModuleSymbols(
|
|||
if (RosSymCreateFromFile(FileContext, RosSymInfo))
|
||||
{
|
||||
/* add file to cache */
|
||||
KdbpSymAddCachedFile(FileName, *RosSymInfo);
|
||||
DPRINT("Installed symbols: %wZ %p\n", FileName, *RosSymInfo);
|
||||
int i;
|
||||
UNICODE_STRING TruncatedName = *FileName;
|
||||
for (i = (TruncatedName.Length / sizeof(WCHAR)) - 1; i >= 0; i--)
|
||||
if (TruncatedName.Buffer[i] == '\\') {
|
||||
TruncatedName.Buffer += i+1;
|
||||
TruncatedName.Length -= (i+1)*sizeof(WCHAR);
|
||||
TruncatedName.MaximumLength -= (i+1)*sizeof(WCHAR);
|
||||
break;
|
||||
}
|
||||
KdbpSymAddCachedFile(&TruncatedName, *RosSymInfo);
|
||||
DPRINT("Installed symbols: %wZ %p\n", &TruncatedName, *RosSymInfo);
|
||||
}
|
||||
KdbpReleaseFileForSymbols(FileContext);
|
||||
}
|
||||
|
@ -569,13 +579,45 @@ KdbSymProcessSymbols(
|
|||
}
|
||||
|
||||
/* Remove symbol info if it already exists */
|
||||
if (LdrEntry->PatchInformation)
|
||||
if (LdrEntry->PatchInformation) {
|
||||
KdbpSymRemoveCachedFile(LdrEntry->PatchInformation);
|
||||
}
|
||||
|
||||
/* Error loading symbol info, try to load it from file */
|
||||
KdbpSymLoadModuleSymbols(&LdrEntry->FullDllName,
|
||||
(PROSSYM_INFO*)&LdrEntry->PatchInformation);
|
||||
|
||||
if (!LdrEntry->PatchInformation) {
|
||||
// HACK: module dll names don't identify the real files
|
||||
UNICODE_STRING SystemRoot;
|
||||
UNICODE_STRING ModuleNameCopy;
|
||||
RtlInitUnicodeString(&SystemRoot, L"\\SystemRoot\\system32\\Drivers\\");
|
||||
ModuleNameCopy.Length = 0;
|
||||
ModuleNameCopy.MaximumLength =
|
||||
LdrEntry->BaseDllName.MaximumLength + SystemRoot.MaximumLength;
|
||||
ModuleNameCopy.Buffer = ExAllocatePool(NonPagedPool, SystemRoot.MaximumLength + LdrEntry->BaseDllName.MaximumLength);
|
||||
RtlCopyUnicodeString(&ModuleNameCopy, &SystemRoot);
|
||||
RtlCopyMemory
|
||||
(ModuleNameCopy.Buffer + ModuleNameCopy.Length / sizeof(WCHAR),
|
||||
LdrEntry->BaseDllName.Buffer,
|
||||
LdrEntry->BaseDllName.Length);
|
||||
ModuleNameCopy.Length += LdrEntry->BaseDllName.Length;
|
||||
KdbpSymLoadModuleSymbols(&ModuleNameCopy,
|
||||
(PROSSYM_INFO*)&LdrEntry->PatchInformation);
|
||||
if (!LdrEntry->PatchInformation) {
|
||||
SystemRoot.Length -= strlen("Drivers\\") * sizeof(WCHAR);
|
||||
RtlCopyUnicodeString(&ModuleNameCopy, &SystemRoot);
|
||||
RtlCopyMemory
|
||||
(ModuleNameCopy.Buffer + ModuleNameCopy.Length / sizeof(WCHAR),
|
||||
LdrEntry->BaseDllName.Buffer,
|
||||
LdrEntry->BaseDllName.Length);
|
||||
ModuleNameCopy.Length += LdrEntry->BaseDllName.Length;
|
||||
KdbpSymLoadModuleSymbols(&ModuleNameCopy,
|
||||
(PROSSYM_INFO*)&LdrEntry->PatchInformation);
|
||||
}
|
||||
RtlFreeUnicodeString(&ModuleNameCopy);
|
||||
}
|
||||
|
||||
/* It already added symbols to cache */
|
||||
DPRINT("Installed symbols: %wZ@%p-%p %p\n",
|
||||
&LdrEntry->BaseDllName,
|
||||
|
|
Loading…
Reference in a new issue