#if defined(KERNEL) & defined(i386) #define KD386 1 #else #undef KD386 #endif #if defined(i386) #define MULTIMODE 1 #endif #if defined(i386) || defined(KERNEL) #define __unaligned #endif #ifdef KERNEL #ifdef NT_HOST #include #endif #else #include #endif #include #include #ifndef KERNEL #include #define NOMINMAX #include #include #endif #if MULTIMODE #define VM86(x) ((unsigned short)((x>>17)&1)) extern unsigned short fVm86; extern unsigned short f16pm; extern long vm86DefaultSeg; typedef struct _ADDR { UCHAR type; USHORT seg; ULONG off; ULONG flat; } NT_ADDR, *NT_PADDR; /* ADDR is CodeView, NT_ADDR is NTSD */ #define ADDR_UNKNOWN ((UCHAR)0x0001) #define ADDR_V86 ((UCHAR)0x0002) #define ADDR_16 ((UCHAR)0x0004) #define ADDR_32 ((UCHAR)0x0008) #define ADDR_1632 ((UCHAR)0x0010) #define FLAT_COMPUTED ((UCHAR)0x0020) #define INSTR_POINTER ((UCHAR)0x0040) #define NO_DEFAULT 0xFFFF #define fnotFlat(x) (!(((x)->type)&FLAT_COMPUTED)) #define fFlat(x) (((x)->type)&FLAT_COMPUTED) #define fInstrPtr(x) (((x)->type)&INSTR_POINTER) #define AddrEqu(x,y) ((x)->flat==(y)->flat) #define AddrLt(x,y) ((x)->flat<(y)->flat) #define AddrGt(x,y) ((x)->flat>(y)->flat) #define AddrDiff(x,y) ((x)->flat-(y)->flat) #define Flat(x) ((x)->flat) #define Off(x) ((x)->off) #define Type(x) ((x)->type) #define NotFlat(x) (x)->type&=~FLAT_COMPUTED #else typedef ULONG NT_ADDR, *NT_PADDR; #define ADDR_32 ((UCHAR)0x0008) #define ADDR_V86 ((UCHAR)0x0002) #define ADDR_16 ((UCHAR)0x0004) #define fnotFlat(x) (FALSE) #define fFlat(x) (TRUE) #define Flat(x) (*x) #define Off(x) (*x) #define Type(x) (ADDR_32) #define NotFlat(x) #define AddrAdd(x,y) (NT_PADDR)(((ULONG)x)|(((*x)+=y)&0L)) #define AddrSub(x,y) (NT_PADDR)(((ULONG)x)|(((*x)-=y)&0L)) #define AddrEqu(x,y) ((*x)==(*y)) #define AddrLt(x,y) ((*x)<(*y)) #define AddrGt(x,y) ((*x)>(*y)) #define AddrDiff(x,y) ((*x)-(*y)) #define ComputeNativeAddress(x) #define ComputeFlatAddress(x,y) #define FormAddress(paddr, seg, off) *paddr=off #define TempAddress(seg,off) &off #define VM86(x) (FALSE) #endif #ifdef KERNEL #undef const #define const const #ifdef NT_HOST #include #define NOMINMAX #include #include #else #undef cdecl #define cdecl cdecl void ExitProcess(ULONG); #define INCL_DOSERRORS #include #undef ASSERT #define ASSERT assert #endif #endif #include #include #define LocalAlloc(x,y) malloc(y) #define LocalFree(x) free(x) #undef NULL #include #undef min #undef max #include #include "ntsdtok.h" ///////////////////////////////////////////////////// #define SYMBOL_TYPE_SYMBOL ((UCHAR)0) #define SYMBOL_TYPE_EXPORT ((UCHAR)1) typedef struct _node { struct _node *pParent; struct _node *pLchild; struct _node *pRchild; } NODE, *PNODE; typedef struct _symcontext { PNODE pNodeRoot; PNODE pNodeMax; int (*pfnCompare)(PNODE, PNODE, PBOOLEAN); LONG nodeDisplacement; } SYMCONTEXT, *PSYMCONTEXT; // SYMBOL-specific macros and structures #define PNODE_TO_PSYMBOL(pnode, psymcontext) \ ((PSYMBOL) ((LONG) (pnode) - (psymcontext)->nodeDisplacement)) #define PSYMBOL_TO_PNODE(psymbol, psymcontext) \ ((PNODE) ((LONG) (psymbol) + (psymcontext)->nodeDisplacement)) #define NODE_SYMBOL_DISPLACEMENT(node) \ ((LONG) (&((PSYMBOL) 0)->node)) typedef struct _locals { #ifdef NT_SAPI // MUST be first for SAPI USHORT cvkind; // Storage Class (public, local etc) USHORT cvtype; // Storage type (CV style) #endif /* NT_SAPI */ struct _locals *next; USHORT type; ULONG value; ULONG aux; CHAR pszLocalName[1]; } LOCAL, *PLOCAL; typedef struct _symbol { #ifdef NT_SAPI // MUST be first for SAPI USHORT cvkind; // Storage Class (public, local etc) USHORT cvtype; // Storage type (CV style) #endif /* NT_SAPI */ NODE nodeOffset; NODE nodeString; ULONG offset; CHAR underscores; // signed value CHAR modIndex; // signed value UCHAR type; PLOCAL pLocal; //#ifdef PACKER // USHORT tableOffset; // struct _symbol *pSymbol; //#endif UCHAR string[3]; } SYMBOL, *PSYMBOL; typedef struct _field { #ifdef NT_SAPI // MUST be first for SAPI USHORT cvkind; // Storage Class (public, local etc) USHORT cvtype; // Storage type (CV style) #endif /* NT_SAPI */ struct _field *next; USHORT type; ULONG value; ULONG aux; CHAR pszFieldName[1]; } FIELD, *PFIELD; typedef struct _struct { #ifdef NT_SAPI // MUST be first for SAPI USHORT cvkind; // Storage Class (public, local etc) USHORT cvtype; // Storage type (CV style) #endif /* NT_SAPI */ NODE nodeOffset; NODE nodeString; ULONG offset; CHAR underscores; // signed value CHAR modIndex; // signed value UCHAR type; PFIELD pField; UCHAR string[3]; } STRUCT, *PSTRUCT; // SYMFILE-specific macros and structures #define PNODE_TO_PSYMFILE(pnode, psymcontext) \ ((PSYMFILE) ((LONG) (pnode) - (psymcontext)->nodeDisplacement)) #define PSYMFILE_TO_PNODE(psymfile, psymcontext) \ ((PNODE) ((LONG) (psymfile) + (psymcontext)->nodeDisplacement)) #define NODE_SYMFILE_DISPLACEMENT(node) \ ((LONG) (&((PSYMFILE) 0)->node)) typedef struct _lineno { ULONG memoryOffset; // memory offset (set from COFF) USHORT breakLineNumber; // line number in file for break (from COFF) USHORT topLineNumber; // line to start display (-1 if not set) ULONG topFileOffset; // offset in file of topLineNumber } LINENO, *PLINENO, **PPLINENO; typedef struct _symfile { NODE nodeOffset; NODE nodeString; PUCHAR pchPath; // path (no filename or extension) PUCHAR pchName; // filename only PUCHAR pchExtension; // extension only (with '.' if nonnull) USHORT cLineno; PLINENO pLineno; // first LINENO in list PLINENO pLinenoNext; // next LINENO to process in ordering list ULONG startOffset; ULONG endOffset; CHAR modIndex; // signed value ULONG nextFileOffset; // file offset for next LINENO scan USHORT nextLineNumber; // line number for next LINENO scan UCHAR nextScanState; // scanner state for next LINENO scan PPLINENO ppLinenoSrcLine; // pointer to PLINENO array for src ordering PPLINENO ppLinenoSrcNext; // next ptr to PLINENO array for src ordering SYMCONTEXT symcontextFunctionOffset; SYMCONTEXT symcontextFunctionString; SYMBOL maxSymbol; USHORT tableOffset; } SYMFILE, *PSYMFILE, **PPSYMFILE; // states of line scanning for comment considerations for .c files enum { stStart, // no comment stSlash, // '/' of possible comment start stSlStar, // '/*' in multiline comment stSlStStar, // '/*'...'*' of possible comment end stSlSlash, // '//' in single line comment stLine, // active char - no comment stLSlash, // active char - '/' of possible comment start stLSlStar, // active char - '/*' in multiline comment stLSlStStar, // active char - '/*'...'*' of possible comment end stLSlSlash // active char - '//' in single line comment }; ///////////////////////////////////////////// #ifdef MIPS #define GetAddrExpression(x) GetAddrExpr() typedef struct _FUNCTION_ENTRY { ULONG StartingAddress; ULONG EndingAddress; ULONG EndOfPrologue; } FUNCTION_ENTRY, *PFUNCTION_ENTRY; #endif typedef struct _IMAGE_INFO { struct _IMAGE_INFO *pImageNext; #ifndef KERNEL HANDLE hFile; DWORD dwDebugInfoFileOffset; DWORD nDebugInfoSize; #endif LPVOID lpBaseOfImage; PUCHAR pszName; ULONG offsetLow; ULONG offsetHigh; #ifdef MIPS ULONG LowAddress; ULONG HighAddress; ULONG NumberOfFunctions; PFUNCTION_ENTRY FunctionTable; #endif #ifdef NT_SAPI unsigned short aFile; int hQCFile; BOOLEAN QCOpened; BOOLEAN IgnoreSymbols; LPVOID pGSN; unsigned long * pRVA; int ObjectCount; unsigned short TypeCount; PUCHAR * rgTypeInfo; #endif UCHAR index; BOOLEAN fSymbolsLoaded; } IMAGE_INFO, *PIMAGE_INFO; #ifndef KERNEL typedef struct _THREAD_INFO { struct _THREAD_INFO *pThreadNext; DWORD dwThreadId; HANDLE hThread; LPTHREAD_START_ROUTINE lpStartAddress; BOOLEAN fFrozen; BOOLEAN fSuspend; BOOLEAN fTerminating; #ifdef i386 ULONG DReg[4]; ULONG DReg7; UCHAR cntDReg; #endif UCHAR index; } THREAD_INFO, *PTHREAD_INFO; #endif typedef struct _PROCESS_INFO { struct _PROCESS_INFO *pProcessNext; PIMAGE_INFO pImageHead; #ifdef NT_SAPI ULONG hpid; #endif /* NT_SAPI */ #ifndef KERNEL DWORD dwProcessId; HANDLE hProcess; PTHREAD_INFO pThreadHead; PTHREAD_INFO pThreadEvent; PTHREAD_INFO pThreadCurrent; BOOLEAN fStopOnBreakPoint; #endif SYMCONTEXT symcontextSymbolOffset; SYMCONTEXT symcontextSymbolString; SYMCONTEXT symcontextSymfileOffset; SYMCONTEXT symcontextSymfileString; SYMCONTEXT symcontextStructOffset; SYMCONTEXT symcontextStructString; UCHAR index; } PROCESS_INFO, *PPROCESS_INFO; extern PPROCESS_INFO pProcessHead; extern PPROCESS_INFO pProcessEvent; extern PPROCESS_INFO pProcessCurrent; //////////////////////////////////////////////////////// // structure used to define register flag fields struct Reg { char *psz; ULONG value; }; struct SubReg { ULONG regindex; ULONG shift; ULONG mask; }; ///////////////////////////////////// // externals used among modules ///////////////////////////////////// // defined in ntcmd.c extern UCHAR *pchCommand; extern UCHAR cmdState; extern UCHAR chSymbolSuffix; extern CONTEXT RegisterContext; extern ULONG baseDefault; extern NtsdPrompt(char *, char *, int); #ifndef KERNEL extern void ProcessStateChange(BOOLEAN, BOOLEAN); extern BOOLEAN fDebugOutput; extern BOOLEAN fVerboseOutput; #else extern void ProcessStateChange(ULONG, PDBGKD_CONTROL_REPORT); #endif #if MULTIMODE extern void ComputeFlatAddress(NT_PADDR, PDESCRIPTOR_TABLE_ENTRY); extern void ComputeNativeAddress(NT_PADDR); extern void FormAddress(NT_PADDR, ULONG, ULONG); extern NT_PADDR AddrAdd(NT_PADDR, ULONG); extern NT_PADDR AddrSub(NT_PADDR, ULONG); #endif extern void InitNtCmd(void); extern void error(ULONG); extern BOOLEAN GetMemByte(NT_PADDR, PUCHAR); extern BOOLEAN GetMemWord(NT_PADDR, PUSHORT); extern BOOLEAN GetMemDword(NT_PADDR, PULONG); extern ULONG GetMemString(NT_PADDR, PUCHAR, ULONG); extern BOOLEAN SetMemDword(NT_PADDR, ULONG); extern ULONG SetMemString(NT_PADDR, PUCHAR, ULONG); extern void dprintAddr(NT_PADDR); extern void cdecl dprintf(char *, ...); // defined in ntreg.c extern ULONG cbBrkptLength; extern ULONG trapInstr; extern ULONG ContextType; extern struct SubReg subregname[]; #if defined(KERNEL) & defined(i386) extern BOOLEAN fTerseReg; #endif extern ULONG GetRegFlagValue(ULONG); extern ULONG GetRegValue(ULONG); extern NT_PADDR GetRegPCValue(void); extern NT_PADDR GetRegFPValue(void); extern void SetRegFlagValue(ULONG, ULONG); extern void SetRegValue(ULONG, ULONG); extern void SetRegPCValue(NT_PADDR); extern ULONG GetRegName(void); extern ULONG GetRegString(PUCHAR); extern void OutputAllRegs(void); extern void OutputOneReg(ULONG); extern void OutputHelp(void); extern void ClearTraceFlag(void); extern void SetTraceFlag(void); #ifdef i386 extern void fnStackTrace(ULONG, NT_PADDR, BOOLEAN); #else extern void fnStackTrace(ULONG,BOOLEAN); #endif extern PUCHAR RegNameFromIndex(ULONG); #ifdef MIPS extern PFUNCTION_ENTRY LookupFunctionEntry(ULONG); #endif #ifdef KERNEL extern ULONG ReadCachedMemory(NT_PADDR, PUCHAR, ULONG); extern void WriteCachedMemory(NT_PADDR, PUCHAR, ULONG); #endif // defined in ntsym.c extern BOOLEAN fSourceOnly; extern BOOLEAN fSourceMixed; extern void GetSymbol(ULONG, PUCHAR, PULONG); extern void LoadSymbols(PIMAGE_INFO); extern BOOLEAN GetOffsetFromSym(PUCHAR, PULONG, CHAR); extern PLINENO GetLinenoFromFilename(PUCHAR, PPSYMFILE, USHORT, CHAR); extern PLINENO GetCurrentLineno(PPSYMFILE); extern PLINENO GetLinenoFromOffset(PPSYMFILE, ULONG); extern void GetCurrentMemoryOffsets(PULONG, PULONG); extern BOOLEAN OutputLines(PSYMFILE, PLINENO, USHORT, USHORT); extern void UpdateLineno(PSYMFILE, PLINENO); extern void GetLinenoString(PUCHAR, ULONG); extern BOOLEAN OutputSourceFromOffset(ULONG, BOOLEAN); extern PLINENO GetLastLineno(PPSYMFILE, PUSHORT); extern PSYMBOL GetFunctionFromOffset(PPSYMFILE, ULONG ); extern PIMAGE_INFO GetModuleIndex(PUCHAR); extern PIMAGE_INFO GetCurrentModuleIndex(void); extern void parseExamine(void); // defined in ntexpr.c #ifndef MIPS extern NT_PADDR GetAddrExpression(ULONG); #else extern NT_PADDR GetAddrExpr(void); #endif extern ULONG GetExpression(void); extern UCHAR PeekChar(void); extern void fnListNear(ULONG); extern USHORT GetSrcExpression(PPSYMFILE, PPLINENO); // defined in ntsdk.c (kernel) #ifdef KERNEL extern USHORT CurrentProcessor; #endif // defined in ntsd.c (non-kernel) #ifndef KERNEL extern void BrkptInit(void); extern NTSTATUS DbgKdWriteBreakPoint(PVOID, PULONG); extern NTSTATUS DbgKdRestoreBreakPoint(ULONG); extern NTSTATUS DbgKdReadVirtualMemory(PVOID, PVOID, ULONG, PULONG); extern NTSTATUS DbgKdWriteVirtualMemory(PVOID, PVOID, ULONG, PULONG); #endif // defined in ntdis.c extern BOOLEAN disasm(NT_PADDR, PUCHAR, BOOLEAN); extern BOOLEAN fDelayInstruction(void); #ifdef MIPS extern ULONG GetNextOffset(BOOLEAN); #else extern void GetNextOffset(NT_PADDR, BOOLEAN); #endif // defined in ntasm.c extern void assem(NT_PADDR, PUCHAR); // defined in nt3000.c (MIPS only) #if defined(MIPS) && defined(KERNEL) extern void fnDumpTb3000(ULONG, ULONG); #endif // defined in nt4000.c (MIPS only) #if defined(MIPS) && defined(KERNEL) extern void fnDumpTb4000(ULONG, ULONG); #endif