Compare commits

...

2 Commits

Author SHA1 Message Date
Amine Khaldi
a273e73c64 [CMAKE]
- *Temporarily* back out every rossym/kdbg related revision from 50033 on until bugs 6372 and 6373 are fixed.
- We'll lose user mode address translation, argument values and dt.
- The same needs to be applied to trunk to allow cmake adoption.

svn path=/branches/cmake-bringup/; revision=52784
2011-07-22 21:47:29 +00:00
Art Yerkes
8d4d3483a6 gcc-4.6.0 doesn't include a pubnames section.
svn path=/branches/cmake-bringup/; revision=52144
2011-06-08 02:32:20 +00:00
29 changed files with 1362 additions and 2074 deletions

View File

@@ -17,86 +17,28 @@ typedef struct _ROSSYM_ENTRY {
ULONG SourceLine; ULONG SourceLine;
} ROSSYM_ENTRY, *PROSSYM_ENTRY; } ROSSYM_ENTRY, *PROSSYM_ENTRY;
enum _ROSSYM_REGNAME {
ROSSYM_X86_EAX = 0,
ROSSYM_X86_ECX,
ROSSYM_X86_EDX,
ROSSYM_X86_EBX,
ROSSYM_X86_ESP,
ROSSYM_X86_EBP,
ROSSYM_X86_ESI,
ROSSYM_X86_EDI,
ROSSYM_X64_RAX = 0,
ROSSYM_X64_RDX,
ROSSYM_X64_RCX,
ROSSYM_X64_RBX,
ROSSYM_X64_RSI,
ROSSYM_X64_RDI,
ROSSYM_X64_RBP,
ROSSYM_X64_RSP,
Rossym_X64_R8,
ROSSYM_X64_R9,
ROSSYM_X64_R10,
ROSSYM_X64_R11,
ROSSYM_X64_R12,
ROSSYM_X64_R13,
ROSSYM_X64_R14,
ROSSYM_X64_R15
};
typedef struct _ROSSYM_REGISTERS {
ULONGLONG Registers[32];
} ROSSYM_REGISTERS, *PROSSYM_REGISTERS;
typedef struct _ROSSYM_PARAMETER {
ULONGLONG Value;
char *ValueName;
} ROSSYM_PARAMETER, *PROSSYM_PARAMETER;
typedef enum _ROSSYM_LINEINFO_FLAGS {
ROSSYM_LINEINFO_HAS_REGISTERS = 1
} ROSSYM_LINEINFO_FLAGS;
typedef enum _ROSSYM_LINEINFO_TYPE {
ROSSYM_LINEINFO_UNKNOWN,
ROSSYM_LINEINFO_NARROW_STRING,
ROSSYM_LINEINFO_WIDE_STRING,
ROSSYM_LINEINFO_ANSI_STRING,
ROSSYM_LINEINFO_UNICODE_STRING,
ROSSYM_LINEINFO_HANDLE
} ROSSYM_LINEINFO_STRINGTYPE;
typedef struct _ROSSYM_LINEINFO {
ROSSYM_LINEINFO_FLAGS Flags;
ULONG LineNumber;
char *FileName;
char *FunctionName;
ROSSYM_REGISTERS Registers;
ULONG NumParams;
ROSSYM_PARAMETER Parameters[16];
} ROSSYM_LINEINFO, *PROSSYM_LINEINFO;
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);
BOOLEAN (*ReadFileProc)(PVOID FileContext, PVOID Buffer, ULONG Size); BOOLEAN (*ReadFileProc)(PVOID FileContext, PVOID Buffer, ULONG Size);
BOOLEAN (*SeekFileProc)(PVOID FileContext, ULONG_PTR Position); BOOLEAN (*SeekFileProc)(PVOID FileContext, ULONG_PTR Position);
BOOLEAN (*MemGetProc)(PVOID FileContext, ULONG_PTR *Target, PVOID SourceMem, ULONG Size);
} ROSSYM_CALLBACKS, *PROSSYM_CALLBACKS; } ROSSYM_CALLBACKS, *PROSSYM_CALLBACKS;
struct Dwarf; struct Dwarf;
typedef struct Dwarf *PROSSYM_INFO; typedef struct Dwarf *PROSSYM_INFO;
VOID RosSymInit(PROSSYM_CALLBACKS Callbacks); VOID RosSymInit(PROSSYM_CALLBACKS Callbacks);
VOID RosSymInitKernelMode(VOID);
VOID RosSymInitUserMode(VOID); VOID RosSymInitUserMode(VOID);
BOOLEAN RosSymCreateFromMem(PVOID ImageStart, ULONG_PTR ImageSize,
PROSSYM_INFO *RosSymInfo);
BOOLEAN RosSymCreateFromFile(PVOID FileContext, PROSSYM_INFO *RosSymInfo); BOOLEAN RosSymCreateFromFile(PVOID FileContext, PROSSYM_INFO *RosSymInfo);
BOOLEAN RosSymGetAddressInformation BOOLEAN RosSymGetAddressInformation(PROSSYM_INFO RosSymInfo,
(PROSSYM_INFO RosSymInfo, ULONG_PTR RelativeAddress,
ULONG_PTR RelativeAddress, ULONG *LineNumber,
PROSSYM_LINEINFO RosSymLineInfo); char *FileName,
VOID RosSymFreeInfo(PROSSYM_LINEINFO RosSymLineInfo); char *FunctionName);
VOID RosSymDelete(PROSSYM_INFO RosSymInfo); VOID RosSymDelete(PROSSYM_INFO RosSymInfo);
#endif /* REACTOS_ROSSYM_H_INCLUDED */ #endif /* REACTOS_ROSSYM_H_INCLUDED */

View File

@@ -5,6 +5,7 @@ else()
add_definitions(-D_NTSYSTEM_) add_definitions(-D_NTSYSTEM_)
list(APPEND SOURCE list(APPEND SOURCE
delete.c delete.c
dwarf386.c
dwarfabbrev.c dwarfabbrev.c
dwarfaranges.c dwarfaranges.c
dwarfcfa.c dwarfcfa.c
@@ -16,6 +17,7 @@ list(APPEND SOURCE
find.c find.c
fromfile.c fromfile.c
init.c init.c
initkm.c
initum.c initum.c
pe.c pe.c
zwfile.c) zwfile.c)

View File

@@ -32,8 +32,6 @@ 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__)
#define malloc(x) RosSymAllocMem(x) #define malloc(x) RosSymAllocMem(x)
#define mallocz(x,y) RosSymAllocMemZero(x,y) #define mallocz(x,y) RosSymAllocMemZero(x,y)
#define free(x) xfree(x) #define free(x) xfree(x)

View File

@@ -22,6 +22,11 @@
VOID VOID
RosSymDelete(PROSSYM_INFO RosSymInfo) RosSymDelete(PROSSYM_INFO RosSymInfo)
{ {
int i;
for (i = 0; i < RosSymInfo->pe->nsections; i++) {
RtlFreeAnsiString(ANSI_NAME_STRING(&RosSymInfo->pe->sect[i]));
}
RosSymFreeMem(RosSymInfo->pe->sect);
dwarfclose(RosSymInfo); dwarfclose(RosSymInfo);
} }

View File

@@ -6,8 +6,6 @@ typedef struct DwarfBlock DwarfBlock;
typedef struct DwarfBuf DwarfBuf; typedef struct DwarfBuf DwarfBuf;
typedef struct DwarfExpr DwarfExpr; typedef struct DwarfExpr DwarfExpr;
typedef struct DwarfSym DwarfSym; typedef struct DwarfSym DwarfSym;
typedef struct DwarfStack DwarfStack;
typedef struct DwarfParam DwarfParam;
typedef union DwarfVal DwarfVal; typedef union DwarfVal DwarfVal;
enum enum
@@ -205,16 +203,6 @@ struct DwarfBlock
ulong len; ulong len;
}; };
struct DwarfParam
{
char *name;
ulong unit;
ulong type;
ulong loctype;
ulong fde, len;
ulong value;
};
/* not for consumer use */ /* not for consumer use */
struct DwarfBuf struct DwarfBuf
{ {
@@ -264,7 +252,7 @@ struct DwarfAttrs
uchar framebase; uchar framebase;
uchar friend; uchar friend;
uchar highpc; uchar highpc;
uchar entrypc; uchar entrypc;
uchar identifiercase; uchar identifiercase;
uchar import; uchar import;
uchar inlined; uchar inlined;
@@ -327,7 +315,7 @@ struct DwarfAttrs
DwarfVal framebase; DwarfVal framebase;
ulong friend; ulong friend;
ulong highpc; ulong highpc;
ulong entrypc; ulong entrypc;
ulong identifiercase; ulong identifiercase;
ulong import; ulong import;
ulong inlined; ulong inlined;
@@ -384,16 +372,19 @@ struct DwarfExpr
struct DwarfSym struct DwarfSym
{ {
DwarfAttrs attrs; DwarfAttrs attrs;
/* not for consumer use... */ /* not for consumer use... */
uint num; DwarfBuf b;
DwarfBuf b; ulong unit;
int depth; uint uoff;
ulong unit, childoff, nextunit; ulong aoff;
ulong aoff; int depth;
int allunits;
ulong nextunit;
}; };
struct _Pe; struct _Pe;
Dwarf *dwarfopen(struct _Pe *elf); Dwarf *dwarfopen(struct _Pe *elf);
void dwarfclose(Dwarf*); void dwarfclose(Dwarf*);
@@ -407,11 +398,9 @@ int dwarfenumunit(Dwarf*, ulong, DwarfSym*);
int dwarfseeksym(Dwarf*, ulong, ulong, DwarfSym*); int dwarfseeksym(Dwarf*, ulong, ulong, DwarfSym*);
int dwarfenum(Dwarf*, DwarfSym*); int dwarfenum(Dwarf*, DwarfSym*);
int dwarfnextsym(Dwarf*, DwarfSym*); int dwarfnextsym(Dwarf*, DwarfSym*);
int dwarfnextsymat(Dwarf*, DwarfSym *parent, DwarfSym *child); int dwarfnextsymat(Dwarf*, DwarfSym*, int);
int dwarfpctoline(Dwarf*, DwarfSym *proc, ulong, char**, char**, ulong *); int dwarfpctoline(Dwarf*, ulong, char**, char**, char**, char **, ulong*, ulong*, ulong*);
int dwarfgetarg(Dwarf *d, const char *name, DwarfBuf *locbuf, ulong cfa, PROSSYM_REGISTERS registers, ulong *value); int dwarfunwind(Dwarf*, ulong, DwarfExpr*, DwarfExpr*, DwarfExpr*, int);
int dwarfgettype(Dwarf *d, DwarfSym *param, DwarfSym *type);
ulong dwarfget1(DwarfBuf*); ulong dwarfget1(DwarfBuf*);
ulong dwarfget2(DwarfBuf*); ulong dwarfget2(DwarfBuf*);
ulong dwarfget4(DwarfBuf*); ulong dwarfget4(DwarfBuf*);
@@ -422,10 +411,7 @@ ulong dwarfgetaddr(DwarfBuf*);
int dwarfgetn(DwarfBuf*, uchar*, int); int dwarfgetn(DwarfBuf*, uchar*, int);
uchar *dwarfgetnref(DwarfBuf*, ulong); uchar *dwarfgetnref(DwarfBuf*, ulong);
char *dwarfgetstring(DwarfBuf*); char *dwarfgetstring(DwarfBuf*);
int dwarfcomputecfa(Dwarf *d, DwarfExpr *cfa, PROSSYM_REGISTERS registers, ulong *cfaLocation);
int dwarfregunwind(Dwarf *d, ulong pc, ulong fde, DwarfExpr *cfa, PROSSYM_REGISTERS registers);
int dwarfargvalue(Dwarf *d, DwarfSym *proc, ulong pc, ulong cfa, PROSSYM_REGISTERS registers, DwarfParam *parameters);
int dwarfgetparams(Dwarf *d, DwarfSym *s, ulong pc, int pnum, DwarfParam *paramblocks);
typedef struct DwarfAbbrev DwarfAbbrev; typedef struct DwarfAbbrev DwarfAbbrev;
typedef struct DwarfAttr DwarfAttr; typedef struct DwarfAttr DwarfAttr;
@@ -463,7 +449,6 @@ struct Dwarf
DwarfBlock pubtypes; DwarfBlock pubtypes;
DwarfBlock ranges; DwarfBlock ranges;
DwarfBlock str; DwarfBlock str;
DwarfBlock loc;
/* little cache */ /* little cache */
struct { struct {
@@ -473,15 +458,14 @@ struct Dwarf
} acache; } acache;
}; };
struct DwarfStack
{
ulong storage[16]; // own storage
ulong *data;
ulong length, max;
};
DwarfAbbrev *dwarfgetabbrev(Dwarf*, ulong, ulong); DwarfAbbrev *dwarfgetabbrev(Dwarf*, ulong, ulong);
int dwarfgetinfounit(Dwarf*, ulong, DwarfBlock*); int dwarfgetinfounit(Dwarf*, ulong, DwarfBlock*);
extern int dwarf386nregs;
extern char *dwarf386regs[];
extern char *dwarf386fp;
#define SYMBOL_SIZE 18
#define MAXIMUM_DWARF_NAME_SIZE 64 #define MAXIMUM_DWARF_NAME_SIZE 64
#define MAXIMUM_COFF_SYMBOL_LENGTH 256

View File

@@ -25,119 +25,117 @@ DwarfAbbrev *dwarfgetabbrev(Dwarf*, ulong, ulong);
static int static int
loadabbrevs(Dwarf *d, ulong off, DwarfAbbrev **aa) loadabbrevs(Dwarf *d, ulong off, DwarfAbbrev **aa)
{ {
int nattr, nabbrev; int nattr, nabbrev;
DwarfAbbrev *abbrev; DwarfAbbrev *abbrev;
DwarfAttr *attr; DwarfAttr *attr;
if(d->acache.off == off && d->acache.na){ if(d->acache.off == off && d->acache.na){
*aa = d->acache.a; *aa = d->acache.a;
return d->acache.na; return d->acache.na;
} }
/* two passes - once to count, then allocate, then a second to copy */ /* two passes - once to count, then allocate, then a second to copy */
if(parseabbrevs(d, off, nil, nil, &nabbrev, &nattr) < 0) { if(parseabbrevs(d, off, nil, nil, &nabbrev, &nattr) < 0) {
return -1; return -1;
} }
abbrev = malloc(nabbrev*sizeof(DwarfAbbrev) + nattr*sizeof(DwarfAttr)); abbrev = malloc(nabbrev*sizeof(DwarfAbbrev) + nattr*sizeof(DwarfAttr));
attr = (DwarfAttr*)(abbrev+nabbrev); attr = (DwarfAttr*)(abbrev+nabbrev);
if(parseabbrevs(d, off, abbrev, attr, nil, nil) < 0){ if(parseabbrevs(d, off, abbrev, attr, nil, nil) < 0){
free(abbrev); free(abbrev);
return -1; return -1;
} }
free(d->acache.a); free(d->acache.a);
d->acache.a = abbrev; d->acache.a = abbrev;
d->acache.na = nabbrev; d->acache.na = nabbrev;
d->acache.off = off; d->acache.off = off;
*aa = abbrev; *aa = abbrev;
return nabbrev; return nabbrev;
} }
static int static int
parseabbrevs(Dwarf *d, ulong off, DwarfAbbrev *abbrev, DwarfAttr *attr, int *pnabbrev, int *pnattr) parseabbrevs(Dwarf *d, ulong off, DwarfAbbrev *abbrev, DwarfAttr *attr, int *pnabbrev, int *pnattr)
{ {
int i, nabbrev, nattr, haskids; int i, nabbrev, nattr, haskids;
ulong num, tag, name, form; ulong num, tag, name, form;
DwarfBuf b; DwarfBuf b;
if(off >= d->abbrev.len){ if(off >= d->abbrev.len){
werrstr("bad abbrev section offset 0x%lux >= 0x%lux", off, d->abbrev.len); werrstr("bad abbrev section offset 0x%lux >= 0x%lux\n", off, d->abbrev.len);
return -1; return -1;
} }
memset(&b, 0, sizeof b); memset(&b, 0, sizeof b);
b.p = d->abbrev.data + off; b.p = d->abbrev.data + off;
b.ep = d->abbrev.data + d->abbrev.len; b.ep = d->abbrev.data + d->abbrev.len;
nabbrev = 0; nabbrev = 0;
nattr = 0; nattr = 0;
for(;;){ for(;;){
if(b.p == nil){ if(b.p == nil){
werrstr("malformed abbrev data"); werrstr("malformed abbrev data");
return -1; return -1;
} }
num = dwarfget128(&b); num = dwarfget128(&b);
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); haskids = dwarfget1(&b);
haskids = dwarfget1(&b); for(i=0;; i++){
for(i=0;; i++){ name = dwarfget128(&b);
name = dwarfget128(&b); form = dwarfget128(&b);
form = dwarfget128(&b); if(name == 0 && form == 0)
assert(form < 0x3000); break;
if(name == 0 && form == 0) if(attr){
break; attr[i].name = name;
if(attr){ attr[i].form = form;
attr[i].name = name; }
attr[i].form = form; }
} if(abbrev){
} abbrev->num = num;
if(abbrev){ abbrev->tag = tag;
abbrev->num = num; abbrev->haskids = haskids;
abbrev->tag = tag; abbrev->attr = attr;
abbrev->haskids = haskids; abbrev->nattr = i;
abbrev->attr = attr; abbrev++;
abbrev->nattr = i; attr += i;
abbrev++; }
attr += i; nabbrev++;
} nattr += i;
nabbrev++; }
nattr += i; if(pnabbrev)
} *pnabbrev = nabbrev;
if(pnabbrev) if(pnattr)
*pnabbrev = nabbrev; *pnattr = nattr;
if(pnattr) return 0;
*pnattr = nattr;
return 0;
} }
static DwarfAbbrev* static DwarfAbbrev*
findabbrev(DwarfAbbrev *a, int na, ulong num) 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"); return nil;
return nil;
} }
DwarfAbbrev* DwarfAbbrev*
dwarfgetabbrev(Dwarf *d, ulong off, ulong num) dwarfgetabbrev(Dwarf *d, ulong off, ulong num)
{ {
DwarfAbbrev *a; DwarfAbbrev *a;
int na; int na;
if((na = loadabbrevs(d, off, &a)) < 0){ if((na = loadabbrevs(d, off, &a)) < 0){
werrstr("loadabbrevs: %r"); werrstr("loadabbrevs: %r");
return nil; return nil;
} }
return findabbrev(a, na, num); return findabbrev(a, na, num);
} }

View File

@@ -16,54 +16,56 @@
int int
dwarfaddrtounit(Dwarf *d, ulong addr, ulong *unit) dwarfaddrtounit(Dwarf *d, ulong addr, ulong *unit)
{ {
DwarfBuf b; DwarfBuf b;
int segsize, i; int segsize, i;
ulong len, id, off, base, size; ulong len, id, off, base, size;
uchar *start, *end; uchar *start, *end;
memset(&b, 0, sizeof b); memset(&b, 0, sizeof b);
b.d = d; b.d = d;
b.p = d->aranges.data; b.p = d->aranges.data;
b.ep = b.p + d->aranges.len; b.ep = b.p + d->aranges.len;
while(b.p < b.ep){ while(b.p < b.ep){
start = b.p; start = b.p;
len = dwarfget4(&b); len = dwarfget4(&b);
if (!len) { b.ep = b.p - 4; return -1; } if (!len) { b.ep = b.p - 4; return -1; }
if((id = dwarfget2(&b)) != 2){ if((id = dwarfget2(&b)) != 2){
if(b.p == nil){ if(b.p == nil){
underflow: underflow:
werrstr("buffer underflow reading address ranges header"); werrstr("buffer underflow reading address ranges header");
}else }else
werrstr("bad dwarf version 0x%x in address ranges header", id); werrstr("bad dwarf version 0x%x in address ranges header", id);
return -1; return -1;
} }
off = dwarfget4(&b); off = dwarfget4(&b);
b.addrsize = dwarfget1(&b); b.addrsize = dwarfget1(&b);
if(d->addrsize == 0) if(d->addrsize == 0)
d->addrsize = b.addrsize; d->addrsize = b.addrsize;
segsize = dwarfget1(&b); segsize = dwarfget1(&b);
USED(segsize); /* what am i supposed to do with this? */ USED(segsize); /* what am i supposed to do with this? */
if(b.p == nil) if(b.p == nil)
goto underflow; goto underflow;
if((i = (b.p-start) % (2*b.addrsize)) != 0) if((i = (b.p-start) % (2*b.addrsize)) != 0)
b.p += 2*b.addrsize - i; b.p += 2*b.addrsize - i;
end = start+4+len; end = start+4+len;
while(b.p!=nil && b.p<end){ while(b.p!=nil && b.p<end){
base = dwarfgetaddr(&b); base = dwarfgetaddr(&b);
size = dwarfgetaddr(&b); size = dwarfgetaddr(&b);
if (!size) continue; if (!size) continue;
if(b.p == nil) if(b.p == nil)
goto underflow; goto underflow;
if(base <= addr && addr < base+size){ if(base <= addr && addr < base+size){
*unit = off; *unit = off;
return 0; return 0;
} }
} }
if(b.p == nil) if(b.p == nil)
goto underflow; goto underflow;
b.p = end; b.p = end;
} }
werrstr("address 0x%lux is not listed in dwarf debugging symbols", addr); werrstr("address 0x%lux is not listed in dwarf debugging symbols", addr);
return -1; return -1;
} }

View File

@@ -17,10 +17,9 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#include "pe.h"
#include "dwarf.h" #include "dwarf.h"
#define trace 1 #define trace 0
typedef struct State State; typedef struct State State;
struct State struct State
@@ -72,7 +71,7 @@ dwarfunwind(Dwarf *d, ulong pc, DwarfExpr *cfa, DwarfExpr *ra, DwarfExpr *r, int
memset(r, 0, nr*sizeof(r[0])); memset(r, 0, nr*sizeof(r[0]));
for(i=0; i<nr; i++) for(i=0; i<nr; i++)
r[i].type = RuleSame; r[i].type = RuleSame;
if(trace) werrstr("s.init %p-%p, fde %p-%p", s.init.p, s.init.ep, fde.p, fde.ep); if(trace) werrstr("s.init %p-%p, fde %p-%p\n", s.init.p, s.init.ep, fde.p, fde.ep);
b = s.init; b = s.init;
if(dexec(&b, &s, 0) < 0) if(dexec(&b, &s, 0) < 0)
goto err; goto err;
@@ -80,9 +79,9 @@ dwarfunwind(Dwarf *d, ulong pc, DwarfExpr *cfa, DwarfExpr *ra, DwarfExpr *r, int
s.initr = initr; s.initr = initr;
memmove(initr, r, nr*sizeof(initr[0])); memmove(initr, r, nr*sizeof(initr[0]));
if(trace) werrstr("s.loc 0x%lx pc 0x%lx", s.loc, pc); if(trace) werrstr("s.loc 0x%lux pc 0x%lux\n", s.loc, pc);
while(s.loc < pc){ while(s.loc < pc){
if(trace) werrstr("s.loc 0x%lx pc 0x%lx", s.loc, pc); if(trace) werrstr("s.loc 0x%lux pc 0x%lux\n", s.loc, pc);
if(dexec(&fde, &s, 1) < 0) if(dexec(&fde, &s, 1) < 0)
goto err; goto err;
} }
@@ -140,16 +139,15 @@ findfde(Dwarf *d, ulong pc, State *s, DwarfBuf *fde)
id = dwarfget4(&b); id = dwarfget4(&b);
if(id == 0xFFFFFFFF){ /* CIE */ if(id == 0xFFFFFFFF){ /* CIE */
vers = dwarfget1(&b); vers = dwarfget1(&b);
if (trace) werrstr("CIE len %x id %x vers %x", len, id, vers);
if(vers != 1 && vers != 2 && vers != 3){ if(vers != 1 && vers != 2 && vers != 3){
if(++nbad == 1) if(++nbad == 1)
werrstr("unknown cie version %d (wanted 1-3)", vers); werrstr("unknown cie version %d (wanted 1-3)\n", vers);
continue; continue;
} }
aug = dwarfgetstring(&b); aug = dwarfgetstring(&b);
if(aug && *aug){ if(aug && *aug){
if(++nbad == 1) if(++nbad == 1)
werrstr("unknown augmentation: %s", aug); werrstr("unknown augmentation: %s\n", aug);
continue; continue;
} }
s->iquantum = dwarfget128(&b); s->iquantum = dwarfget128(&b);
@@ -165,7 +163,6 @@ findfde(Dwarf *d, ulong pc, State *s, DwarfBuf *fde)
}else{ /* FDE */ }else{ /* FDE */
base = dwarfgetaddr(&b); base = dwarfgetaddr(&b);
size = dwarfgetaddr(&b); size = dwarfgetaddr(&b);
if (trace) werrstr("FDE: base %x-%x (want pc %x)", base, base+size, pc);
fde->p = b.p; fde->p = b.p;
fde->ep = next; fde->ep = next;
s->loc = base; s->loc = base;
@@ -174,7 +171,7 @@ findfde(Dwarf *d, ulong pc, State *s, DwarfBuf *fde)
return 0; return 0;
} }
} }
werrstr("cannot find call frame information for pc 0x%lx", pc); werrstr("cannot find call frame information for pc 0x%lux", pc);
return -1; return -1;
} }
@@ -183,7 +180,7 @@ static int
checkreg(State *s, long r) checkreg(State *s, long r)
{ {
if(r < 0 || r >= s->nr){ if(r < 0 || r >= s->nr){
werrstr("bad register number 0x%lx", r); werrstr("bad register number 0x%lux", r);
return -1; return -1;
} }
return 0; return 0;
@@ -200,21 +197,20 @@ dexec(DwarfBuf *b, State *s, int locstop)
if(b->p == b->ep){ if(b->p == b->ep){
if(s->initr) if(s->initr)
s->loc = s->endloc; s->loc = s->endloc;
werrstr("end dexec");
return 0; return 0;
} }
c = dwarfget1(b); c = dwarfget1(b);
if(b->p == nil){ if(b->p == nil){
werrstr("ran out of instructions during cfa program"); werrstr("ran out of instructions during cfa program");
if(trace) werrstr("%r"); if(trace) werrstr("%r\n");
return -1; return -1;
} }
if(trace) werrstr("+ loc=0x%x op 0x%x ", s->loc, c); if(trace) werrstr("+ loc=0x%lux op 0x%ux ", s->loc, c);
switch(c>>6){ switch(c>>6){
case 1: /* advance location */ case 1: /* advance location */
arg1 = c&0x3F; arg1 = c&0x3F;
advance: advance:
if(trace) werrstr("loc += %ld", arg1*s->iquantum); if(trace) werrstr("loc += %ld\n", arg1*s->iquantum);
s->loc += arg1 * s->iquantum; s->loc += arg1 * s->iquantum;
if(locstop) if(locstop)
return 0; return 0;
@@ -224,7 +220,7 @@ dexec(DwarfBuf *b, State *s, int locstop)
arg1 = c&0x3F; arg1 = c&0x3F;
arg2 = dwarfget128(b); arg2 = dwarfget128(b);
offset: offset:
if(trace) werrstr("r%ld += %ld", arg1, arg2*s->dquantum); if(trace) werrstr("r%ld += %ld\n", arg1, arg2*s->dquantum);
if(checkreg(s, arg1) < 0) if(checkreg(s, arg1) < 0)
return -1; return -1;
s->r[arg1].type = RuleCfaOffset; s->r[arg1].type = RuleCfaOffset;
@@ -234,7 +230,7 @@ dexec(DwarfBuf *b, State *s, int locstop)
case 3: /* restore initial setting */ case 3: /* restore initial setting */
arg1 = c&0x3F; arg1 = c&0x3F;
restore: restore:
if(trace) werrstr("r%ld = init", arg1); if(trace) werrstr("r%ld = init\n", arg1);
if(checkreg(s, arg1) < 0) if(checkreg(s, arg1) < 0)
return -1; return -1;
s->r[arg1] = s->initr[arg1]; s->r[arg1] = s->initr[arg1];
@@ -243,12 +239,12 @@ dexec(DwarfBuf *b, State *s, int locstop)
switch(c){ switch(c){
case 0: /* nop */ case 0: /* nop */
if(trace) werrstr("nop"); if(trace) werrstr("nop\n");
continue; continue;
case 0x01: /* set location */ case 0x01: /* set location */
s->loc = dwarfgetaddr(b); s->loc = dwarfgetaddr(b);
if(trace) werrstr("loc = 0x%lx", s->loc); if(trace) werrstr("loc = 0x%lux\n", s->loc);
if(locstop) if(locstop)
return 0; return 0;
continue; continue;
@@ -276,7 +272,7 @@ dexec(DwarfBuf *b, State *s, int locstop)
case 0x07: /* undefined */ case 0x07: /* undefined */
arg1 = dwarfget128(b); arg1 = dwarfget128(b);
if(trace) werrstr("r%ld = undef", arg1); if(trace) werrstr("r%ld = undef\n", arg1);
if(checkreg(s, arg1) < 0) if(checkreg(s, arg1) < 0)
return -1; return -1;
s->r[arg1].type = RuleUndef; s->r[arg1].type = RuleUndef;
@@ -284,7 +280,7 @@ dexec(DwarfBuf *b, State *s, int locstop)
case 0x08: /* same value */ case 0x08: /* same value */
arg1 = dwarfget128(b); arg1 = dwarfget128(b);
if(trace) werrstr("r%ld = same", arg1); if(trace) werrstr("r%ld = same\n", arg1);
if(checkreg(s, arg1) < 0) if(checkreg(s, arg1) < 0)
return -1; return -1;
s->r[arg1].type = RuleSame; s->r[arg1].type = RuleSame;
@@ -293,7 +289,7 @@ dexec(DwarfBuf *b, State *s, int locstop)
case 0x09: /* register */ case 0x09: /* register */
arg1 = dwarfget128(b); arg1 = dwarfget128(b);
arg2 = dwarfget128(b); arg2 = dwarfget128(b);
if(trace) werrstr("r%ld = r%ld", arg1, arg2); if(trace) werrstr("r%ld = r%ld\n", arg1, arg2);
if(checkreg(s, arg1) < 0 || checkreg(s, arg2) < 0) if(checkreg(s, arg1) < 0 || checkreg(s, arg2) < 0)
return -1; return -1;
s->r[arg1].type = RuleRegister; s->r[arg1].type = RuleRegister;
@@ -302,7 +298,7 @@ dexec(DwarfBuf *b, State *s, int locstop)
case 0x0A: /* remember state */ case 0x0A: /* remember state */
e = malloc(s->nr*sizeof(e[0])); e = malloc(s->nr*sizeof(e[0]));
if(trace) werrstr("push"); if(trace) werrstr("push\n");
if(e == nil) if(e == nil)
return -1; return -1;
void *newstack = malloc(s->nstack*sizeof(s->stack[0])); void *newstack = malloc(s->nstack*sizeof(s->stack[0]));
@@ -323,7 +319,7 @@ dexec(DwarfBuf *b, State *s, int locstop)
continue; continue;
case 0x0B: /* restore state */ case 0x0B: /* restore state */
if(trace) werrstr("pop"); if(trace) werrstr("pop\n");
if(s->nstack == 0){ if(s->nstack == 0){
werrstr("restore state underflow"); werrstr("restore state underflow");
return -1; return -1;
@@ -338,7 +334,7 @@ dexec(DwarfBuf *b, State *s, int locstop)
arg1 = dwarfget128(b); arg1 = dwarfget128(b);
arg2 = dwarfget128(b); arg2 = dwarfget128(b);
defcfa: defcfa:
if(trace) werrstr("cfa %ld(r%ld)", arg2, arg1); if(trace) werrstr("cfa %ld(r%ld)\n", arg2, arg1);
if(checkreg(s, arg1) < 0) if(checkreg(s, arg1) < 0)
return -1; return -1;
s->cfa->type = RuleRegOff; s->cfa->type = RuleRegOff;
@@ -348,7 +344,7 @@ dexec(DwarfBuf *b, State *s, int locstop)
case 0x0D: /* def cfa register */ case 0x0D: /* def cfa register */
arg1 = dwarfget128(b); arg1 = dwarfget128(b);
if(trace) werrstr("cfa reg r%ld", arg1); if(trace) werrstr("cfa reg r%ld\n", arg1);
if(s->cfa->type != RuleRegOff){ if(s->cfa->type != RuleRegOff){
werrstr("change CFA register but CFA not in register+offset form"); werrstr("change CFA register but CFA not in register+offset form");
return -1; return -1;
@@ -361,7 +357,7 @@ dexec(DwarfBuf *b, State *s, int locstop)
case 0x0E: /* def cfa offset */ case 0x0E: /* def cfa offset */
arg1 = dwarfget128(b); arg1 = dwarfget128(b);
cfaoffset: cfaoffset:
if(trace) werrstr("cfa off %ld", arg1); if(trace) werrstr("cfa off %ld\n", arg1);
if(s->cfa->type != RuleRegOff){ if(s->cfa->type != RuleRegOff){
werrstr("change CFA offset but CFA not in register+offset form"); werrstr("change CFA offset but CFA not in register+offset form");
return -1; return -1;
@@ -370,7 +366,7 @@ dexec(DwarfBuf *b, State *s, int locstop)
continue; continue;
case 0x0F: /* def cfa expression */ case 0x0F: /* def cfa expression */
if(trace) werrstr("cfa expr"); if(trace) werrstr("cfa expr\n");
s->cfa->type = RuleLocation; s->cfa->type = RuleLocation;
s->cfa->loc.len = dwarfget128(b); s->cfa->loc.len = dwarfget128(b);
s->cfa->loc.data = dwarfgetnref(b, s->cfa->loc.len); s->cfa->loc.data = dwarfgetnref(b, s->cfa->loc.len);
@@ -378,7 +374,7 @@ dexec(DwarfBuf *b, State *s, int locstop)
case 0x10: /* def reg expression */ case 0x10: /* def reg expression */
arg1 = dwarfget128(b); arg1 = dwarfget128(b);
if(trace) werrstr("reg expr r%ld", arg1); if(trace) werrstr("reg expr r%ld\n", arg1);
if(checkreg(s, arg1) < 0) if(checkreg(s, arg1) < 0)
return -1; return -1;
s->r[arg1].type = RuleLocation; s->r[arg1].type = RuleLocation;
@@ -401,98 +397,11 @@ dexec(DwarfBuf *b, State *s, int locstop)
goto cfaoffset; goto cfaoffset;
default: /* unknown */ default: /* unknown */
werrstr("unknown opcode 0x%x in cfa program", c); werrstr("unknown opcode 0x%ux in cfa program", c);
return -1; return -1;
} }
} }
/* not reached */ /* not reached */
} }
int dwarfcomputecfa(Dwarf *d, DwarfExpr *cfa, PROSSYM_REGISTERS registers, ulong *cfaLocation)
{
switch (cfa->type) {
case RuleRegOff:
*cfaLocation = registers->Registers[cfa->reg] + cfa->offset;
werrstr("cfa reg %d (%x) offset %x = %x", cfa->reg, (ulong)registers->Registers[cfa->reg], cfa->offset, cfaLocation);
break;
default:
werrstr("cfa->type %x", cfa->type);
return -1;
}
return 0;
}
int dwarfregunwind(Dwarf *d, ulong pc, ulong fde, DwarfExpr *cfa, PROSSYM_REGISTERS registers)
{
int i;
State s = { };
DwarfExpr initr[sizeof(registers->Registers) / sizeof(registers->Registers[0])] = { };
DwarfExpr r[sizeof(registers->Registers) / sizeof(registers->Registers[0])] = { };
DwarfExpr ra;
int nr = s.nr = sizeof(registers->Registers) / sizeof(registers->Registers[0]);
s.initr = initr;
s.r = r;
for (i = 0; i < sizeof(r) / sizeof(r[0]); i++) {
r[i].type = RuleRegister;
r[i].offset = registers->Registers[i];
r[i].reg = i;
}
int res = dwarfunwind(d, pc, cfa, &ra, initr, sizeof(initr) / sizeof(initr[0]));
if (res == -1) return -1;
ulong cfaLocation;
if (dwarfcomputecfa(d, cfa, registers, &cfaLocation) == -1)
return -1;
for (i = 0; i < nr; i++) {
switch (r[i].type) {
case RuleUndef:
werrstr("Undefined register slot %d", i);
assert(FALSE);
break;
case RuleSame:
break;
case RuleRegister:
registers->Registers[i] = registers->Registers[r[i].reg];
break;
case RuleRegOff: {
BOOLEAN success =
RosSymCallbacks.MemGetProc
(d->pe->fd,
&registers->Registers[i],
r[i].offset + registers->Registers[r[i].reg],
d->addrsize);
if (!success) return -1;
} break;
case RuleCfaOffset:
{
BOOLEAN success =
RosSymCallbacks.MemGetProc
(d->pe->fd,
&registers->Registers[i],
r[i].offset + cfaLocation,
d->addrsize);
werrstr("reg[%d] = %x: cfa offset (cfa %x, offset %x) -> @%x", i, (ulong)registers->Registers[i], cfaLocation, initr[i].offset, r[i].offset + cfaLocation);
if (!success) return -1;
} break;
default:
werrstr("We don't yet support cfa rule %d in slot %d", r[i].type, i);
assert(FALSE);
break;
}
}
ulong cfaSpace[4];
for (i = 0; i < sizeof(cfaSpace) / sizeof(cfaSpace[0]); i++) {
RosSymCallbacks.MemGetProc
(d->pe->fd, &cfaSpace[i], cfaLocation + (i * 4), d->addrsize);
}
werrstr("CFA(%x) [%08x, %08x, %08x, %08x]",
cfaLocation, cfaSpace[0], cfaSpace[1], cfaSpace[2], cfaSpace[3]);
return 0;
}

View File

@@ -139,7 +139,7 @@ dwarfgetaddr(DwarfBuf *b)
return dwarfget8(b); return dwarfget8(b);
default: default:
if(++nbad == 1) if(++nbad == 1)
werrstr("dwarf: unexpected address size %lud in dwarfgetaddr", b->addrsize); werrstr("dwarf: unexpected address size %lud in dwarfgetaddr\n", b->addrsize);
b->p = nil; b->p = nil;
return 0; return 0;
} }
@@ -190,7 +190,7 @@ dwarfget128(DwarfBuf *b)
while(b->p<b->ep && *b->p&0x80) while(b->p<b->ep && *b->p&0x80)
b->p++; b->p++;
if(++nbad == 1) if(++nbad == 1)
werrstr("dwarf: overflow during parsing of uleb128 integer"); werrstr("dwarf: overflow during parsing of uleb128 integer\n");
return c; return c;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -30,10 +30,9 @@ 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)
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);
@@ -41,7 +40,6 @@ dwarfopen(Pe *pe)
return d; return d;
err: err:
DPRINT("Failed to open dwarf\n");
free(d->abbrev.data); free(d->abbrev.data);
free(d->aranges.data); free(d->aranges.data);
free(d->frame.data); free(d->frame.data);
@@ -50,7 +48,6 @@ err:
free(d->ranges.data); free(d->ranges.data);
free(d->str.data); free(d->str.data);
free(d->info.data); free(d->info.data);
free(d->loc.data);
free(d); free(d);
return nil; return nil;
} }

View File

@@ -27,389 +27,354 @@
enum enum
{ {
Isstmt = 1<<0, Isstmt = 1<<0,
BasicDwarfBlock = 1<<1, BasicDwarfBlock = 1<<1,
EndSequence = 1<<2, EndSequence = 1<<2,
PrologueEnd = 1<<3, PrologueEnd = 1<<3,
EpilogueBegin = 1<<4 EpilogueBegin = 1<<4
}; };
typedef struct State State; typedef struct State State;
struct State struct State
{ {
ulong addr; ulong addr;
ulong file; ulong file;
ulong line; ulong line;
ulong column; ulong column;
ulong flags; ulong flags;
ulong isa; ulong isa;
}; };
int int
dwarfpctoline(Dwarf *d, DwarfSym *proc, ulong pc, char **file, char **function, ulong *line) dwarfpctoline(Dwarf *d, ulong pc, char **cdir, char **dir, char **file, char **function, ulong *line, ulong *mtime, ulong *length)
{ {
char *cdir; uchar *prog, *opcount, *end, *dirs;
uchar *prog, *opcount, *end, *dirs; ulong off, unit, len, vers, x, start, lastline;
ulong off, unit, len, vers, x, start, lastline; int i, first, op, a, l, quantum, isstmt, linebase, linerange, opcodebase, nf;
int i, first, firstline, op, a, l, quantum, isstmt, linebase, linerange, opcodebase, nf; char *files, *s;
char *files, *s; DwarfBuf b;
DwarfBuf b; DwarfSym sym;
DwarfSym sym; State emit, cur, reset;
State emit, cur, reset; uchar **f, **newf;
char **f, **newf;
f = nil; f = nil;
memset(proc, 0, sizeof(*proc));
int runit = dwarfaddrtounit(d, pc, &unit); if(dwarfaddrtounit(d, pc, &unit) < 0
if (runit < 0) || dwarflookuptag(d, unit, TagCompileUnit, &sym) < 0)
return -1; return -1;
int rtag = dwarflookuptag(d, unit, TagCompileUnit, &sym);
if (rtag < 0)
return -1;
if(!sym.attrs.have.stmtlist){ if(!sym.attrs.have.stmtlist){
werrstr("no line mapping information for 0x%x", pc); werrstr("no line mapping information for 0x%x", pc);
return -1; return -1;
} }
off = sym.attrs.stmtlist; off = sym.attrs.stmtlist;
if(off >= d->line.len){ if(off >= d->line.len){
werrstr("bad stmtlist"); werrstr("bad stmtlist\n");
goto bad; goto bad;
}
if(trace) werrstr("unit 0x%x stmtlist 0x%x", unit, sym.attrs.stmtlist);
memset(&b, 0, sizeof b);
b.d = d;
b.p = d->line.data + off;
b.ep = b.p + d->line.len;
b.addrsize = sym.b.addrsize; /* should i get this from somewhere else? */
len = dwarfget4(&b);
if(b.p==nil || b.p+len > b.ep || b.p+len < b.p){
werrstr("bad len");
goto bad;
}
b.ep = b.p+len;
vers = dwarfget2(&b);
if(vers != 2){
werrstr("bad dwarf version 0x%x", vers);
return -1;
}
len = dwarfget4(&b);
if(b.p==nil || b.p+len > b.ep || b.p+len < b.p){
werrstr("another bad len");
goto bad;
}
prog = b.p+len;
quantum = dwarfget1(&b);
isstmt = dwarfget1(&b);
linebase = (schar)dwarfget1(&b);
linerange = (schar)dwarfget1(&b);
opcodebase = dwarfget1(&b);
opcount = b.p-1;
dwarfgetnref(&b, opcodebase-1);
if(b.p == nil){
werrstr("bad opcode chart");
goto bad;
}
/* just skip the files and dirs for now; we'll come back */
dirs = b.p;
while (b.p && *b.p)
dwarfgetstring(&b);
dwarfget1(&b);
files = (char*)b.p;
while(b.p!=nil && *b.p!=0){
dwarfgetstring(&b);
dwarfget128(&b);
dwarfget128(&b);
dwarfget128(&b);
}
dwarfget1(&b);
/* move on to the program */
if(b.p == nil || b.p > prog){
werrstr("bad header");
goto bad;
}
b.p = prog;
reset.addr = 0;
reset.file = 1;
reset.line = 1;
reset.column = 0;
reset.flags = isstmt ? Isstmt : 0;
reset.isa = 0;
cur = reset;
emit = reset;
nf = 0;
start = 0;
if(trace) werrstr("program @ %lu ... %.*H opbase = %d", b.p - d->line.data, b.ep-b.p, b.p, opcodebase);
first = 1;
while(b.p != nil){
firstline = 0;
op = dwarfget1(&b);
if(trace) werrstr("\tline %lu, addr 0x%x, op %d %.10H", cur.line, cur.addr, op, b.p);
if(op >= opcodebase){
a = (op - opcodebase) / linerange;
l = (op - opcodebase) % linerange + linebase;
cur.line += l;
cur.addr += a * quantum;
if(trace) werrstr(" +%d,%d", a, l);
emit:
if(first){
if(cur.addr > pc){
werrstr("found wrong line mapping 0x%x for pc 0x%x", cur.addr, pc);
/* This is an overzealous check. gcc can produce discontiguous ranges
and reorder statements, so it's possible for a future line to start
ahead of pc and still find a matching one. */
/*goto out;*/
firstline = 1;
}
first = 0;
start = cur.addr;
}
if(cur.addr > pc && !firstline)
break;
if(b.p == nil){
werrstr("buffer underflow in line mapping");
goto out;
}
emit = cur;
if(emit.flags & EndSequence){
werrstr("found wrong line mapping 0x%x-0x%x for pc 0x%x", start, cur.addr, pc);
goto out;
}
cur.flags &= ~(BasicDwarfBlock|PrologueEnd|EpilogueBegin);
}else{
switch(op){
case 0: /* extended op code */
if(trace) werrstr(" ext");
len = dwarfget128(&b);
end = b.p+len;
if(b.p == nil || end > b.ep || end < b.p || len < 1)
goto bad;
switch(dwarfget1(&b)){
case 1: /* end sequence */
if(trace) werrstr(" end");
cur.flags |= EndSequence;
goto emit;
case 2: /* set address */
cur.addr = dwarfgetaddr(&b);
if(trace) werrstr(" set pc 0x%x", cur.addr);
break;
case 3: /* define file */
newf = malloc(nf+1*sizeof(f[0]));
if (newf)
RtlMoveMemory(newf, f, nf*sizeof(f[0]));
if(newf == nil)
goto out;
free(f);
f = newf;
f[nf++] = s = dwarfgetstring(&b);
DPRINT1("str %s", s);
dwarfget128(&b);
dwarfget128(&b);
dwarfget128(&b);
if(trace) werrstr(" def file %s", s);
break;
}
if(b.p == nil || b.p > end)
goto bad;
b.p = end;
break;
case 1: /* emit */
if(trace) werrstr(" emit");
goto emit;
case 2: /* advance pc */
a = dwarfget128(&b);
if(trace) werrstr(" advance pc + %lu", a*quantum);
cur.addr += a * quantum;
break;
case 3: /* advance line */
l = dwarfget128s(&b);
if(trace) werrstr(" advance line + %ld", l);
cur.line += l;
break;
case 4: /* set file */
if(trace) werrstr(" set file");
cur.file = dwarfget128s(&b);
break;
case 5: /* set column */
if(trace) werrstr(" set column");
cur.column = dwarfget128(&b);
break;
case 6: /* negate stmt */
if(trace) werrstr(" negate stmt");
cur.flags ^= Isstmt;
break;
case 7: /* set basic block */
if(trace) werrstr(" set basic block");
cur.flags |= BasicDwarfBlock;
break;
case 8: /* const add pc */
a = (255 - opcodebase) / linerange * quantum;
if(trace) werrstr(" const add pc + %d", a);
cur.addr += a;
break;
case 9: /* fixed advance pc */
a = dwarfget2(&b);
if(trace) werrstr(" fixed advance pc + %d", a);
cur.addr += a;
break;
case 10: /* set prologue end */
if(trace) werrstr(" set prologue end");
cur.flags |= PrologueEnd;
break;
case 11: /* set epilogue begin */
if(trace) werrstr(" set epilogue begin");
cur.flags |= EpilogueBegin;
break;
case 12: /* set isa */
if(trace) werrstr(" set isa");
cur.isa = dwarfget128(&b);
break;
default: /* something new - skip it */
if(trace) werrstr(" unknown %d", opcount[op]);
for(i=0; i<opcount[op]; i++)
dwarfget128(&b);
break;
}
}
}
if(b.p == nil)
goto bad;
/* finally! the data we seek is in "emit" */
if(emit.file == 0){
werrstr("invalid file index in mapping data");
goto out;
}
if(line)
*line = emit.line;
/* skip over first emit.file-2 guys */
b.p = (uchar*)files;
for(i=emit.file-1; i > 0 && b.p!=nil && *b.p!=0; i--){
dwarfgetstring(&b);
dwarfget128(&b);
dwarfget128(&b);
dwarfget128(&b);
}
if(b.p == nil){
werrstr("problem parsing file data second time (cannot happen)");
goto bad;
}
if(*b.p == 0){
if(i >= nf){
werrstr("bad file index in mapping data");
goto bad;
}
b.p = (uchar*)f[i];
}
s = dwarfgetstring(&b);
*file = s;
i = dwarfget128(&b); /* directory */
x = dwarfget128(&b);
x = dwarfget128(&b);
/* fetch dir name */
cdir = sym.attrs.have.compdir ? sym.attrs.compdir : 0;
char *dwarfdir;
dwarfdir = nil;
b.p = dirs;
for (x = 1; b.p && *b.p; x++) {
dwarfdir = dwarfgetstring(&b);
if (x == i) break;
} }
if (!cdir && dwarfdir) if(trace) werrstr("unit 0x%x stmtlist 0x%x", unit, sym.attrs.stmtlist);
cdir = dwarfdir;
char *filefull = malloc(strlen(cdir) + strlen(*file) + 2);
strcpy(filefull, cdir);
strcat(filefull, "/");
strcat(filefull, *file);
*file = filefull;
*function = nil;
lastline = 0;
runit = dwarfaddrtounit(d, pc, &unit);
if (runit == 0) {
DwarfSym compunit = { };
int renum = dwarfenumunit(d, unit, &compunit);
if (renum < 0)
return -1;
renum = dwarfnextsymat(d, &compunit, proc);
while (renum == 0) {
if (proc->attrs.tag == TagSubprogram &&
proc->attrs.have.name)
{
if (proc->attrs.lowpc <= pc && proc->attrs.highpc > pc) {
*function = malloc(strlen(proc->attrs.name)+1);
strcpy(*function, proc->attrs.name);
goto done;
}
}
renum = dwarfnextsym(d, proc);
}
}
// Next search by declaration memset(&b, 0, sizeof b);
runit = dwarfaddrtounit(d, pc, &unit); b.d = d;
if (runit == 0) { b.p = d->line.data + off;
DwarfSym compunit = { }; b.ep = b.p + d->line.len;
int renum = dwarfenumunit(d, unit, &compunit); b.addrsize = sym.b.addrsize; /* should i get this from somewhere else? */
if (renum < 0)
return -1; len = dwarfget4(&b);
renum = dwarfnextsymat(d, &compunit, proc); if(b.p==nil || b.p+len > b.ep || b.p+len < b.p){
while (renum == 0) { werrstr("bad len\n");
if (proc->attrs.tag == TagSubprogram && goto bad;
proc->attrs.have.name && }
proc->attrs.declfile == emit.file)
{ b.ep = b.p+len;
if (proc->attrs.declline <= *line && vers = dwarfget2(&b);
proc->attrs.declline > lastline) { if(vers != 2){
free(*function); werrstr("bad dwarf version 0x%x", vers);
*function = malloc(strlen(proc->attrs.name)+1); return -1;
strcpy(*function, proc->attrs.name); }
goto done;
} len = dwarfget4(&b);
lastline = proc->attrs.declline; if(b.p==nil || b.p+len > b.ep || b.p+len < b.p){
} werrstr("another bad len\n");
renum = dwarfnextsym(d, proc); goto bad;
} }
} prog = b.p+len;
quantum = dwarfget1(&b);
isstmt = dwarfget1(&b);
linebase = (schar)dwarfget1(&b);
linerange = (schar)dwarfget1(&b);
opcodebase = dwarfget1(&b);
opcount = b.p-1;
dwarfgetnref(&b, opcodebase-1);
if(b.p == nil){
werrstr("bad opcode chart\n");
goto bad;
}
/* just skip the files and dirs for now; we'll come back */
dirs = b.p;
while (b.p && *b.p)
dwarfgetstring(&b);
dwarfget1(&b);
files = (char*)b.p;
while(b.p!=nil && *b.p!=0){
dwarfgetstring(&b);
dwarfget128(&b);
dwarfget128(&b);
dwarfget128(&b);
}
dwarfget1(&b);
/* move on to the program */
if(b.p == nil || b.p > prog){
werrstr("bad header\n");
goto bad;
}
b.p = prog;
reset.addr = 0;
reset.file = 1;
reset.line = 1;
reset.column = 0;
reset.flags = isstmt ? Isstmt : 0;
reset.isa = 0;
cur = reset;
emit = reset;
nf = 0;
start = 0;
if(trace) werrstr("program @ %lu ... %.*H opbase = %d\n", b.p - d->line.data, b.ep-b.p, b.p, opcodebase);
first = 1;
while(b.p != nil){
op = dwarfget1(&b);
if(trace) werrstr("\tline %lu, addr 0x%x, op %d %.10H", cur.line, cur.addr, op, b.p);
if(op >= opcodebase){
a = (op - opcodebase) / linerange;
l = (op - opcodebase) % linerange + linebase;
cur.line += l;
cur.addr += a * quantum;
if(trace) werrstr(" +%d,%d\n", a, l);
emit:
if(first){
if(cur.addr > pc){
werrstr("found wrong line mapping 0x%x for pc 0x%x", cur.addr, pc);
goto out;
}
first = 0;
start = cur.addr;
}
if(cur.addr > pc)
break;
if(b.p == nil){
werrstr("buffer underflow in line mapping");
goto out;
}
emit = cur;
if(emit.flags & EndSequence){
werrstr("found wrong line mapping 0x%x-0x%x for pc 0x%x", start, cur.addr, pc);
goto out;
}
cur.flags &= ~(BasicDwarfBlock|PrologueEnd|EpilogueBegin);
}else{
switch(op){
case 0: /* extended op code */
if(trace) werrstr(" ext");
len = dwarfget128(&b);
end = b.p+len;
if(b.p == nil || end > b.ep || end < b.p || len < 1)
goto bad;
switch(dwarfget1(&b)){
case 1: /* end sequence */
if(trace) werrstr(" end\n");
cur.flags |= EndSequence;
goto emit;
case 2: /* set address */
cur.addr = dwarfgetaddr(&b);
if(trace) werrstr(" set pc 0x%x\n", cur.addr);
break;
case 3: /* define file */
newf = malloc(nf+1*sizeof(f[0]));
if (newf)
RtlMoveMemory(newf, f, nf*sizeof(f[0]));
if(newf == nil)
goto out;
f[nf++] = b.p;
s = dwarfgetstring(&b);
dwarfget128(&b);
dwarfget128(&b);
dwarfget128(&b);
if(trace) werrstr(" def file %s\n", s);
break;
}
if(b.p == nil || b.p > end)
goto bad;
b.p = end;
break;
case 1: /* emit */
if(trace) werrstr(" emit\n");
goto emit;
case 2: /* advance pc */
a = dwarfget128(&b);
if(trace) werrstr(" advance pc + %lu\n", a*quantum);
cur.addr += a * quantum;
break;
case 3: /* advance line */
l = dwarfget128s(&b);
if(trace) werrstr(" advance line + %ld\n", l);
cur.line += l;
break;
case 4: /* set file */
if(trace) werrstr(" set file\n");
cur.file = dwarfget128s(&b);
break;
case 5: /* set column */
if(trace) werrstr(" set column\n");
cur.column = dwarfget128(&b);
break;
case 6: /* negate stmt */
if(trace) werrstr(" negate stmt\n");
cur.flags ^= Isstmt;
break;
case 7: /* set basic block */
if(trace) werrstr(" set basic block\n");
cur.flags |= BasicDwarfBlock;
break;
case 8: /* const add pc */
a = (255 - opcodebase) / linerange * quantum;
if(trace) werrstr(" const add pc + %d\n", a);
cur.addr += a;
break;
case 9: /* fixed advance pc */
a = dwarfget2(&b);
if(trace) werrstr(" fixed advance pc + %d\n", a);
cur.addr += a;
break;
case 10: /* set prologue end */
if(trace) werrstr(" set prologue end\n");
cur.flags |= PrologueEnd;
break;
case 11: /* set epilogue begin */
if(trace) werrstr(" set epilogue begin\n");
cur.flags |= EpilogueBegin;
break;
case 12: /* set isa */
if(trace) werrstr(" set isa\n");
cur.isa = dwarfget128(&b);
break;
default: /* something new - skip it */
if(trace) werrstr(" unknown %d\n", opcount[op]);
for(i=0; i<opcount[op]; i++)
dwarfget128(&b);
break;
}
}
}
if(b.p == nil)
goto bad;
/* finally! the data we seek is in "emit" */
if(emit.file == 0){
werrstr("invalid file index in mapping data");
goto out;
}
if(line)
*line = emit.line;
/* skip over first emit.file-2 guys */
b.p = (uchar*)files;
for(i=emit.file-1; i > 0 && b.p!=nil && *b.p!=0; i--){
dwarfgetstring(&b);
dwarfget128(&b);
dwarfget128(&b);
dwarfget128(&b);
}
if(b.p == nil){
werrstr("problem parsing file data second time (cannot happen)");
goto bad;
}
if(*b.p == 0){
if(i >= nf){
werrstr("bad file index in mapping data");
goto bad;
}
b.p = f[i];
}
s = dwarfgetstring(&b);
if(file)
*file = s;
i = dwarfget128(&b); /* directory */
x = dwarfget128(&b);
if(mtime)
*mtime = x;
x = dwarfget128(&b);
if(length)
*length = x;
/* fetch dir name */
if(cdir)
*cdir = sym.attrs.compdir;
if(dir){
*dir = nil;
b.p = dirs;
for (x = 1; b.p && *b.p; x++)
if (x == i) {
*dir = dwarfgetstring(&b);
break;
}
}
*function = nil;
lastline = 0;
#if 0
if (dwarfenumunit(d, unit, &proc) >= 0) {
dwarfnextsymat(d, &proc, 0);
while (dwarfnextsymat(d, &proc, 1) == 1) {
if (proc.attrs.tag == TagSubprogram &&
proc.attrs.have.name &&
proc.attrs.declfile == emit.file &&
proc.attrs.declline <= *line &&
proc.attrs.declline > lastline) {
lastline = proc.attrs.declline;
free(*function);
*function = malloc(strlen(proc.attrs.name)+1);
strcpy(*function, proc.attrs.name);
}
}
}
#elif 1
ulong lastaddr = 0;
*function = NULL;
for (i = 0; i < d->pe->nsymbols; i++) {
if (d->pe->symtab[i].address > lastaddr &&
d->pe->symtab[i].address <= pc - d->pe->imagebase &&
d->pe->symtab[i].address < d->pe->imagesize) {
lastaddr = d->pe->symtab[i].address;
*function = d->pe->symtab[i].name;
}
}
#else
// *sigh* we get unrelocated low_pc and high_pc because the dwarf symbols
// are not 'loaded' in the PE sense.
if (dwarflookupfn(d, unit, pc, &proc) >= 0) {
*function = malloc(strlen(proc.attrs.name)+1);
strcpy(*function, proc.attrs.name);
}
#endif
/* free at last, free at last */
free(f);
return 0;
/* free at last, free at last */
done:
free(f);
return 0;
bad: bad:
werrstr("corrupted line mapping for 0x%x", pc); werrstr("corrupted line mapping for 0x%x", pc);
out: out:
free(f); free(f);
return -1; return -1;
} }
VOID RosSymFreeInfo(PROSSYM_LINEINFO LineInfo)
{
int i;
free(LineInfo->FileName);
LineInfo->FileName = NULL;
free(LineInfo->FunctionName);
LineInfo->FunctionName = NULL;
for (i = 0; i < sizeof(LineInfo->Parameters)/sizeof(LineInfo->Parameters[0]); i++)
free(LineInfo->Parameters[i].ValueName);
}

View File

@@ -66,7 +66,8 @@ _dwarfnametounit(Dwarf *d, char *name, DwarfBlock *bl, DwarfSym *s)
int int
dwarflookupname(Dwarf *d, char *name, DwarfSym *sym) dwarflookupname(Dwarf *d, char *name, DwarfSym *sym)
{ {
return _dwarfnametounit(d, name, &d->pubnames, sym); if (!d->pubnames.data) return -1;
else return _dwarfnametounit(d, name, &d->pubnames, sym);
} }
/* /*

View File

@@ -47,85 +47,40 @@
#include "pe.h" #include "pe.h"
BOOLEAN BOOLEAN
RosSymGetAddressInformation RosSymGetAddressInformation(PROSSYM_INFO RosSymInfo,
(PROSSYM_INFO RosSymInfo, ULONG_PTR RelativeAddress,
ULONG_PTR RelativeAddress, ULONG *LineNumber,
PROSSYM_LINEINFO RosSymLineInfo) char *FileName,
char *FunctionName)
{ {
ROSSYM_REGISTERS registers; char *cdir, *dir, *file, *function;
DwarfParam params[sizeof(RosSymLineInfo->Parameters)/sizeof(RosSymLineInfo->Parameters[0])]; ulong line, mtime, length;
DwarfSym proc = { };
int i;
int res = dwarfpctoline int res = dwarfpctoline
(RosSymInfo, (RosSymInfo,
&proc,
RelativeAddress + RosSymInfo->pe->imagebase, RelativeAddress + RosSymInfo->pe->imagebase,
&RosSymLineInfo->FileName, &cdir,
&RosSymLineInfo->FunctionName, &dir,
&RosSymLineInfo->LineNumber); &file,
if (res == -1) { &function,
werrstr("Could not get basic function info"); &line,
&mtime,
&length);
if (res != -1) {
*LineNumber = line;
FileName[0] = 0;
if (dir) {
strcpy(FileName, dir);
strcat(FileName, "/");
}
if (file)
strcat(FileName, file);
FunctionName[0] = 0;
if (function)
strcpy(FunctionName, function);
return TRUE;
} else {
return FALSE; return FALSE;
} }
if (!(RosSymLineInfo->Flags & ROSSYM_LINEINFO_HAS_REGISTERS))
return TRUE;
registers = RosSymLineInfo->Registers;
DwarfExpr cfa = { };
ulong cfaLocation;
if (dwarfregunwind
(RosSymInfo,
RelativeAddress + RosSymInfo->pe->imagebase,
proc.attrs.framebase.c,
&cfa,
&registers) == -1) {
werrstr("Can't get cfa location for %s", RosSymLineInfo->FunctionName);
return TRUE;
}
res = dwarfgetparams
(RosSymInfo,
&proc,
RelativeAddress + RosSymInfo->pe->imagebase,
sizeof(params)/sizeof(params[0]),
params);
if (res == -1) {
werrstr("%s: could not get params at all", RosSymLineInfo->FunctionName);
RosSymLineInfo->NumParams = 0;
return TRUE;
}
werrstr("%s: res %d", RosSymLineInfo->FunctionName, res);
RosSymLineInfo->NumParams = res;
res = dwarfcomputecfa(RosSymInfo, &cfa, &registers, &cfaLocation);
if (res == -1) {
werrstr("%s: could not get our own cfa", RosSymLineInfo->FunctionName);
return TRUE;
}
for (i = 0; i < RosSymLineInfo->NumParams; i++) {
werrstr("Getting arg %s, unit %x, type %x",
params[i].name, params[i].unit, params[i].type);
res = dwarfargvalue
(RosSymInfo,
&proc,
RelativeAddress + RosSymInfo->pe->imagebase,
cfaLocation,
&registers,
&params[i]);
if (res == -1) { RosSymLineInfo->NumParams = i; return TRUE; }
werrstr("%s: %x", params[i].name, params[i].value);
RosSymLineInfo->Parameters[i].ValueName = malloc(strlen(params[i].name)+1);
strcpy(RosSymLineInfo->Parameters[i].ValueName, params[i].name);
free(params[i].name);
RosSymLineInfo->Parameters[i].Value = params[i].value;
}
return TRUE;
} }
/* EOF */ /* EOF */

View File

@@ -20,144 +20,182 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#define SYMBOL_SIZE 18
extern NTSTATUS RosSymStatus;
BOOLEAN BOOLEAN
RosSymCreateFromFile(PVOID FileContext, PROSSYM_INFO *RosSymInfo) RosSymCreateFromFile(PVOID FileContext, PROSSYM_INFO *RosSymInfo)
{ {
IMAGE_DOS_HEADER DosHeader; IMAGE_DOS_HEADER DosHeader;
IMAGE_NT_HEADERS NtHeaders; IMAGE_NT_HEADERS NtHeaders;
PIMAGE_SECTION_HEADER SectionHeaders; PIMAGE_SECTION_HEADER SectionHeaders;
unsigned SectionIndex; unsigned SectionIndex;
unsigned SymbolTable, NumSymbols; unsigned SymbolTable, NumSymbols;
/* Load DOS header */ /* Load DOS header */
if (! RosSymSeekFile(FileContext, 0)) DPRINT("About to read file\n");
if (! RosSymReadFile(FileContext, &DosHeader, sizeof(IMAGE_DOS_HEADER)))
{ {
werrstr("Could not rewind file\n"); DPRINT1("Failed to read DOS header\n");
return FALSE; return FALSE;
} }
if (! RosSymReadFile(FileContext, &DosHeader, sizeof(IMAGE_DOS_HEADER))) if (! ROSSYM_IS_VALID_DOS_HEADER(&DosHeader))
{ {
werrstr("Failed to read DOS header %x\n", RosSymStatus); DPRINT1("Image doesn't have a valid DOS header\n");
return FALSE; return FALSE;
}
if (! ROSSYM_IS_VALID_DOS_HEADER(&DosHeader))
{
werrstr("Image doesn't have a valid DOS header\n");
return FALSE;
} }
/* Load NT headers */ /* Load NT headers */
if (! RosSymSeekFile(FileContext, DosHeader.e_lfanew)) if (! RosSymSeekFile(FileContext, DosHeader.e_lfanew))
{ {
werrstr("Failed seeking to NT headers\n"); DPRINT1("Failed seeking to NT headers\n");
return FALSE; return FALSE;
} }
if (! RosSymReadFile(FileContext, &NtHeaders, sizeof(IMAGE_NT_HEADERS))) if (! RosSymReadFile(FileContext, &NtHeaders, sizeof(IMAGE_NT_HEADERS)))
{ {
werrstr("Failed to read NT headers\n"); DPRINT1("Failed to read NT headers\n");
return FALSE; return FALSE;
} }
if (! ROSSYM_IS_VALID_NT_HEADERS(&NtHeaders)) if (! ROSSYM_IS_VALID_NT_HEADERS(&NtHeaders))
{ {
werrstr("Image doesn't have a valid PE header\n"); DPRINT1("Image doesn't have a valid PE header\n");
return FALSE; return FALSE;
} }
SymbolTable = NtHeaders.FileHeader.PointerToSymbolTable; SymbolTable = NtHeaders.FileHeader.PointerToSymbolTable;
NumSymbols = NtHeaders.FileHeader.NumberOfSymbols; NumSymbols = NtHeaders.FileHeader.NumberOfSymbols;
if (!NumSymbols) if (!NumSymbols)
{ {
werrstr("Image doesn't have debug symbols\n"); DPRINT1("Image doesn't have debug symbols\n");
return FALSE; return FALSE;
} }
DPRINT("SymbolTable %x NumSymbols %x\n", SymbolTable, NumSymbols); DPRINT("SymbolTable %x NumSymbols %x\n", SymbolTable, NumSymbols);
/* Load section headers */ /* Load section headers */
if (! RosSymSeekFile(FileContext, (char *) IMAGE_FIRST_SECTION(&NtHeaders) - if (! RosSymSeekFile(FileContext, (char *) IMAGE_FIRST_SECTION(&NtHeaders) -
(char *) &NtHeaders + DosHeader.e_lfanew)) (char *) &NtHeaders + DosHeader.e_lfanew))
{ {
werrstr("Failed seeking to section headers\n"); DPRINT1("Failed seeking to section headers\n");
return FALSE; return FALSE;
} }
DPRINT("Alloc section headers\n"); SectionHeaders = RosSymAllocMem(NtHeaders.FileHeader.NumberOfSections
SectionHeaders = RosSymAllocMem(NtHeaders.FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER));
* sizeof(IMAGE_SECTION_HEADER)); if (NULL == SectionHeaders)
if (NULL == SectionHeaders)
{ {
werrstr("Failed to allocate memory for %u section headers\n", DPRINT1("Failed to allocate memory for %u section headers\n",
NtHeaders.FileHeader.NumberOfSections); NtHeaders.FileHeader.NumberOfSections);
return FALSE; return FALSE;
} }
if (! RosSymReadFile(FileContext, SectionHeaders, if (! RosSymReadFile(FileContext, SectionHeaders,
NtHeaders.FileHeader.NumberOfSections NtHeaders.FileHeader.NumberOfSections
* sizeof(IMAGE_SECTION_HEADER))) * sizeof(IMAGE_SECTION_HEADER)))
{ {
RosSymFreeMem(SectionHeaders); RosSymFreeMem(SectionHeaders);
werrstr("Failed to read section headers\n"); DPRINT1("Failed to read section headers\n");
return FALSE; return FALSE;
} }
// Convert names to ANSI_STRINGs // Convert names to ANSI_STRINGs
for (SectionIndex = 0; SectionIndex < NtHeaders.FileHeader.NumberOfSections; for (SectionIndex = 0; SectionIndex < NtHeaders.FileHeader.NumberOfSections;
SectionIndex++) SectionIndex++)
{ {
ANSI_STRING astr; ANSI_STRING astr;
if (SectionHeaders[SectionIndex].Name[0] != '/') { if (SectionHeaders[SectionIndex].Name[0] != '/') {
DPRINT("Short name string %d, %s\n", SectionIndex, SectionHeaders[SectionIndex].Name); DPRINT("Short name string %d, %s\n", SectionIndex, SectionHeaders[SectionIndex].Name);
astr.Buffer = RosSymAllocMem(IMAGE_SIZEOF_SHORT_NAME); astr.Buffer = RosSymAllocMem(IMAGE_SIZEOF_SHORT_NAME);
memcpy(astr.Buffer, SectionHeaders[SectionIndex].Name, IMAGE_SIZEOF_SHORT_NAME); memcpy(astr.Buffer, SectionHeaders[SectionIndex].Name, IMAGE_SIZEOF_SHORT_NAME);
astr.MaximumLength = IMAGE_SIZEOF_SHORT_NAME; astr.MaximumLength = IMAGE_SIZEOF_SHORT_NAME;
astr.Length = GetStrnlen(astr.Buffer, IMAGE_SIZEOF_SHORT_NAME); astr.Length = GetStrnlen(astr.Buffer, IMAGE_SIZEOF_SHORT_NAME);
} else { } else {
UNICODE_STRING intConv; UNICODE_STRING intConv;
NTSTATUS Status; NTSTATUS Status;
ULONG StringOffset; ULONG StringOffset;
Status = RtlCreateUnicodeStringFromAsciiz(&intConv, (PCSZ)SectionHeaders[SectionIndex].Name + 1); Status = RtlCreateUnicodeStringFromAsciiz(&intConv, (PCSZ)SectionHeaders[SectionIndex].Name + 1);
if (!NT_SUCCESS(Status)) goto freeall; if (!NT_SUCCESS(Status)) goto freeall;
Status = RtlUnicodeStringToInteger(&intConv, 10, &StringOffset); Status = RtlUnicodeStringToInteger(&intConv, 10, &StringOffset);
RtlFreeUnicodeString(&intConv); RtlFreeUnicodeString(&intConv);
if (!NT_SUCCESS(Status)) goto freeall; if (!NT_SUCCESS(Status)) goto freeall;
if (!RosSymSeekFile(FileContext, SymbolTable + NumSymbols * SYMBOL_SIZE + StringOffset)) if (!RosSymSeekFile(FileContext, SymbolTable + NumSymbols * SYMBOL_SIZE + StringOffset))
goto freeall; goto freeall;
astr.Buffer = RosSymAllocMem(MAXIMUM_DWARF_NAME_SIZE); astr.Buffer = RosSymAllocMem(MAXIMUM_DWARF_NAME_SIZE);
if (!RosSymReadFile(FileContext, astr.Buffer, MAXIMUM_DWARF_NAME_SIZE)) if (!RosSymReadFile(FileContext, astr.Buffer, MAXIMUM_DWARF_NAME_SIZE))
goto freeall; goto freeall;
astr.Length = GetStrnlen(astr.Buffer, MAXIMUM_DWARF_NAME_SIZE); astr.Length = GetStrnlen(astr.Buffer, MAXIMUM_DWARF_NAME_SIZE);
astr.MaximumLength = MAXIMUM_DWARF_NAME_SIZE; astr.MaximumLength = MAXIMUM_DWARF_NAME_SIZE;
DPRINT("Long name %d, %s\n", SectionIndex, astr.Buffer); DPRINT("Long name %d, %s\n", SectionIndex, astr.Buffer);
} }
*ANSI_NAME_STRING(&SectionHeaders[SectionIndex]) = astr; *ANSI_NAME_STRING(&SectionHeaders[SectionIndex]) = astr;
} }
DPRINT("Done with sections\n"); DPRINT("Done with sections\n");
Pe *pe = RosSymAllocMem(sizeof(*pe)); Pe *pe = RosSymAllocMem(sizeof(*pe));
pe->fd = FileContext; pe->fd = FileContext;
pe->e2 = peget2; pe->e2 = peget2;
pe->e4 = peget4; pe->e4 = peget4;
pe->e8 = peget8; pe->e8 = peget8;
pe->nsections = NtHeaders.FileHeader.NumberOfSections; pe->nsections = NtHeaders.FileHeader.NumberOfSections;
pe->sect = SectionHeaders; pe->sect = SectionHeaders;
pe->imagebase = pe->loadbase = NtHeaders.OptionalHeader.ImageBase; pe->nsymbols = NtHeaders.FileHeader.NumberOfSymbols;
pe->imagesize = NtHeaders.OptionalHeader.SizeOfImage; pe->symtab = malloc(pe->nsymbols * sizeof(CoffSymbol));
pe->loadsection = loaddisksection; SYMENT SymbolData;
*RosSymInfo = dwarfopen(pe); int i, j;
DPRINT("Getting symbol data\n");
ASSERT(sizeof(SymbolData) == 18);
for (i = 0, j = 0; i < pe->nsymbols; i++) {
if (!RosSymSeekFile
(FileContext,
NtHeaders.FileHeader.PointerToSymbolTable + i * sizeof(SymbolData)))
goto freeall;
if (!RosSymReadFile(FileContext, &SymbolData, sizeof(SymbolData)))
goto freeall;
if ((SymbolData.e_scnum < 1) ||
(SymbolData.e_sclass != C_EXT &&
SymbolData.e_sclass != C_STAT))
continue;
int section = SymbolData.e_scnum - 1;
if (SymbolData.e.e.e_zeroes) {
pe->symtab[j].name = malloc(sizeof(SymbolData.e.e_name)+1);
memcpy(pe->symtab[j].name, SymbolData.e.e_name, sizeof(SymbolData.e.e_name));
pe->symtab[j].name[sizeof(SymbolData.e.e_name)] = 0;
} else {
if (!RosSymSeekFile
(FileContext,
NtHeaders.FileHeader.PointerToSymbolTable +
(NtHeaders.FileHeader.NumberOfSymbols * 18) +
SymbolData.e.e.e_offset))
goto freeall;
pe->symtab[j].name = malloc(MAXIMUM_COFF_SYMBOL_LENGTH+1);
pe->symtab[j].name[MAXIMUM_COFF_SYMBOL_LENGTH] = 0;
// It's possible that we've got a string just at the end of the file
// we'll skip that symbol if needed
if (!RosSymReadFile(FileContext, pe->symtab[j].name, MAXIMUM_COFF_SYMBOL_LENGTH)) {
free(pe->symtab[j].name);
continue;
}
}
if (pe->symtab[j].name[0] == '.') {
free(pe->symtab[j].name);
continue;
}
pe->symtab[j].address = pe->sect[section].VirtualAddress + SymbolData.e_value;
j++;
}
DPRINT("%d symbols\n", j);
pe->nsymbols = j;
pe->imagebase = pe->loadbase = NtHeaders.OptionalHeader.ImageBase;
pe->imagesize = NtHeaders.OptionalHeader.SizeOfImage;
pe->loadsection = loaddisksection;
*RosSymInfo = dwarfopen(pe);
return TRUE; return TRUE;
freeall: freeall:
for (SectionIndex = 0; SectionIndex < NtHeaders.FileHeader.NumberOfSections; for (SectionIndex = 0; SectionIndex < NtHeaders.FileHeader.NumberOfSections;
SectionIndex++) SectionIndex++)
RtlFreeAnsiString(ANSI_NAME_STRING(&SectionHeaders[SectionIndex])); RtlFreeAnsiString(ANSI_NAME_STRING(&SectionHeaders[SectionIndex]));
RosSymFreeMem(SectionHeaders); RosSymFreeMem(SectionHeaders);
return FALSE; return FALSE;
} }
/* EOF */ /* EOF */

View File

@@ -38,8 +38,8 @@ RosSymInitKernelMode(VOID)
{ {
RosSymAllocMemKM, RosSymAllocMemKM,
RosSymFreeMemKM, RosSymFreeMemKM,
RosSymIoReadFile, RosSymZwReadFile,
RosSymIoSeekFile RosSymZwSeekFile
}; };
RosSymInit(&KmCallbacks); RosSymInit(&KmCallbacks);

View File

@@ -7,13 +7,9 @@
* PROGRAMMERS: Ge van Geldorp (gvg@reactos.com) * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com)
*/ */
#define WIN32_NO_STATUS
#include <windows.h> #include <windows.h>
#include <reactos/rossym.h> #include <reactos/rossym.h>
#include "rossympriv.h" #include "rossympriv.h"
#define NTOS_MODE_USER
#include <ndk/ntndk.h>
#include <pseh/pseh.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
@@ -21,19 +17,13 @@
static PVOID static PVOID
RosSymAllocMemUM(ULONG_PTR Size) RosSymAllocMemUM(ULONG_PTR Size)
{ {
return RtlAllocateHeap(RtlGetProcessHeap(), 0, Size); return HeapAlloc(GetProcessHeap(), 0, Size);
} }
static VOID static VOID
RosSymFreeMemUM(PVOID Area) RosSymFreeMemUM(PVOID Area)
{ {
RtlFreeHeap(RtlGetProcessHeap(), 0, Area); HeapFree(GetProcessHeap(), 0, Area);
}
static BOOLEAN
RosSymGetMemUM(ULONG_PTR *Target, PVOID SourceMem, ULONG Size)
{
return FALSE;
} }
VOID VOID
@@ -44,8 +34,7 @@ RosSymInitUserMode(VOID)
RosSymAllocMemUM, RosSymAllocMemUM,
RosSymFreeMemUM, RosSymFreeMemUM,
RosSymZwReadFile, RosSymZwReadFile,
RosSymZwSeekFile, RosSymZwSeekFile
RosSymGetMemUM
}; };
RosSymInit(&KmCallbacks); RosSymInit(&KmCallbacks);

View File

@@ -1,34 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: lib/rossym/zwfile.c
* PURPOSE: File I/O using native functions
*
* PROGRAMMERS: Ge van Geldorp (gvg@reactos.com)
*/
#define NTOSAPI
#include <ntddk.h>
#include <reactos/rossym.h>
#include "rossympriv.h"
#define NDEBUG
#include <debug.h>
NTSTATUS RosSymStatus;
BOOLEAN
RosSymIoReadFile(PVOID FileContext, PVOID Buffer, ULONG Size)
{
PROSSYM_OWN_FILECONTEXT OwnContext = (PROSSYM_OWN_FILECONTEXT)FileContext;
return OwnContext->ReadFileProc(FileContext, Buffer, Size);
}
BOOLEAN
RosSymIoSeekFile(PVOID FileContext, ULONG_PTR Position)
{
PROSSYM_OWN_FILECONTEXT OwnContext = (PROSSYM_OWN_FILECONTEXT)FileContext;
return OwnContext->SeekFileProc(FileContext, Position);
}
/* EOF */

View File

@@ -6,19 +6,49 @@
struct DwarfBlock; struct DwarfBlock;
typedef struct _IMAGE_SECTION_HEADER PeSect; typedef struct _IMAGE_SECTION_HEADER PeSect;
typedef struct _CoffSymbol {
ulong address;
char *name;
} CoffSymbol;
typedef struct _Pe { typedef struct _Pe {
void *fd; void *fd;
u16int (*e2)(const unsigned char *data); u16int (*e2)(const unsigned char *data);
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 nsymbols;
CoffSymbol *symtab;
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;
} Pe; } Pe;
#define E_SYMNMLEN 8
#include <pshpack1.h>
typedef struct {
union {
char e_name[E_SYMNMLEN];
struct {
unsigned long e_zeroes;
unsigned long e_offset;
} e;
} e;
unsigned long e_value;
short e_scnum;
unsigned short e_type;
unsigned char e_sclass;
unsigned char e_numaux;
} SYMENT, *PSYMENT;
#include <poppack.h>
#define C_EXT 2
#define C_STAT 3
#define DT_FCN 0x40
Pe *peopen(const char *name); Pe *peopen(const char *name);
int loaddisksection(struct _Pe *pe, char *name, struct DwarfBlock *b); int loaddisksection(struct _Pe *pe, char *name, struct DwarfBlock *b);
int loadmemsection(struct _Pe *pe, char *name, struct DwarfBlock *b);
u16int peget2(const unsigned char *ptr); u16int peget2(const unsigned char *ptr);
u32int peget4(const unsigned char *ptr); u32int peget4(const unsigned char *ptr);
u64int peget8(const unsigned char *ptr); u64int peget8(const unsigned char *ptr);

View File

@@ -9,15 +9,12 @@
#pragma once #pragma once
#define HIGHBIT 0x80000000
extern ROSSYM_CALLBACKS RosSymCallbacks; extern ROSSYM_CALLBACKS RosSymCallbacks;
#define RosSymAllocMem(Size) (*RosSymCallbacks.AllocMemProc)(Size) #define RosSymAllocMem(Size) (*RosSymCallbacks.AllocMemProc)(Size)
#define RosSymFreeMem(Area) (*RosSymCallbacks.FreeMemProc)(Area) #define RosSymFreeMem(Area) (*RosSymCallbacks.FreeMemProc)(Area)
#define RosSymReadFile(FileContext, Buffer, Size) (*RosSymCallbacks.ReadFileProc)((FileContext), (Buffer), (Size)) #define RosSymReadFile(FileContext, Buffer, Size) (*RosSymCallbacks.ReadFileProc)((FileContext), (Buffer), (Size))
#define RosSymSeekFile(FileContext, Position) (*RosSymCallbacks.SeekFileProc)((FileContext), (Position)) #define RosSymSeekFile(FileContext, Position) (*RosSymCallbacks.SeekFileProc)((FileContext), (Position))
#define RosSymGetMem(TargetAddress, Address, Size) (*RosSymCallbacks.MemGetProc)((TargetAddress), (Address), (Size))
extern BOOLEAN RosSymZwReadFile(PVOID FileContext, PVOID Buffer, ULONG Size); extern BOOLEAN RosSymZwReadFile(PVOID FileContext, PVOID Buffer, ULONG Size);
extern BOOLEAN RosSymZwSeekFile(PVOID FileContext, ULONG_PTR Position); extern BOOLEAN RosSymZwSeekFile(PVOID FileContext, ULONG_PTR Position);

View File

@@ -15,40 +15,38 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
NTSTATUS RosSymStatus;
BOOLEAN BOOLEAN
RosSymZwReadFile(PVOID FileContext, PVOID Buffer, ULONG Size) RosSymZwReadFile(PVOID FileContext, PVOID Buffer, ULONG Size)
{ {
//NTSTATUS Status; NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock; IO_STATUS_BLOCK IoStatusBlock;
RosSymStatus = ZwReadFile(*((HANDLE *) FileContext), Status = ZwReadFile(*((HANDLE *) FileContext),
0, 0, 0, 0, 0, 0,
&IoStatusBlock, &IoStatusBlock,
Buffer, Buffer,
Size, Size,
0, 0); 0, 0);
return NT_SUCCESS(RosSymStatus) && IoStatusBlock.Information == Size; return NT_SUCCESS(Status) && IoStatusBlock.Information == Size;
} }
BOOLEAN BOOLEAN
RosSymZwSeekFile(PVOID FileContext, ULONG_PTR Position) RosSymZwSeekFile(PVOID FileContext, ULONG_PTR Position)
{ {
//NTSTATUS Status; NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock; IO_STATUS_BLOCK IoStatusBlock;
FILE_POSITION_INFORMATION NewPosition; FILE_POSITION_INFORMATION NewPosition;
NewPosition.CurrentByteOffset.u.HighPart = 0; NewPosition.CurrentByteOffset.u.HighPart = 0;
NewPosition.CurrentByteOffset.u.LowPart = Position; NewPosition.CurrentByteOffset.u.LowPart = Position;
RosSymStatus = ZwSetInformationFile(*((HANDLE *) FileContext), Status = ZwSetInformationFile(*((HANDLE *) FileContext),
&IoStatusBlock, &IoStatusBlock,
(PVOID) &NewPosition, (PVOID) &NewPosition,
sizeof(FILE_POSITION_INFORMATION), sizeof(FILE_POSITION_INFORMATION),
FilePositionInformation); FilePositionInformation);
return NT_SUCCESS(RosSymStatus); return NT_SUCCESS(Status);
} }
/* EOF */ /* EOF */

View File

@@ -32,6 +32,7 @@ if(NEWCC)
cache/pinsup.c cache/pinsup.c
cache/section/data.c cache/section/data.c
cache/section/fault.c cache/section/fault.c
cache/section/io.c
cache/section/reqtools.c cache/section/reqtools.c
cache/section/sptab.c cache/section/sptab.c
cache/section/swapout.c) cache/section/swapout.c)
@@ -46,7 +47,6 @@ else()
endif() endif()
list(APPEND SOURCE list(APPEND SOURCE
cache/section/io.c
config/cmalloc.c config/cmalloc.c
config/cmapi.c config/cmapi.c
config/cmboot.c config/cmboot.c

View File

@@ -99,7 +99,6 @@ MiSimpleRead
PLARGE_INTEGER FileOffset, PLARGE_INTEGER FileOffset,
PVOID Buffer, PVOID Buffer,
ULONG Length, ULONG Length,
BOOLEAN Paging,
PIO_STATUS_BLOCK ReadStatus) PIO_STATUS_BLOCK ReadStatus)
{ {
NTSTATUS Status; NTSTATUS Status;
@@ -128,7 +127,7 @@ MiSimpleRead
Length); Length);
KeInitializeEvent(&ReadWait, NotificationEvent, FALSE); KeInitializeEvent(&ReadWait, NotificationEvent, FALSE);
Irp = IoBuildAsynchronousFsdRequest Irp = IoBuildAsynchronousFsdRequest
(IRP_MJ_READ, (IRP_MJ_READ,
DeviceObject, DeviceObject,
@@ -142,7 +141,7 @@ MiSimpleRead
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
} }
Irp->Flags |= (Paging ? IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO | IRP_NOCACHE : 0) | IRP_SYNCHRONOUS_API; Irp->Flags |= IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO | IRP_NOCACHE | IRP_SYNCHRONOUS_API;
Irp->UserEvent = &ReadWait; Irp->UserEvent = &ReadWait;
Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->Tail.Overlay.OriginalFileObject = FileObject;
@@ -151,8 +150,7 @@ MiSimpleRead
IrpSp->Control |= SL_INVOKE_ON_SUCCESS | SL_INVOKE_ON_ERROR; IrpSp->Control |= SL_INVOKE_ON_SUCCESS | SL_INVOKE_ON_ERROR;
IrpSp->FileObject = FileObject; IrpSp->FileObject = FileObject;
IrpSp->CompletionRoutine = MiSimpleReadComplete; IrpSp->CompletionRoutine = MiSimpleReadComplete;
ObReferenceObject(FileObject);
Status = IoCallDriver(DeviceObject, Irp); Status = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING)
{ {

View File

@@ -181,7 +181,6 @@ MiSimpleRead
PLARGE_INTEGER FileOffset, PLARGE_INTEGER FileOffset,
PVOID Buffer, PVOID Buffer,
ULONG Length, ULONG Length,
BOOLEAN Paging,
PIO_STATUS_BLOCK ReadStatus); PIO_STATUS_BLOCK ReadStatus);
NTSTATUS NTSTATUS
@@ -405,6 +404,40 @@ MmCreateCacheSection
ULONG AllocationAttributes, ULONG AllocationAttributes,
PFILE_OBJECT FileObject); PFILE_OBJECT FileObject);
NTSTATUS
NTAPI
MiSimpleRead
(PFILE_OBJECT FileObject,
PLARGE_INTEGER FileOffset,
PVOID Buffer,
ULONG Length,
PIO_STATUS_BLOCK ReadStatus);
NTSTATUS
NTAPI
_MiSimpleWrite
(PFILE_OBJECT FileObject,
PLARGE_INTEGER FileOffset,
PVOID Buffer,
ULONG Length,
PIO_STATUS_BLOCK ReadStatus,
const char *file,
int line);
#define MiSimpleWrite(F,O,B,L,R) _MiSimpleWrite(F,O,B,L,R,__FILE__,__LINE__)
NTSTATUS
NTAPI
_MiWriteBackPage
(PFILE_OBJECT FileObject,
PLARGE_INTEGER Offset,
ULONG Length,
PFN_NUMBER Page,
const char *File,
int Line);
#define MiWriteBackPage(F,O,L,P) _MiWriteBackPage(F,O,L,P,__FILE__,__LINE__)
PVOID PVOID
NTAPI NTAPI
MmGetSegmentRmap(PFN_NUMBER Page, PULONG RawOffset); MmGetSegmentRmap(PFN_NUMBER Page, PULONG RawOffset);

View File

@@ -75,14 +75,15 @@ KdbSymProcessSymbols(
BOOLEAN BOOLEAN
KdbSymPrintAddress( KdbSymPrintAddress(
IN PVOID Address, IN PVOID Address);
IN PKTRAP_FRAME Context);
NTSTATUS NTSTATUS
KdbSymGetAddressInformation( KdbSymGetAddressInformation(
IN PROSSYM_INFO RosSymInfo, IN PROSSYM_INFO RosSymInfo,
IN ULONG_PTR RelativeAddress, IN ULONG_PTR RelativeAddress,
IN PROSSYM_LINEINFO RosSymLineInfo OUT PULONG LineNumber OPTIONAL,
OUT PCH FileName OPTIONAL,
OUT PCH FunctionName OPTIONAL
); );
#endif #endif

View File

@@ -78,7 +78,7 @@ KdbpMemoryError(int Status, unsigned int Addr,
static void static void
KdbpPrintAddressInCode(unsigned int Addr, struct disassemble_info * Ignored) KdbpPrintAddressInCode(unsigned int Addr, struct disassemble_info * Ignored)
{ {
if (!KdbSymPrintAddress((void*)Addr, NULL)) if (!KdbSymPrintAddress((void*)Addr))
{ {
DbgPrint("<%08x>", Addr); DbgPrint("<%08x>", Addr);
} }

View File

@@ -595,7 +595,7 @@ KdbpCmdDisassembleX(
while (Count > 0) while (Count > 0)
{ {
if (!KdbSymPrintAddress((PVOID)Address, NULL)) if (!KdbSymPrintAddress((PVOID)Address))
KdbpPrint("<%x>:", Address); KdbpPrint("<%x>:", Address);
else else
KdbpPrint(":"); KdbpPrint(":");
@@ -621,7 +621,7 @@ KdbpCmdDisassembleX(
/* Disassemble */ /* Disassemble */
while (Count-- > 0) while (Count-- > 0)
{ {
if (!KdbSymPrintAddress((PVOID)Address, NULL)) if (!KdbSymPrintAddress((PVOID)Address))
KdbpPrint("<%08x>: ", Address); KdbpPrint("<%08x>: ", Address);
else else
KdbpPrint(": "); KdbpPrint(": ");
@@ -794,7 +794,6 @@ KdbpCmdBackTrace(
ULONGLONG Result = 0; ULONGLONG Result = 0;
ULONG_PTR Frame = KdbCurrentTrapFrame->Tf.Ebp; ULONG_PTR Frame = KdbCurrentTrapFrame->Tf.Ebp;
ULONG_PTR Address; ULONG_PTR Address;
KTRAP_FRAME TrapFrame;
if (Argc >= 2) if (Argc >= 2)
{ {
@@ -854,19 +853,15 @@ KdbpCmdBackTrace(
KdbpPrint("Eip:\n"); KdbpPrint("Eip:\n");
/* Try printing the function at EIP */ /* Try printing the function at EIP */
if (!KdbSymPrintAddress((PVOID)KdbCurrentTrapFrame->Tf.Eip, &KdbCurrentTrapFrame->Tf)) if (!KdbSymPrintAddress((PVOID)KdbCurrentTrapFrame->Tf.Eip))
KdbpPrint("<%08x>\n", KdbCurrentTrapFrame->Tf.Eip); KdbpPrint("<%08x>\n", KdbCurrentTrapFrame->Tf.Eip);
else else
KdbpPrint("\n"); KdbpPrint("\n");
} }
TrapFrame = KdbCurrentTrapFrame->Tf;
KdbpPrint("Frames:\n"); KdbpPrint("Frames:\n");
for (;;) for (;;)
{ {
BOOLEAN GotNextFrame;
if (Frame == 0) if (Frame == 0)
break; break;
@@ -876,11 +871,8 @@ KdbpCmdBackTrace(
break; break;
} }
if ((GotNextFrame = NT_SUCCESS(KdbpSafeReadMemory(&Frame, (PVOID)Frame, sizeof (ULONG_PTR)))))
TrapFrame.Ebp = Frame;
/* Print the location of the call instruction */ /* Print the location of the call instruction */
if (!KdbSymPrintAddress((PVOID)(Address - 5), &TrapFrame)) if (!KdbSymPrintAddress((PVOID)(Address - 5)))
KdbpPrint("<%08x>\n", Address); KdbpPrint("<%08x>\n", Address);
else else
KdbpPrint("\n"); KdbpPrint("\n");
@@ -890,7 +882,7 @@ KdbpCmdBackTrace(
if (Address == 0) if (Address == 0)
break; break;
if (!GotNextFrame) if (!NT_SUCCESS(KdbpSafeReadMemory(&Frame, (PVOID)Frame, sizeof (ULONG_PTR))))
{ {
KdbpPrint("Couldn't access memory at 0x%p!\n", Frame); KdbpPrint("Couldn't access memory at 0x%p!\n", Frame);
break; break;
@@ -2674,7 +2666,7 @@ KdbpCliMainLoop(
if (EnteredOnSingleStep) if (EnteredOnSingleStep)
{ {
if (!KdbSymPrintAddress((PVOID)KdbCurrentTrapFrame->Tf.Eip, &KdbCurrentTrapFrame->Tf)) if (!KdbSymPrintAddress((PVOID)KdbCurrentTrapFrame->Tf.Eip))
{ {
KdbpPrint("<%x>", KdbCurrentTrapFrame->Tf.Eip); KdbpPrint("<%x>", KdbCurrentTrapFrame->Tf.Eip);
} }

View File

@@ -13,7 +13,6 @@
#include <ntoskrnl.h> #include <ntoskrnl.h>
#define NDEBUG #define NDEBUG
#include "../cache/section/newmm.h"
#include <debug.h> #include <debug.h>
/* GLOBALS ******************************************************************/ /* GLOBALS ******************************************************************/
@@ -27,61 +26,13 @@ typedef struct _IMAGE_SYMBOL_INFO_CACHE
} }
IMAGE_SYMBOL_INFO_CACHE, *PIMAGE_SYMBOL_INFO_CACHE; IMAGE_SYMBOL_INFO_CACHE, *PIMAGE_SYMBOL_INFO_CACHE;
typedef struct _ROSSYM_KM_OWN_CONTEXT {
LARGE_INTEGER FileOffset;
PFILE_OBJECT FileObject;
} ROSSYM_KM_OWN_CONTEXT, *PROSSYM_KM_OWN_CONTEXT;
static BOOLEAN LoadSymbols; static BOOLEAN LoadSymbols;
static LIST_ENTRY SymbolFileListHead; static LIST_ENTRY SymbolFileListHead;
static KSPIN_LOCK SymbolFileListLock; static KSPIN_LOCK SymbolFileListLock;
static PROSSYM_INFO KdbpRosSymInfo;
static ULONG_PTR KdbpImageBase;
BOOLEAN KdbpSymbolsInitialized = FALSE; BOOLEAN KdbpSymbolsInitialized = FALSE;
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
static BOOLEAN
KdbpSeekSymFile(PVOID FileContext, ULONG_PTR Target)
{
PROSSYM_KM_OWN_CONTEXT Context = (PROSSYM_KM_OWN_CONTEXT)FileContext;
Context->FileOffset.QuadPart = Target;
return TRUE;
}
static BOOLEAN
KdbpReadSymFile(PVOID FileContext, PVOID Buffer, ULONG Length)
{
PROSSYM_KM_OWN_CONTEXT Context = (PROSSYM_KM_OWN_CONTEXT)FileContext;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status = MiSimpleRead
(Context->FileObject,
&Context->FileOffset,
Buffer,
Length,
FALSE,
&Iosb);
return NT_SUCCESS(Status);
}
static PROSSYM_KM_OWN_CONTEXT
KdbpCaptureFileForSymbols(PFILE_OBJECT FileObject)
{
PROSSYM_KM_OWN_CONTEXT Context = ExAllocatePool(NonPagedPool, sizeof(*Context));
if (!Context) return NULL;
ObReferenceObject(FileObject);
Context->FileOffset.QuadPart = 0;
Context->FileObject = FileObject;
return Context;
}
static VOID
KdbpReleaseFileForSymbols(PROSSYM_KM_OWN_CONTEXT Context)
{
ObDereferenceObject(Context->FileObject);
ExFreePool(Context);
}
static BOOLEAN static BOOLEAN
KdbpSymSearchModuleList( KdbpSymSearchModuleList(
IN PLIST_ENTRY current_entry, IN PLIST_ENTRY current_entry,
@@ -171,145 +122,33 @@ KdbpSymFindModule(
*/ */
BOOLEAN BOOLEAN
KdbSymPrintAddress( KdbSymPrintAddress(
IN PVOID Address, IN PVOID Address)
IN PKTRAP_FRAME Context)
{ {
int i;
PMEMORY_AREA MemoryArea = NULL;
PROS_SECTION_OBJECT SectionObject;
PLDR_DATA_TABLE_ENTRY LdrEntry; PLDR_DATA_TABLE_ENTRY LdrEntry;
PROSSYM_KM_OWN_CONTEXT FileContext;
ULONG_PTR RelativeAddress; ULONG_PTR RelativeAddress;
NTSTATUS Status; NTSTATUS Status;
ROSSYM_LINEINFO LineInfo = { }; ULONG LineNumber;
CHAR FileName[256];
struct { CHAR FunctionName[256];
enum _ROSSYM_REGNAME regname;
size_t ctx_offset;
} regmap[] = {
{ ROSSYM_X86_EDX, FIELD_OFFSET(KTRAP_FRAME, Edx) },
{ ROSSYM_X86_EAX, FIELD_OFFSET(KTRAP_FRAME, Eax) },
{ ROSSYM_X86_ECX, FIELD_OFFSET(KTRAP_FRAME, Ecx) },
{ ROSSYM_X86_EBX, FIELD_OFFSET(KTRAP_FRAME, Ebx) },
{ ROSSYM_X86_ESI, FIELD_OFFSET(KTRAP_FRAME, Esi) },
{ ROSSYM_X86_EDI, FIELD_OFFSET(KTRAP_FRAME, Edi) },
{ ROSSYM_X86_EBP, FIELD_OFFSET(KTRAP_FRAME, Ebp) },
{ ROSSYM_X86_ESP, FIELD_OFFSET(KTRAP_FRAME, HardwareEsp) }
};
if (Context)
{
DPRINT("Has Context %x (EBP %x)\n", Context, Context->Ebp);
LineInfo.Flags = ROSSYM_LINEINFO_HAS_REGISTERS;
for (i = 0; i < sizeof(regmap) / sizeof(regmap[0]); i++) {
memcpy
(&LineInfo.Registers.Registers[regmap[i].regname],
((PCHAR)Context)+regmap[i].ctx_offset,
sizeof(ULONG_PTR));
DPRINT("DWARF REG[%d] -> %x\n", regmap[i].regname, LineInfo.Registers.Registers[regmap[i].regname]);
}
}
if (!KdbpSymbolsInitialized || !KdbpSymFindModule(Address, NULL, -1, &LdrEntry)) if (!KdbpSymbolsInitialized || !KdbpSymFindModule(Address, NULL, -1, &LdrEntry))
return FALSE; return FALSE;
RelativeAddress = (ULONG_PTR)Address - (ULONG_PTR)LdrEntry->DllBase; RelativeAddress = (ULONG_PTR)Address - (ULONG_PTR)LdrEntry->DllBase;
Status = KdbSymGetAddressInformation Status = KdbSymGetAddressInformation(LdrEntry->PatchInformation,
(LdrEntry->PatchInformation, RelativeAddress,
RelativeAddress, &LineNumber,
&LineInfo); FileName,
FunctionName);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
DbgPrint("<%wZ:%x (%s:%d (%s))>", DbgPrint("<%wZ:%x (%s:%d (%s))>",
&LdrEntry->BaseDllName, RelativeAddress, LineInfo.FileName, LineInfo.LineNumber, LineInfo.FunctionName); &LdrEntry->BaseDllName, RelativeAddress, FileName, LineNumber, FunctionName);
if (Context) }
{ else
int i; {
char *comma = ""; DbgPrint("<%wZ:%x>", &LdrEntry->BaseDllName, RelativeAddress);
DbgPrint("(");
for (i = 0; i < LineInfo.NumParams; i++) {
DbgPrint
("%s%s=%llx",
comma,
LineInfo.Parameters[i].ValueName,
LineInfo.Parameters[i].Value);
comma = ",";
}
DbgPrint(")");
}
return TRUE;
} }
else if (Address < MmSystemRangeStart)
{
MemoryArea = MmLocateMemoryAreaByAddress(&PsGetCurrentProcess()->Vm, Address);
if (!MemoryArea || MemoryArea->Type != MEMORY_AREA_SECTION_VIEW)
{
goto end;
}
SectionObject = MemoryArea->Data.SectionData.Section;
if (!(SectionObject->AllocationAttributes & SEC_IMAGE)) goto end;
if (MemoryArea->StartingAddress != (PVOID)KdbpImageBase)
{
if (KdbpRosSymInfo)
{
RosSymDelete(KdbpRosSymInfo);
KdbpRosSymInfo = NULL;
KdbpImageBase = 0;
}
if ((FileContext = KdbpCaptureFileForSymbols(SectionObject->FileObject)))
{
if (RosSymCreateFromFile(FileContext, &KdbpRosSymInfo))
KdbpImageBase = (ULONG_PTR)MemoryArea->StartingAddress;
KdbpReleaseFileForSymbols(FileContext);
}
}
if (KdbpRosSymInfo)
{
RelativeAddress = (ULONG_PTR)Address - KdbpImageBase;
RosSymFreeInfo(&LineInfo);
Status = KdbSymGetAddressInformation
(KdbpRosSymInfo,
RelativeAddress,
&LineInfo);
if (NT_SUCCESS(Status))
{
DbgPrint
("<%wZ:%x (%s:%d (%s))>",
&SectionObject->FileObject->FileName,
RelativeAddress,
LineInfo.FileName,
LineInfo.LineNumber,
LineInfo.FunctionName);
if (Context)
{
int i;
char *comma = "";
DbgPrint("(");
for (i = 0; i < LineInfo.NumParams; i++) {
DbgPrint
("%s%s=%llx",
comma,
LineInfo.Parameters[i].ValueName,
LineInfo.Parameters[i].Value);
comma = ",";
}
DbgPrint(")");
}
return TRUE;
}
}
}
end:
DbgPrint("<%wZ:%x>", &LdrEntry->BaseDllName, RelativeAddress);
return TRUE; return TRUE;
} }
@@ -335,11 +174,13 @@ NTSTATUS
KdbSymGetAddressInformation( KdbSymGetAddressInformation(
IN PROSSYM_INFO RosSymInfo, IN PROSSYM_INFO RosSymInfo,
IN ULONG_PTR RelativeAddress, IN ULONG_PTR RelativeAddress,
IN PROSSYM_LINEINFO LineInfo) OUT PULONG LineNumber OPTIONAL,
OUT PCH FileName OPTIONAL,
OUT PCH FunctionName OPTIONAL)
{ {
if (!KdbpSymbolsInitialized || if (!KdbpSymbolsInitialized ||
!RosSymInfo || !RosSymInfo ||
!RosSymGetAddressInformation(RosSymInfo, RelativeAddress, LineInfo)) !RosSymGetAddressInformation(RosSymInfo, RelativeAddress, LineNumber, FileName, FunctionName))
{ {
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
@@ -367,6 +208,8 @@ KdbpSymFindCachedFile(
PLIST_ENTRY CurrentEntry; PLIST_ENTRY CurrentEntry;
KIRQL Irql; KIRQL Irql;
DPRINT("Looking for cached symbol file %wZ\n", FileName);
KeAcquireSpinLock(&SymbolFileListLock, &Irql); KeAcquireSpinLock(&SymbolFileListLock, &Irql);
CurrentEntry = SymbolFileListHead.Flink; CurrentEntry = SymbolFileListHead.Flink;
@@ -374,6 +217,7 @@ KdbpSymFindCachedFile(
{ {
Current = CONTAINING_RECORD(CurrentEntry, IMAGE_SYMBOL_INFO_CACHE, ListEntry); Current = CONTAINING_RECORD(CurrentEntry, IMAGE_SYMBOL_INFO_CACHE, ListEntry);
DPRINT("Current->FileName %wZ FileName %wZ\n", &Current->FileName, FileName);
if (RtlEqualUnicodeString(&Current->FileName, FileName, TRUE)) if (RtlEqualUnicodeString(&Current->FileName, FileName, TRUE))
{ {
Current->RefCount++; Current->RefCount++;
@@ -467,6 +311,7 @@ KdbpSymRemoveCachedFile(
} }
KeReleaseSpinLock(&SymbolFileListLock, Irql); KeReleaseSpinLock(&SymbolFileListLock, Irql);
DPRINT1("Warning: Removing unknown symbol file: RosSymInfo = %p\n", RosSymInfo);
} }
/*! \brief Loads a symbol file. /*! \brief Loads a symbol file.
@@ -485,8 +330,6 @@ KdbpSymLoadModuleSymbols(
HANDLE FileHandle; HANDLE FileHandle;
NTSTATUS Status; NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock; IO_STATUS_BLOCK IoStatusBlock;
PFILE_OBJECT FileObject;
PROSSYM_KM_OWN_CONTEXT FileContext;
/* Allow KDB to break on module load */ /* Allow KDB to break on module load */
KdbModuleLoaded(FileName); KdbModuleLoaded(FileName);
@@ -508,7 +351,7 @@ KdbpSymLoadModuleSymbols(
/* Open the file */ /* Open the file */
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
FileName, FileName,
OBJ_CASE_INSENSITIVE, 0,
NULL, NULL,
NULL); NULL);
@@ -528,34 +371,20 @@ KdbpSymLoadModuleSymbols(
DPRINT("Loading symbols from %wZ...\n", FileName); DPRINT("Loading symbols from %wZ...\n", FileName);
Status = ObReferenceObjectByHandle if (!RosSymCreateFromFile(&FileHandle, RosSymInfo))
(FileHandle,
FILE_READ_DATA|SYNCHRONIZE,
NULL,
KernelMode,
(PVOID*)&FileObject,
NULL);
if (!NT_SUCCESS(Status))
{ {
DPRINT("Could not get the file object\n"); DPRINT("Failed to load symbols from %wZ\n", FileName);
ZwClose(FileHandle);
return; return;
} }
if ((FileContext = KdbpCaptureFileForSymbols(FileObject)))
{
if (RosSymCreateFromFile(FileContext, RosSymInfo))
{
/* add file to cache */
KdbpSymAddCachedFile(FileName, *RosSymInfo);
DPRINT("Installed symbols: %wZ %p\n", FileName, *RosSymInfo);
}
KdbpReleaseFileForSymbols(FileContext);
}
ObDereferenceObject(FileObject);
ZwClose(FileHandle); ZwClose(FileHandle);
DPRINT("Symbols loaded.\n");
/* add file to cache */
KdbpSymAddCachedFile(FileName, *RosSymInfo);
DPRINT("Installed symbols: %wZ %p\n", FileName, *RosSymInfo);
} }
VOID VOID
@@ -582,6 +411,7 @@ KdbSymProcessSymbols(
LdrEntry->DllBase, LdrEntry->DllBase,
(PVOID)(LdrEntry->SizeOfImage + (ULONG_PTR)LdrEntry->DllBase), (PVOID)(LdrEntry->SizeOfImage + (ULONG_PTR)LdrEntry->DllBase),
LdrEntry->PatchInformation); LdrEntry->PatchInformation);
} }
VOID VOID
@@ -593,26 +423,6 @@ KdbDebugPrint(
/* Nothing here */ /* Nothing here */
} }
static PVOID KdbpSymAllocMem(ULONG_PTR size)
{
return ExAllocatePoolWithTag(NonPagedPool, size, 'RSYM');
}
static VOID KdbpSymFreeMem(PVOID Area)
{
return ExFreePool(Area);
}
static BOOLEAN KdbpSymReadMem(PVOID FileContext, PVOID TargetDebug, PVOID SourceMem, ULONG Size)
{
return NT_SUCCESS(KdbpSafeReadMemory(TargetDebug, SourceMem, Size));
}
static ROSSYM_CALLBACKS KdbpRosSymCallbacks = {
KdbpSymAllocMem, KdbpSymFreeMem,
KdbpReadSymFile, KdbpSeekSymFile,
KdbpSymReadMem
};
/*! \brief Initializes the KDB symbols implementation. /*! \brief Initializes the KDB symbols implementation.
* *
@@ -698,7 +508,7 @@ KdbInitialize(
p1 = p2; p1 = p2;
} }
RosSymInit(&KdbpRosSymCallbacks); RosSymInitKernelMode();
} }
else if (BootPhase == 3) else if (BootPhase == 3)
{ {

View File

@@ -266,7 +266,7 @@ KeRosDumpStackFrameArray(IN PULONG_PTR Frames,
if (p) if (p)
{ {
#ifdef KDBG #ifdef KDBG
if (!KdbSymPrintAddress((PVOID)Addr, NULL)) if (!KdbSymPrintAddress((PVOID)Addr))
#endif #endif
{ {
/* Print out the module name */ /* Print out the module name */