summaryrefslogtreecommitdiffstats
path: root/private/os2/client/vrdebug.h
blob: 2d9053352b8ea0cb31a8630ab638b1e718e322ac (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
/*++

Copyright (c) 1991  Microsoft Corporation

Module Name:

    vrdebug.h

Abstract:

    Contains defines for Vdm Redir Debugging info

Author:

    Richard L Firth (rfirth) 13-Feb-1992

Notes:

    Add new category for each new group of functions added for which external
    debug control is required

Revision History:

--*/

//
// COMPILE-time debugging options:
// definitions for debug flags. Each bit enables diagnostic printing/specific
// debugging of corresponding module. Also overridden at run-time in DBG
// version by having these flags in the VR= environment variable
//

#define DEBUG_MAILSLOT      0x00000001L // general Mailslots
#define DEBUG_NAMEPIPE      0x00000002L // general Named Pipe
#define DEBUG_NETAPI        0x00000004L // general NETAPI
#define DEBUG_NETBIOS       0x00000008L // general NETBIOS
#define DEBUG_DLC           0x00000010L // general DLC
#define DEBUG_DOS_CCB_IN    0x00000020L // input DOS CCBs & parameter tables
#define DEBUG_DOS_CCB_OUT   0x00000040L // output DOS CCBs & parameter tables
#define DEBUG_NT_CCB_IN     0x00000080L // input NT CCBs & parameter tables
#define DEBUG_NT_CCB_OUT    0x00000100L // output NT CCBs & parameter tables
#define DEBUG_DLC_BUFFERS   0x00000200L // DLC buffer pools
#define DEBUG_DLC_TX_DATA   0x00000400L // DLC transmit data
#define DEBUG_DLC_RX_DATA   0x00000800L // DLC received data
#define DEBUG_DLC_ASYNC     0x00001000L // DLC async call-backs
#define DEBUG_TRANSACT_TX   0x00002000L // Transaction send data buffer(s)
#define DEBUG_TRANSACT_RX   0x00004000L // Transaction receive data buffer(s)
#define DEBUG_DLC_ALLOC     0x00008000L // dump alloc/free calls in DLC
#define DEBUG_READ_COMPLETE 0x00010000L // dump CCB when READ completes
#define DEBUG_ASYNC_EVENT   0x00020000L // dump asynchronous event info
#define DEBUG_CMD_COMPLETE  0x00040000L // dump command complete event info
#define DEBUG_TX_COMPLETE   0x00080000L // dump transmit complete event info
#define DEBUG_RX_DATA       0x00100000L // dump data received event info
#define DEBUG_STATUS_CHANGE 0x00200000L // dump DLC status change event info
#define DEBUG_EVENT_QUEUE   0x00400000L // dump PutEvent, GetEvent and PeekEvent
#define DEBUG_DOUBLE_TICKS  0x00800000L // multiply timer tick counts by 2
#define DEBUG_DUMP_FREE_BUF 0x01000000L // dump buffer header on BUFFER.FREE
#define DEBUG_CRITSEC       0x02000000L // dump enter/leave critical section info
#define DEBUG_SUPERCRITICAL 0x04000000L // dump only stuff we absolutely need to know
#define DEBUG_CRITICAL      0x08000000L // where #ifdef CRITICAL_DEBUGGING used to be
#define DEBUG_TIME          0x10000000L // display relative time of events
#define DEBUG_TO_FILE       0x20000000L // dump output to file VRDEBUG.LOG
#define DEBUG_DLL           0x40000000L // general DLL stuff - init, terminate
#define DEBUG_BREAKPOINT    0x80000000L // break everywhere there's a DEBUG_BREAK

#define DEBUG_DOS_CCB       (DEBUG_DOS_CCB_IN | DEBUG_DOS_CCB_OUT)

#define VRDEBUG_FILE        "VRDEBUG.LOG"

#if DBG
#include <stdio.h>
//extern  DWORD   VrDebugFlags;
DWORD   VrDebugFlags;
extern  FILE*   hVrDebugLog;

extern  VOID    DbgOut(LPSTR, ...);

#define IF_DEBUG(type)      if (VrDebugFlags & DEBUG_##type)
#define DEBUG_BREAK()       IF_DEBUG(BREAKPOINT) { \
                                DbgPrint("BP %s.%d\n", __FILE__, __LINE__); \
                                DbgBreakPoint(); \
                            }
#define DBGPRINT            DbgOut
#define DPUT(s)             DBGPRINT(s)
#define DPUT1(s, a)         DBGPRINT(s, a)
#define DPUT2(s, a, b)      DBGPRINT(s, a, b)
#define DPUT3(s, a, b, c)   DBGPRINT(s, a, b, c)
#define DPUT4(s, a, b, c, d) DBGPRINT(s, a, b, c, d)
#define DPUT5(s, a, b, c, d, e) DBGPRINT(s, a, b, c, d, e)
#define CRITDUMP(x)         DbgPrint x
#define DUMPCCB             DumpCcb
#else
#define IF_DEBUG(type)      if (0)
#define DEBUG_BREAK()
#define DBGPRINT
#define DPUT(s)
#define DPUT1(s, a)
#define DPUT2(s, a, b)
#define DPUT3(s, a, b, c)
#define DPUT4(s, a, b, c, d)
#define DPUT5(s, a, b, c, d, e)
#define CRITDUMP(x)
#define DUMPCCB
#endif

//
// defaults
//

#define DEFAULT_STACK_DUMP  32

//
// numbers
//

#define NUMBER_OF_VR_GROUPS 5
#define NUMBER_OF_CPU_REGISTERS 14
#define MAX_ID_LEN  40
#define MAX_DESC_LEN    256

//
// environment strings - shortened since they all go through to dos & dos can
// only handle 1K of environment
//

#define ES_VRDEBUG  "VRDBG" // "__VRDEBUG"
#define ES_MAILSLOT "MS"    // "MAILSLOT"
#define ES_NAMEPIPE "NP"    // "NAMEPIPE"
#define ES_LANMAN   "LM"    // "LANMAN"
#define ES_NETBIOS  "NB"    // "NETBIOS"
#define ES_DLC      "DLC"   // "DLC"

//
// diagnostic controls - in same numerical order as TOKEN!!!
//

#define DC_BREAK        "BRK"   // "BREAK"
#define DC_DISPLAYNAME  "DN"    // "DISPLAYNAME"
#define DC_DLC          ES_DLC
#define DC_DUMPMEM      "DM"    // "DUMPMEM"
#define DC_DUMPREGS     "DR"    // "DUMPREGS"
#define DC_DUMPSTACK    "DK"    // "DUMPSTACK"
#define DC_DUMPSTRUCT   "DS"    // "DUMPSTRUCT"
#define DC_ERROR        "E"     // "ERROR"
#define DC_ERRORBREAK   "EB"    // "ERRORBREAK"
#define DC_INFO         "I"     // "INFO"
#define DC_LANMAN       ES_LANMAN
#define DC_MAILSLOT     ES_MAILSLOT
#define DC_NAMEPIPE     ES_NAMEPIPE
#define DC_NETBIOS      ES_NETBIOS
#define DC_PAUSEBREAK   "PB"    // "PAUSEBREAK"
#define DC_WARN         "W"     // "WARN"

//
// diagnostic categories (groups)
//

#define DG_ALL          -1L         // catch first enabled set
#define DG_NONE         0           // no category
#define DG_MAILSLOT     0x00000001L
#define DG_NAMEPIPE     0x00000002L
#define DG_LANMAN       0x00000004L
#define DG_NETBIOS      0x00000008L
#define DG_DLC          0x00000010L

//
// diagnostic index (in VrDiagnosticGroups array)
//

#define DI_MAILSLOT     0
#define DI_NAMEPIPE     1
#define DI_LANMAN       2
#define DI_NETBIOS      3
#define DI_DLC          4

//
// diagnostic control manifests
//

#define DM_INFORMATION  0x00010000L     // display all info, warning and error messages
#define DM_WARNING      0x00020000L     // display warning and error messages
#define DM_ERROR        0x00030000L     // display error messages only
#define DM_ERRORBREAK   0x00100000L     // DbgBreakPoint() on error
#define DM_PAUSEBREAK   0x00200000L     // DbgBreakPoint() on pause (wait for developer)
#define DM_DUMPREGS     0x00800000L     // dump x86 registers when routine entered
#define DM_DUMPREGSDBG  0x01000000L     // dump x86 registers when routine entered, debug style
#define DM_DUMPMEM      0x02000000L     // dump DOS memory when routine entered
#define DM_DUMPSTACK    0x04000000L     // dump DOS stack when routine entered
#define DM_DUMPSTRUCT   0x08000000L     // dump a structure when routine entered
#define DM_DISPLAYNAME  0x10000000L     // display the function name
#define DM_BREAK        0x80000000L     // break when routine entered

#define DM_DISPLAY_MASK 0x000f0000L

//
// enumerated types
//

////
//// GPREG - General Purpose REGisters
////
//
//typedef enum {
//    AX = 0,
//    BX,
//    CX,
//    DX,
//    SI,
//    DI,
//    BP,
//    SP
//} GPREG;
//
////
//// SEGREG - SEGment REGisters
////
//
//typedef enum {
//    CS = 8,
//    DS,
//    ES,
//    SS
//} SEGREG;
//
////
//// SPREG - Special Purpose REGisters
////
//
//typedef enum {
//    IP = 12,
//    FLAGS
//} SPREG;
//
//typedef union {
//    SEGREG  SegReg;
//    GPREG   GpReg;
//    SPREG   SpReg;
//} REGISTER;

typedef enum {
    AX = 0,
    BX = 1,
    CX = 2,
    DX = 3,
    SI = 4,
    DI = 5,
    BP = 6,
    SP = 7,
    CS = 8,
    DS = 9,
    ES = 10,
    SS = 11,
    IP = 12,
    FLAGS = 13
} REGISTER;

//
// REGVAL - keeps a 16-bit value or a register specification, depending on
// sense of IsRegister
//

typedef struct {
    BOOL    IsRegister;
    union {
        REGISTER Register;
        WORD    Value;
    } RegOrVal;
} REGVAL, *LPREGVAL;

//
// structures
//

//
// CONTROL - keeps correspondence between control keyword and control flag
//

typedef struct {
    char*   Keyword;
    DWORD   Flag;
} CONTROL;

//
// OPTION - keeps correspondence between diagnostic option and option type
//

typedef struct {
    char*   Keyword;
    DWORD   Flag;
} OPTION;

//
// REGDEF - defines a register - keeps correspondence between name and type
//

typedef struct {
    char    RegisterName[3];
    REGISTER Register;
} REGDEF, *LPREGDEF;

//
// GROUPDEF - keeps correspondence between group name and index in
// VrDiagnosticGroups array
//

typedef struct {
    char*   Name;
    DWORD   Index;
} GROUPDEF;

//
// MEMORY_INFO - for each each memory dump we keep a record of its type, length
// and starting address
//

typedef struct _MEMORY_INFO {
    struct _MEMORY_INFO* Next;
    REGVAL  Segment;
    REGVAL  Offset;
    REGVAL  DumpCount;
    BYTE    DumpType;
} MEMORY_INFO, *LPMEMORY_INFO;

//
// STRUCT_INFO - for each structure to be dumped we keep record of the segment
// and offset registers and the string which describes the structure to be
// dumped. The descriptor is similar to (but NOT THE SAME AS) the Rap
// descriptor stuff
//

typedef struct _STRUCT_INFO {
    struct _STRUCTINFO* Next;
    char    StructureDescriptor[MAX_DESC_LEN+1];
    REGVAL  Segment;
    REGVAL  Offset;
} STRUCT_INFO, *LPSTRUCT_INFO;

//
// DIAGNOSTIC_INFO - information common to GROUP_DIAGNOSTIC and FUNCTION_DIAGNOSTIC
//

typedef struct {
    DWORD       OnControl;
    DWORD       OffControl;
    MEMORY_INFO StackInfo;  // special case of MemoryInfo
    MEMORY_INFO MemoryInfo;
    STRUCT_INFO StructInfo;
} DIAGNOSTIC_INFO, *LPDIAGNOSTIC_INFO;

//
// GROUP_DIAGNOSTIC - because the groups are predefined, we don't keep any
// name information, or a list - just NUMBER_OF_VR_GROUPS elements in an
// array of GROUP_DIAGNOSTIC structures
//

typedef struct {
    char    GroupName[MAX_ID_LEN+1];
    DIAGNOSTIC_INFO Diagnostic;
} GROUP_DIAGNOSTIC, *LPGROUP_DIAGNOSTIC;

//
// FUNCTION_DIAGNOSTIC - if we want to diagnose a particular named function,
// then we generate one of these. We keep a (unsorted) list of these if a
// function description is parsed from the environment string(s)
//

typedef struct _FUNCTION_DIAGNOSTIC {
    struct _FUNCTION_DIAGNOSTIC* Next;
    char    FunctionName[MAX_ID_LEN+1];
    DIAGNOSTIC_INFO Diagnostic;
} FUNCTION_DIAGNOSTIC, *LPFUNCTION_DIAGNOSTIC;

//
// structure descriptor characters (general purpose data descriptors)
//

#define SD_BYTE     'B'     //  8-bits, displayed as hex (0a)
#define SD_WORD     'W'     // 16-bits, displayed as hex (0abc)
#define SD_DWORD    'D'     // 32-bits, displayed as hex (0abc1234)
#define SD_POINTER  'P'     // 32-bits, displayed as pointer (0abc:1234)
#define SD_ASCIZ    'A'     // asciz string, displayed as string "this is a string"
#define SD_ASCII    'a'     // asciz pointer, displayed as pointer, string 0abc:1234 "this is a string"
#define SD_CHAR     'C'     // ascii character, displayed as character 'c'
#define SD_NUM      'N'     //  8-bits, displayed as unsigned byte (0 to 255)
#define SD_INT      'I'     // 16-bits, displayed as unsigned word (0 to 65,535)
#define SD_LONG     'L'     // 32-bits, displayed as unsigned long (0 to 4,294,967,295)
#define SD_SIGNED   '-'     // convert I,L,N to signed
#define SD_DELIM    ':'     // name delimiter
#define SD_FIELDSEP ';'     // separates named fields
#define SD_NAMESEP  '/'     // separates structure name from fields

#define SD_CHARS    {SD_BYTE, \
                    SD_WORD, \
                    SD_DWORD, \
                    SD_POINTER, \
                    SD_ASCIZ, \
                    SD_ASCII,\
                    SD_CHAR, \
                    SD_NUM, \
                    SD_INT, \
                    SD_LONG, \
                    SD_SIGNED}

#define MD_CHARS    {SD_BYTE, SD_WORD, SD_DWORD, SD_POINTER}

//
// token stuff
//

//
// TOKEN - enumerated, alphabetically ordered tokens
//

typedef enum {
    TLEFTPAREN = -6,    // (
    TRIGHTPAREN = -5,   // )
    TREGISTER = -4,
    TNUMBER = -3,
    TEOS = -2,  // end of string
    TUNKNOWN = -1,  // unknown lexeme, assume routine name?

    //
    // tokens from here on down are also the index into DiagnosticTokens which
    // describe them
    //

    TBREAK = 0,
    TDISPLAYNAME,
    TDLC,
    TDUMPMEM,
    TDUMPREGS,
    TDUMPSTACK,
    TDUMPSTRUCT,
    TERROR,
    TERRORBREAK,
    TINFO,
    TLANMAN,
    TMAILSLOT,
    TNAMEPIPE,
    TNETBIOS,
    TPAUSEBREAK,
    TWARN
} TOKEN;

//
// TIB (Token Info Bucket) - Contains info describing token found. Only filled
// in when we find an identifier, number or a register
//

typedef struct {
    LPSTR   TokenStream;
    TOKEN   Token;
    union {
        REGVAL  RegVal;
        char    Id[MAX_DESC_LEN+1];
    } RegValOrId;
} TIB, *LPTIB;

//
// DEBUG_TOKEN - maps from lexeme to token
//

typedef struct {
    char*   TokenString;
    TOKEN   Token;
} DEBUG_TOKEN;

//
// what to expect when parsing strings
//

#define EXPECTING_NOTHING       0x00
#define EXPECTING_REGVAL        0x01
#define EXPECTING_MEMDESC       0x02
#define EXPECTING_STRUCTDESC    0x04
#define EXPECTING_LEFTPAREN     0x08
#define EXPECTING_RIGHTPAREN    0x10
#define EXPECTING_EOS           0x20
#define EXPECTING_NO_ARGS       0x40

//
// data (defined in vrdebug.c)
//

//
// VrDiagnosticGroups - an array of GROUP_DIAGNOSTIC structures
//

GROUP_DIAGNOSTIC VrDiagnosticGroups[NUMBER_OF_VR_GROUPS];

//
// FunctionList - linked list of FUNCTION_DIAGNOSTIC structures
//

LPFUNCTION_DIAGNOSTIC FunctionList;

//
// prototypes (in vrdebug.c)
//

VOID
VrDebugInit(
    VOID
    );

LPDIAGNOSTIC_INFO
VrDiagnosticEntryPoint(
    IN  LPSTR   FunctionName,
    IN  DWORD   FunctionCategory,
    OUT LPDIAGNOSTIC_INFO Info
    );

VOID
VrPauseBreak(
    LPDIAGNOSTIC_INFO Info
    );

VOID
VrErrorBreak(
    LPDIAGNOSTIC_INFO Info
    );

VOID
VrPrint(
    IN  DWORD   Level,
    IN  LPDIAGNOSTIC_INFO Context,
    IN  LPSTR   Format,
    IN  ...
    );

VOID
VrDumpRealMode16BitRegisters(
    IN  BOOL    DebugStyle
    );

VOID
VrDumpDosMemory(
    IN  BYTE    Type,
    IN  DWORD   Iterations,
    IN  WORD    Segment,
    IN  WORD    Offset
    );

VOID
VrDumpDosMemoryStructure(
    IN  LPSTR   Descriptor,
    IN  WORD    Segment,
    IN  WORD    Offset
    );

//
//VOID
//VrDumpDosStack(
//    IN  DWORD   Depth
//    )
//
///*++
//
//Routine Description:
//
//    Dumps <Depth> words from the Vdm stack, as addressed by getSS():getSP().
//    Uses VrDumpDosMemory to dump stack contents
//
//Arguments:
//
//    Depth   - number of 16-bit words to dump from DOS memory stack
//
//Return Value:
//
//    None.
//
//--*/
//

#define VrDumpDosStack(Depth)   VrDumpDosMemory('W', Depth, getSS(), getSP())

//
// macros used in routines to be diagnosed
//

#if DBG
#define DIAGNOSTIC_ENTRY    VrDiagnosticEntryPoint
#define DIAGNOSTIC_EXIT     VrDiagnosticExitPoint
#define BREAK_ON_PAUSE      VrPauseBreak
#define BREAK_ON_ERROR      VrErrorBreak
//#define INFORM(s, ...)      VrPrint(DM_INFORMATION, s, ...)
//#define WARN(s, ...)        VrPrint(DM_WARNING, s, ...)
//#define ERROR(s, ...)       VrPrint(DM_ERROR, s, ...)

#else

//
// macros used in routines to be diagnosed - don't expand to anything in non-debug
//

#define DIAGNOSTIC_ENTRY
#define DIAGNOSTIC_EXIT
#define BREAK_ON_PAUSE
#define BREAK_ON_ERROR
//#define INFORM
//#define WARN
//#define ERROR
#endif