mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 07:42:59 +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"
|
#define ROSSYM_SECTION_NAME ".rossym"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct _ROSSYM_HEADER {
|
typedef struct _ROSSYM_HEADER {
|
||||||
unsigned long SymbolsOffset;
|
unsigned long SymbolsOffset;
|
||||||
unsigned long SymbolsLength;
|
unsigned long SymbolsLength;
|
||||||
|
@ -86,6 +90,18 @@ typedef struct _ROSSYM_LINEINFO {
|
||||||
ROSSYM_PARAMETER Parameters[16];
|
ROSSYM_PARAMETER Parameters[16];
|
||||||
} ROSSYM_LINEINFO, *PROSSYM_LINEINFO;
|
} 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 {
|
typedef struct _ROSSYM_CALLBACKS {
|
||||||
PVOID (*AllocMemProc)(ULONG_PTR Size);
|
PVOID (*AllocMemProc)(ULONG_PTR Size);
|
||||||
VOID (*FreeMemProc)(PVOID Area);
|
VOID (*FreeMemProc)(PVOID Area);
|
||||||
|
@ -132,6 +148,13 @@ BOOLEAN RosSymGetAddressInformation(PROSSYM_INFO RosSymInfo,
|
||||||
#endif
|
#endif
|
||||||
VOID RosSymFreeInfo(PROSSYM_LINEINFO RosSymLineInfo);
|
VOID RosSymFreeInfo(PROSSYM_LINEINFO RosSymLineInfo);
|
||||||
VOID RosSymDelete(PROSSYM_INFO RosSymInfo);
|
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 */
|
#endif /* REACTOS_ROSSYM_H_INCLUDED */
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,19 @@ typedef long long s64int;
|
||||||
typedef ulong size_t;
|
typedef ulong size_t;
|
||||||
#endif
|
#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 offsetof(x,y) FIELD_OFFSET(x,y)
|
||||||
#define nil (0)
|
#define nil (0)
|
||||||
|
|
||||||
|
@ -32,7 +45,13 @@ void *RosSymRealloc(void *mem, ulong newsize);
|
||||||
void xfree(void *v);
|
void xfree(void *v);
|
||||||
|
|
||||||
#define werrstr(str, ...) DPRINT(str "\n" ,##__VA_ARGS__)
|
#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 malloc(x) RosSymAllocMem(x)
|
||||||
#define mallocz(x,y) RosSymAllocMemZero(x,y)
|
#define mallocz(x,y) RosSymAllocMemZero(x,y)
|
||||||
|
|
|
@ -483,5 +483,6 @@ struct DwarfStack
|
||||||
DwarfAbbrev *dwarfgetabbrev(Dwarf*, ulong, ulong);
|
DwarfAbbrev *dwarfgetabbrev(Dwarf*, ulong, ulong);
|
||||||
|
|
||||||
int dwarfgetinfounit(Dwarf*, ulong, DwarfBlock*);
|
int dwarfgetinfounit(Dwarf*, ulong, DwarfBlock*);
|
||||||
|
void dwarfdumpsym(Dwarf *d, DwarfSym *s);
|
||||||
|
|
||||||
#define MAXIMUM_DWARF_NAME_SIZE 64
|
#define MAXIMUM_DWARF_NAME_SIZE 64
|
||||||
|
|
|
@ -83,7 +83,7 @@ parseabbrevs(Dwarf *d, ulong off, DwarfAbbrev *abbrev, DwarfAttr *attr, int *pna
|
||||||
if(num == 0)
|
if(num == 0)
|
||||||
break;
|
break;
|
||||||
tag = dwarfget128(&b);
|
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);
|
haskids = dwarfget1(&b);
|
||||||
for(i=0;; i++){
|
for(i=0;; i++){
|
||||||
name = dwarfget128(&b);
|
name = dwarfget128(&b);
|
||||||
|
@ -120,11 +120,12 @@ findabbrev(DwarfAbbrev *a, int na, ulong num)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i=0; i<na; i++)
|
for(i=0; i<na; i++) {
|
||||||
if(a[i].num == num)
|
if(a[i].num == num) {
|
||||||
return &a[i];
|
return &a[i];
|
||||||
assert(0);
|
}
|
||||||
werrstr("abbrev not found");
|
}
|
||||||
|
werrstr("abbrev not found (%x)", na);
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +134,7 @@ dwarfgetabbrev(Dwarf *d, ulong off, ulong num)
|
||||||
{
|
{
|
||||||
DwarfAbbrev *a;
|
DwarfAbbrev *a;
|
||||||
int na;
|
int na;
|
||||||
|
werrstr("want num %d\n", num);
|
||||||
if((na = loadabbrevs(d, off, &a)) < 0){
|
if((na = loadabbrevs(d, off, &a)) < 0){
|
||||||
werrstr("loadabbrevs: %r");
|
werrstr("loadabbrevs: %r");
|
||||||
return nil;
|
return nil;
|
||||||
|
|
|
@ -128,9 +128,11 @@ dwarflookupnameinunit(Dwarf *d, ulong unit, char *name, DwarfSym *s)
|
||||||
DwarfSym compunit = { };
|
DwarfSym compunit = { };
|
||||||
if(dwarfenumunit(d, unit, &compunit) < 0)
|
if(dwarfenumunit(d, unit, &compunit) < 0)
|
||||||
return -1;
|
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)
|
if(s->attrs.name && strcmp(s->attrs.name, name) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
werrstr("symbol '%s' not found", name);
|
werrstr("symbol '%s' not found", name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -188,7 +190,10 @@ dwarfseeksym(Dwarf *d, ulong unit, ulong off, DwarfSym *s)
|
||||||
DwarfSym compunit = { };
|
DwarfSym compunit = { };
|
||||||
if(dwarfenumunit(d, unit, &compunit) < 0)
|
if(dwarfenumunit(d, unit, &compunit) < 0)
|
||||||
return -1;
|
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.p = d->info.data + unit + off;
|
||||||
|
s->b.ep = compunit.b.ep;
|
||||||
if(dwarfnextsymat(d, &compunit, s) == -1)
|
if(dwarfnextsymat(d, &compunit, s) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
werrstr("dwarfseeksym: unit %x off %x, tag %x", unit, off, s->attrs.tag);
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
s->b.ep = s->b.p+len;
|
s->b.ep = s->b.p+len;
|
||||||
if((i=dwarfget2(&s->b)) != 2)
|
if((i=dwarfget2(&s->b)) > 4)
|
||||||
goto badheader;
|
goto badheader;
|
||||||
aoff = dwarfget4(&s->b);
|
aoff = dwarfget4(&s->b);
|
||||||
s->b.addrsize = dwarfget1(&s->b);
|
s->b.addrsize = dwarfget1(&s->b);
|
||||||
|
@ -258,15 +263,19 @@ dwarfnextsym(Dwarf *d, DwarfSym *s)
|
||||||
ulong num;
|
ulong num;
|
||||||
DwarfAbbrev *a;
|
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);
|
num = dwarfget128(&s->b);
|
||||||
|
werrstr("abbrev num %x\n", num);
|
||||||
s->num = num;
|
s->num = num;
|
||||||
if(num == 0){
|
if(num == 0){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
a = dwarfgetabbrev(d, s->aoff, num);
|
a = dwarfgetabbrev(d, s->aoff, num);
|
||||||
|
werrstr("a %p\n", a);
|
||||||
if(a == nil){
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,6 +286,7 @@ dwarfnextsym(Dwarf *d, DwarfSym *s)
|
||||||
if (s->attrs.haskids) {
|
if (s->attrs.haskids) {
|
||||||
DwarfSym childSkip = { };
|
DwarfSym childSkip = { };
|
||||||
s->childoff = s->b.p - d->info.data;
|
s->childoff = s->b.p - d->info.data;
|
||||||
|
werrstr("Set childoff at %x\n", s->childoff);
|
||||||
int r = dwarfnextsymat(d, s, &childSkip);
|
int r = dwarfnextsymat(d, s, &childSkip);
|
||||||
while (r == 0) {
|
while (r == 0) {
|
||||||
r = dwarfnextsym(d, &childSkip);
|
r = dwarfnextsym(d, &childSkip);
|
||||||
|
@ -316,6 +326,7 @@ dwarfnextsymat(Dwarf *d, DwarfSym *parent, DwarfSym *child)
|
||||||
if (!child->b.d) {
|
if (!child->b.d) {
|
||||||
child->b = parent->b;
|
child->b = parent->b;
|
||||||
child->b.p = parent->childoff + parent->b.d->info.data;
|
child->b.p = parent->childoff + parent->b.d->info.data;
|
||||||
|
werrstr("Rewound to childoff %x\n", parent->childoff);
|
||||||
}
|
}
|
||||||
|
|
||||||
return dwarfnextsym(d, child);
|
return dwarfnextsym(d, child);
|
||||||
|
@ -323,76 +334,78 @@ dwarfnextsymat(Dwarf *d, DwarfSym *parent, DwarfSym *child)
|
||||||
|
|
||||||
typedef struct Parse Parse;
|
typedef struct Parse Parse;
|
||||||
struct Parse {
|
struct Parse {
|
||||||
|
const char *namestr;
|
||||||
int name;
|
int name;
|
||||||
int off;
|
int off;
|
||||||
int haveoff;
|
int haveoff;
|
||||||
int type;
|
int type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define ATTR(x) (#x)+9, x
|
||||||
#define OFFSET(x) offsetof(DwarfAttrs, x), offsetof(DwarfAttrs, have.x)
|
#define OFFSET(x) offsetof(DwarfAttrs, x), offsetof(DwarfAttrs, have.x)
|
||||||
|
|
||||||
static Parse plist[] = { /* Font Tab 4 */
|
static Parse plist[] = { /* Font Tab 4 */
|
||||||
{ DwarfAttrAbstractOrigin, OFFSET(abstractorigin), TReference },
|
{ ATTR(DwarfAttrAbstractOrigin), OFFSET(abstractorigin), TReference },
|
||||||
{ DwarfAttrAccessibility, OFFSET(accessibility), TConstant },
|
{ ATTR(DwarfAttrAccessibility), OFFSET(accessibility), TConstant },
|
||||||
{ DwarfAttrAddrClass, OFFSET(addrclass), TConstant },
|
{ ATTR(DwarfAttrAddrClass), OFFSET(addrclass), TConstant },
|
||||||
{ DwarfAttrArtificial, OFFSET(isartificial), TFlag },
|
{ ATTR(DwarfAttrBaseTypes), OFFSET(basetypes), TReference },
|
||||||
{ DwarfAttrBaseTypes, OFFSET(basetypes), TReference },
|
{ ATTR(DwarfAttrBitOffset), OFFSET(bitoffset), TConstant },
|
||||||
{ DwarfAttrBitOffset, OFFSET(bitoffset), TConstant },
|
{ ATTR(DwarfAttrBitSize), OFFSET(bitsize), TConstant },
|
||||||
{ DwarfAttrBitSize, OFFSET(bitsize), TConstant },
|
{ ATTR(DwarfAttrByteSize), OFFSET(bytesize), TConstant },
|
||||||
{ DwarfAttrByteSize, OFFSET(bytesize), TConstant },
|
{ ATTR(DwarfAttrCalling), OFFSET(calling), TConstant },
|
||||||
{ DwarfAttrCalling, OFFSET(calling), TConstant },
|
{ ATTR(DwarfAttrCommonRef), OFFSET(commonref), TReference },
|
||||||
{ DwarfAttrCommonRef, OFFSET(commonref), TReference },
|
{ ATTR(DwarfAttrCompDir), OFFSET(compdir), TString },
|
||||||
{ DwarfAttrCompDir, OFFSET(compdir), TString },
|
{ ATTR(DwarfAttrConstValue), OFFSET(constvalue), TString|TConstant|TBlock },
|
||||||
{ DwarfAttrConstValue, OFFSET(constvalue), TString|TConstant|TBlock },
|
{ ATTR(DwarfAttrContainingType), OFFSET(containingtype), TReference },
|
||||||
{ DwarfAttrContainingType, OFFSET(containingtype), TReference },
|
{ ATTR(DwarfAttrCount), OFFSET(count), TConstant|TReference },
|
||||||
{ DwarfAttrCount, OFFSET(count), TConstant|TReference },
|
{ ATTR(DwarfAttrDataMemberLoc), OFFSET(datamemberloc), TBlock|TConstant|TReference },
|
||||||
{ DwarfAttrDataMemberLoc, OFFSET(datamemberloc), TBlock|TConstant|TReference },
|
{ ATTR(DwarfAttrDeclColumn), OFFSET(declcolumn), TConstant },
|
||||||
{ DwarfAttrDeclColumn, OFFSET(declcolumn), TConstant },
|
{ ATTR(DwarfAttrDeclFile), OFFSET(declfile), TConstant },
|
||||||
{ DwarfAttrDeclFile, OFFSET(declfile), TConstant },
|
{ ATTR(DwarfAttrDeclLine), OFFSET(declline), TConstant },
|
||||||
{ DwarfAttrDeclLine, OFFSET(declline), TConstant },
|
{ ATTR(DwarfAttrDefaultValue), OFFSET(defaultvalue), TReference },
|
||||||
{ DwarfAttrDeclaration, OFFSET(isdeclaration), TFlag },
|
{ ATTR(DwarfAttrDiscr), OFFSET(discr), TReference },
|
||||||
{ DwarfAttrDefaultValue, OFFSET(defaultvalue), TReference },
|
{ ATTR(DwarfAttrDiscrList), OFFSET(discrlist), TBlock },
|
||||||
{ DwarfAttrDiscr, OFFSET(discr), TReference },
|
{ ATTR(DwarfAttrDiscrValue), OFFSET(discrvalue), TConstant },
|
||||||
{ DwarfAttrDiscrList, OFFSET(discrlist), TBlock },
|
{ ATTR(DwarfAttrEncoding), OFFSET(encoding), TConstant },
|
||||||
{ DwarfAttrDiscrValue, OFFSET(discrvalue), TConstant },
|
{ ATTR(DwarfAttrFrameBase), OFFSET(framebase), TBlock|TConstant },
|
||||||
{ DwarfAttrEncoding, OFFSET(encoding), TConstant },
|
{ ATTR(DwarfAttrFriend), OFFSET(friend), TReference },
|
||||||
{ DwarfAttrExternal, OFFSET(isexternal), TFlag },
|
{ ATTR(DwarfAttrHighpc), OFFSET(highpc), TAddress },
|
||||||
{ DwarfAttrFrameBase, OFFSET(framebase), TBlock|TConstant },
|
{ ATTR(DwarfAttrEntrypc), OFFSET(entrypc), TAddress },
|
||||||
{ DwarfAttrFriend, OFFSET(friend), TReference },
|
{ ATTR(DwarfAttrIdentifierCase), OFFSET(identifiercase), TConstant },
|
||||||
{ DwarfAttrHighpc, OFFSET(highpc), TAddress },
|
{ ATTR(DwarfAttrImport), OFFSET(import), TReference },
|
||||||
{ DwarfAttrEntrypc, OFFSET(entrypc), TAddress },
|
{ ATTR(DwarfAttrInline), OFFSET(inlined), TConstant },
|
||||||
{ DwarfAttrIdentifierCase, OFFSET(identifiercase), TConstant },
|
{ ATTR(DwarfAttrArtificial), OFFSET(isartificial), TFlag },
|
||||||
{ DwarfAttrImport, OFFSET(import), TReference },
|
{ ATTR(DwarfAttrDeclaration), OFFSET(isdeclaration), TFlag },
|
||||||
{ DwarfAttrInline, OFFSET(inlined), TConstant },
|
{ ATTR(DwarfAttrExternal), OFFSET(isexternal), TFlag },
|
||||||
{ DwarfAttrIsOptional, OFFSET(isoptional), TFlag },
|
{ ATTR(DwarfAttrIsOptional), OFFSET(isoptional), TFlag },
|
||||||
{ DwarfAttrLanguage, OFFSET(language), TConstant },
|
{ ATTR(DwarfAttrPrototyped), OFFSET(isprototyped), TFlag },
|
||||||
{ DwarfAttrLocation, OFFSET(location), TReference|TBlock },
|
{ ATTR(DwarfAttrVarParam), OFFSET(isvarparam), TFlag },
|
||||||
{ DwarfAttrLowerBound, OFFSET(lowerbound), TConstant|TReference },
|
{ ATTR(DwarfAttrLanguage), OFFSET(language), TConstant },
|
||||||
{ DwarfAttrLowpc, OFFSET(lowpc), TAddress },
|
{ ATTR(DwarfAttrLocation), OFFSET(location), TReference|TBlock },
|
||||||
{ DwarfAttrMacroInfo, OFFSET(macroinfo), TConstant },
|
{ ATTR(DwarfAttrLowerBound), OFFSET(lowerbound), TConstant|TReference },
|
||||||
{ DwarfAttrName, OFFSET(name), TString },
|
{ ATTR(DwarfAttrLowpc), OFFSET(lowpc), TAddress },
|
||||||
{ DwarfAttrNamelistItem, OFFSET(namelistitem), TBlock },
|
{ ATTR(DwarfAttrMacroInfo), OFFSET(macroinfo), TConstant },
|
||||||
{ DwarfAttrOrdering, OFFSET(ordering), TConstant },
|
{ ATTR(DwarfAttrName), OFFSET(name), TString },
|
||||||
{ DwarfAttrPriority, OFFSET(priority), TReference },
|
{ ATTR(DwarfAttrNamelistItem), OFFSET(namelistitem), TBlock },
|
||||||
{ DwarfAttrProducer, OFFSET(producer), TString },
|
{ ATTR(DwarfAttrOrdering), OFFSET(ordering), TConstant },
|
||||||
{ DwarfAttrPrototyped, OFFSET(isprototyped), TFlag },
|
{ ATTR(DwarfAttrPriority), OFFSET(priority), TReference },
|
||||||
{ DwarfAttrRanges, OFFSET(ranges), TReference },
|
{ ATTR(DwarfAttrProducer), OFFSET(producer), TString },
|
||||||
{ DwarfAttrReturnAddr, OFFSET(returnaddr), TBlock|TConstant },
|
{ ATTR(DwarfAttrRanges), OFFSET(ranges), TReference },
|
||||||
{ DwarfAttrSegment, OFFSET(segment), TBlock|TConstant },
|
{ ATTR(DwarfAttrReturnAddr), OFFSET(returnaddr), TBlock|TConstant },
|
||||||
{ DwarfAttrSibling, OFFSET(sibling), TReference },
|
{ ATTR(DwarfAttrSegment), OFFSET(segment), TBlock|TConstant },
|
||||||
{ DwarfAttrSpecification, OFFSET(specification), TReference },
|
{ ATTR(DwarfAttrSibling), OFFSET(sibling), TReference },
|
||||||
{ DwarfAttrStartScope, OFFSET(startscope), TConstant },
|
{ ATTR(DwarfAttrSpecification), OFFSET(specification), TReference },
|
||||||
{ DwarfAttrStaticLink, OFFSET(staticlink), TBlock|TConstant },
|
{ ATTR(DwarfAttrStartScope), OFFSET(startscope), TConstant },
|
||||||
{ DwarfAttrStmtList, OFFSET(stmtlist), TConstant },
|
{ ATTR(DwarfAttrStaticLink), OFFSET(staticlink), TBlock|TConstant },
|
||||||
{ DwarfAttrStrideSize, OFFSET(stridesize), TConstant },
|
{ ATTR(DwarfAttrStmtList), OFFSET(stmtlist), TConstant },
|
||||||
{ DwarfAttrStringLength, OFFSET(stringlength), TBlock|TConstant },
|
{ ATTR(DwarfAttrStrideSize), OFFSET(stridesize), TConstant },
|
||||||
{ DwarfAttrType, OFFSET(type), TReference },
|
{ ATTR(DwarfAttrStringLength), OFFSET(stringlength), TBlock|TConstant },
|
||||||
{ DwarfAttrUpperBound, OFFSET(upperbound), TConstant|TReference },
|
{ ATTR(DwarfAttrType), OFFSET(type), TReference },
|
||||||
{ DwarfAttrUseLocation, OFFSET(uselocation), TBlock|TConstant },
|
{ ATTR(DwarfAttrUpperBound), OFFSET(upperbound), TConstant|TReference },
|
||||||
{ DwarfAttrVarParam, OFFSET(isvarparam), TFlag },
|
{ ATTR(DwarfAttrUseLocation), OFFSET(uselocation), TBlock|TConstant },
|
||||||
{ DwarfAttrVirtuality, OFFSET(virtuality), TConstant },
|
{ ATTR(DwarfAttrVirtuality), OFFSET(virtuality), TConstant },
|
||||||
{ DwarfAttrVisibility, OFFSET(visibility), TConstant },
|
{ ATTR(DwarfAttrVisibility), OFFSET(visibility), TConstant },
|
||||||
{ DwarfAttrVtableElemLoc, OFFSET(vtableelemloc), TBlock|TReference },
|
{ 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++){
|
for(i=0; i<a->nattr; i++){
|
||||||
n = a->attr[i].name;
|
n = a->attr[i].name;
|
||||||
f = a->attr[i].form;
|
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(n < 0 || n >= DwarfAttrMax || ptab[n].name==0) {
|
||||||
if (skipform(d, b, f) < 0) {
|
if (skipform(d, b, f) < 0) {
|
||||||
if(++nbad == 1)
|
if(++nbad == 1)
|
||||||
|
@ -436,11 +450,12 @@ parseattrs(Dwarf *d, DwarfBuf *b, ulong tag, ulong unit, DwarfAbbrev *a, DwarfAt
|
||||||
got = TFlag;
|
got = TFlag;
|
||||||
else if((ptab[n].type&TString) && getstring(d, b, f, v) >= 0)
|
else if((ptab[n].type&TString) && getstring(d, b, f, v) >= 0)
|
||||||
got = TString;
|
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;
|
got = TBlock;
|
||||||
else {
|
} else {
|
||||||
|
werrstr("Skipping form %x\n", f);
|
||||||
if(skipform(d, b, f) < 0){
|
if(skipform(d, b, f) < 0){
|
||||||
if(++nbad == 1)
|
//if(++nbad == 1)
|
||||||
werrstr("dwarf parse attrs: cannot skip form %d", f);
|
werrstr("dwarf parse attrs: cannot skip form %d", f);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -451,6 +466,10 @@ parseattrs(Dwarf *d, DwarfBuf *b, ulong tag, ulong unit, DwarfAbbrev *a, DwarfAt
|
||||||
#endif
|
#endif
|
||||||
*((uchar*)attrs+ptab[n].haveoff) = got;
|
*((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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -651,6 +670,7 @@ int dwarfgetarg(Dwarf *d, const char *name, DwarfBuf *buf, ulong cfa, PROSSYM_RE
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
DwarfStack stack = { };
|
DwarfStack stack = { };
|
||||||
stackinit(&stack);
|
stackinit(&stack);
|
||||||
|
stackpush(&stack, cfa);
|
||||||
while (buf->p < buf->ep) {
|
while (buf->p < buf->ep) {
|
||||||
int opcode = dwarfget1(buf);
|
int opcode = dwarfget1(buf);
|
||||||
werrstr("opcode %x", opcode);
|
werrstr("opcode %x", opcode);
|
||||||
|
@ -951,6 +971,25 @@ int dwarfargvalue(Dwarf *d, DwarfSym *proc, ulong pc, ulong cfa, PROSSYM_REGISTE
|
||||||
return 0;
|
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
|
int
|
||||||
dwarfgetparams(Dwarf *d, DwarfSym *s, ulong pc, int pnum, DwarfParam *paramblocks)
|
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
|
if(pe->loadsection(pe, ".debug_abbrev", &d->abbrev) < 0
|
||||||
|| pe->loadsection(pe, ".debug_aranges", &d->aranges) < 0
|
|| pe->loadsection(pe, ".debug_aranges", &d->aranges) < 0
|
||||||
|| pe->loadsection(pe, ".debug_line", &d->line) < 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_info", &d->info) < 0
|
||||||
|| pe->loadsection(pe, ".debug_loc", &d->loc) < 0)
|
|| pe->loadsection(pe, ".debug_loc", &d->loc) < 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
pe->loadsection(pe, ".debug_pubnames", &d->pubnames);
|
||||||
pe->loadsection(pe, ".debug_frame", &d->frame);
|
pe->loadsection(pe, ".debug_frame", &d->frame);
|
||||||
pe->loadsection(pe, ".debug_ranges", &d->ranges);
|
pe->loadsection(pe, ".debug_ranges", &d->ranges);
|
||||||
pe->loadsection(pe, ".debug_str", &d->str);
|
pe->loadsection(pe, ".debug_str", &d->str);
|
||||||
|
|
|
@ -128,4 +128,136 @@ RosSymGetAddressInformation
|
||||||
return TRUE;
|
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 */
|
/* EOF */
|
||||||
|
|
|
@ -146,6 +146,8 @@ RosSymCreateFromFile(PVOID FileContext, PROSSYM_INFO *RosSymInfo)
|
||||||
pe->sect = SectionHeaders;
|
pe->sect = SectionHeaders;
|
||||||
pe->imagebase = pe->loadbase = NtHeaders.OptionalHeader.ImageBase;
|
pe->imagebase = pe->loadbase = NtHeaders.OptionalHeader.ImageBase;
|
||||||
pe->imagesize = NtHeaders.OptionalHeader.SizeOfImage;
|
pe->imagesize = NtHeaders.OptionalHeader.SizeOfImage;
|
||||||
|
pe->codestart = NtHeaders.OptionalHeader.BaseOfCode;
|
||||||
|
pe->datastart = NtHeaders.OptionalHeader.BaseOfData;
|
||||||
pe->loadsection = loaddisksection;
|
pe->loadsection = loaddisksection;
|
||||||
*RosSymInfo = dwarfopen(pe);
|
*RosSymInfo = dwarfopen(pe);
|
||||||
|
|
||||||
|
|
|
@ -17,18 +17,18 @@ PeSect *pesection(Pe *pe, const char *name)
|
||||||
int i;
|
int i;
|
||||||
ANSI_STRING WantName;
|
ANSI_STRING WantName;
|
||||||
RtlInitAnsiString(&WantName, name);
|
RtlInitAnsiString(&WantName, name);
|
||||||
DPRINT("Searching for section %s\n", name);
|
werrstr("Searching for section %s\n", name);
|
||||||
for (i = 0; i < pe->nsections; i++) {
|
for (i = 0; i < pe->nsections; i++) {
|
||||||
PANSI_STRING AnsiString = ANSI_NAME_STRING(&pe->sect[i]);
|
PANSI_STRING AnsiString = ANSI_NAME_STRING(&pe->sect[i]);
|
||||||
if (WantName.Length == AnsiString->Length &&
|
if (WantName.Length == AnsiString->Length &&
|
||||||
!memcmp(AnsiString->Buffer, name, WantName.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,
|
((PCHAR)pe->imagebase)+pe->sect[i].VirtualAddress,
|
||||||
pe->sect[i].SizeOfRawData);
|
pe->sect[i].SizeOfRawData);
|
||||||
return &pe->sect[i];
|
return &pe->sect[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DPRINT("%s not found\n", name);
|
werrstr("%s not found\n", name);
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,11 +84,11 @@ loadmemsection(Pe *pe, char *name, DwarfBlock *b)
|
||||||
|
|
||||||
if((s = pesection(pe, name)) == nil)
|
if((s = pesection(pe, name)) == nil)
|
||||||
return -1;
|
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->data = RosSymAllocMem(s->SizeOfRawData);
|
||||||
b->len = s->SizeOfRawData;
|
b->len = s->SizeOfRawData;
|
||||||
PCHAR DataSource = ((char *)pe->fd) + s->VirtualAddress;
|
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);
|
RtlCopyMemory(b->data, DataSource, s->SizeOfRawData);
|
||||||
|
|
||||||
return s->SizeOfRawData;
|
return s->SizeOfRawData;
|
||||||
|
@ -121,16 +121,16 @@ void xfree(void *v) {
|
||||||
|
|
||||||
ulong pefindrva(struct _IMAGE_SECTION_HEADER *SectionHeaders, int NumberOfSections, ulong TargetPhysical) {
|
ulong pefindrva(struct _IMAGE_SECTION_HEADER *SectionHeaders, int NumberOfSections, ulong TargetPhysical) {
|
||||||
int i;
|
int i;
|
||||||
DPRINT("Finding RVA for Physical %x\n", TargetPhysical);
|
werrstr("Finding RVA for Physical %x\n", TargetPhysical);
|
||||||
for (i = 0; i < NumberOfSections; i++) {
|
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,
|
i,
|
||||||
ANSI_NAME_STRING(&SectionHeaders[i])->Buffer,
|
ANSI_NAME_STRING(&SectionHeaders[i])->Buffer,
|
||||||
SectionHeaders[i].PointerToRawData,
|
SectionHeaders[i].PointerToRawData,
|
||||||
SectionHeaders[i].VirtualAddress);
|
SectionHeaders[i].VirtualAddress);
|
||||||
if (TargetPhysical >= SectionHeaders[i].PointerToRawData &&
|
if (TargetPhysical >= SectionHeaders[i].PointerToRawData &&
|
||||||
TargetPhysical < SectionHeaders[i].PointerToRawData + SectionHeaders[i].SizeOfRawData) {
|
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;
|
return TargetPhysical - SectionHeaders[i].PointerToRawData + SectionHeaders[i].VirtualAddress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ typedef struct _Pe {
|
||||||
u32int (*e4)(const unsigned char *data);
|
u32int (*e4)(const unsigned char *data);
|
||||||
u64int (*e8)(const unsigned char *data);
|
u64int (*e8)(const unsigned char *data);
|
||||||
ulong imagebase, imagesize, loadbase;
|
ulong imagebase, imagesize, loadbase;
|
||||||
|
ulong codestart, datastart;
|
||||||
int (*loadsection)(struct _Pe *pe, char *name, struct DwarfBlock *b);
|
int (*loadsection)(struct _Pe *pe, char *name, struct DwarfBlock *b);
|
||||||
int nsections;
|
int nsections;
|
||||||
struct _IMAGE_SECTION_HEADER *sect;
|
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 KdbpCmdHelp(ULONG Argc, PCHAR Argv[]);
|
||||||
static BOOLEAN KdbpCmdDmesg(ULONG Argc, PCHAR Argv[]);
|
static BOOLEAN KdbpCmdDmesg(ULONG Argc, PCHAR Argv[]);
|
||||||
|
|
||||||
|
#ifdef __ROS_CMAKE__
|
||||||
|
static BOOLEAN KdbpCmdPrintStruct(ULONG Argc, PCHAR Argv[]);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
static BOOLEAN KdbUseIntelSyntax = FALSE; /* Set to TRUE for intel syntax */
|
static BOOLEAN KdbUseIntelSyntax = FALSE; /* Set to TRUE for intel syntax */
|
||||||
|
@ -135,6 +139,9 @@ static const struct
|
||||||
{ "sregs", "sregs", "Display status registers.", KdbpCmdRegs },
|
{ "sregs", "sregs", "Display status registers.", KdbpCmdRegs },
|
||||||
{ "dregs", "dregs", "Display debug registers.", KdbpCmdRegs },
|
{ "dregs", "dregs", "Display debug registers.", KdbpCmdRegs },
|
||||||
{ "bt", "bt [*frameaddr|thread id]", "Prints current backtrace or from given frame addr", KdbpCmdBackTrace },
|
{ "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 */
|
/* Flow control */
|
||||||
{ NULL, NULL, "Flow control", NULL },
|
{ NULL, NULL, "Flow control", NULL },
|
||||||
|
@ -453,6 +460,142 @@ KdbpCmdEvalExpression(
|
||||||
return TRUE;
|
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
|
/*!\brief Display list of active debug channels
|
||||||
*/
|
*/
|
||||||
static BOOLEAN
|
static BOOLEAN
|
||||||
|
|
|
@ -359,7 +359,7 @@ KdbSymGetAddressInformation(
|
||||||
*
|
*
|
||||||
* \sa KdbpSymAddCachedFile
|
* \sa KdbpSymAddCachedFile
|
||||||
*/
|
*/
|
||||||
static PROSSYM_INFO
|
PROSSYM_INFO
|
||||||
KdbpSymFindCachedFile(
|
KdbpSymFindCachedFile(
|
||||||
IN PUNICODE_STRING FileName)
|
IN PUNICODE_STRING FileName)
|
||||||
{
|
{
|
||||||
|
@ -405,7 +405,7 @@ KdbpSymAddCachedFile(
|
||||||
{
|
{
|
||||||
PIMAGE_SYMBOL_INFO_CACHE CacheEntry;
|
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 */
|
/* allocate entry */
|
||||||
CacheEntry = ExAllocatePoolWithTag(NonPagedPool, sizeof (IMAGE_SYMBOL_INFO_CACHE), TAG_KDBS);
|
CacheEntry = ExAllocatePoolWithTag(NonPagedPool, sizeof (IMAGE_SYMBOL_INFO_CACHE), TAG_KDBS);
|
||||||
|
@ -416,6 +416,7 @@ KdbpSymAddCachedFile(
|
||||||
CacheEntry->FileName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
|
CacheEntry->FileName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
FileName->Length,
|
FileName->Length,
|
||||||
TAG_KDBS);
|
TAG_KDBS);
|
||||||
|
CacheEntry->FileName.MaximumLength = FileName->Length;
|
||||||
RtlCopyUnicodeString(&CacheEntry->FileName, FileName);
|
RtlCopyUnicodeString(&CacheEntry->FileName, FileName);
|
||||||
ASSERT(CacheEntry->FileName.Buffer);
|
ASSERT(CacheEntry->FileName.Buffer);
|
||||||
CacheEntry->RefCount = 1;
|
CacheEntry->RefCount = 1;
|
||||||
|
@ -476,7 +477,7 @@ KdbpSymRemoveCachedFile(
|
||||||
*
|
*
|
||||||
* \sa KdbpSymUnloadModuleSymbols
|
* \sa KdbpSymUnloadModuleSymbols
|
||||||
*/
|
*/
|
||||||
static VOID
|
VOID
|
||||||
KdbpSymLoadModuleSymbols(
|
KdbpSymLoadModuleSymbols(
|
||||||
IN PUNICODE_STRING FileName,
|
IN PUNICODE_STRING FileName,
|
||||||
OUT PROSSYM_INFO *RosSymInfo)
|
OUT PROSSYM_INFO *RosSymInfo)
|
||||||
|
@ -508,7 +509,7 @@ KdbpSymLoadModuleSymbols(
|
||||||
/* Open the file */
|
/* Open the file */
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
FileName,
|
FileName,
|
||||||
OBJ_CASE_INSENSITIVE,
|
OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
@ -519,10 +520,10 @@ KdbpSymLoadModuleSymbols(
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
&IoStatusBlock,
|
&IoStatusBlock,
|
||||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
FILE_SYNCHRONOUS_IO_NONALERT);
|
FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT);
|
||||||
if (!NT_SUCCESS(Status))
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,8 +549,17 @@ KdbpSymLoadModuleSymbols(
|
||||||
if (RosSymCreateFromFile(FileContext, RosSymInfo))
|
if (RosSymCreateFromFile(FileContext, RosSymInfo))
|
||||||
{
|
{
|
||||||
/* add file to cache */
|
/* add file to cache */
|
||||||
KdbpSymAddCachedFile(FileName, *RosSymInfo);
|
int i;
|
||||||
DPRINT("Installed symbols: %wZ %p\n", FileName, *RosSymInfo);
|
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);
|
KdbpReleaseFileForSymbols(FileContext);
|
||||||
}
|
}
|
||||||
|
@ -569,13 +579,45 @@ KdbSymProcessSymbols(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove symbol info if it already exists */
|
/* Remove symbol info if it already exists */
|
||||||
if (LdrEntry->PatchInformation)
|
if (LdrEntry->PatchInformation) {
|
||||||
KdbpSymRemoveCachedFile(LdrEntry->PatchInformation);
|
KdbpSymRemoveCachedFile(LdrEntry->PatchInformation);
|
||||||
|
}
|
||||||
|
|
||||||
/* Error loading symbol info, try to load it from file */
|
/* Error loading symbol info, try to load it from file */
|
||||||
KdbpSymLoadModuleSymbols(&LdrEntry->FullDllName,
|
KdbpSymLoadModuleSymbols(&LdrEntry->FullDllName,
|
||||||
(PROSSYM_INFO*)&LdrEntry->PatchInformation);
|
(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 */
|
/* It already added symbols to cache */
|
||||||
DPRINT("Installed symbols: %wZ@%p-%p %p\n",
|
DPRINT("Installed symbols: %wZ@%p-%p %p\n",
|
||||||
&LdrEntry->BaseDllName,
|
&LdrEntry->BaseDllName,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue