home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / dumptool.zip / DTRACE.ZIP / dtrace.doc next >
Text File  |  1998-09-06  |  83KB  |  2,356 lines

  1. DTRACE: Low level Dynamic Trace Utility
  2. Author: Richard Moore
  3. Version: 4.3
  4. Date: 06 Sep 1998
  5.  
  6. Abstract: Exploits the DosDynamicTrace facility at a low-level. This may be
  7. used to implement ad-hoc tracing in DLLs, Device Drivers, File System Drivers
  8. and the OS2 Kernel. EXE files are also included. Dynamic Trace may be used
  9. for diagnostic purposes and performance monitoring.
  10.  
  11. DTRACE 3.4a is distributed with Warp 3 fix pack 29 and Warp 4 fix pack 2.
  12.  
  13. DTRACE 4.2 is distributed with feature F180062 for Warp version 3.
  14.  
  15. See also:
  16.  
  17. TRUTILS.ZIP for related trace utilities.
  18. DYNDD.ZIP for a sample Dynamic Trace Device Driver Kernel Exit.
  19. SAMPLRPN.ZIP for sample DTRACE command files that selectively intercept 
  20. traps and exceptions.
  21.  
  22. If you would like to know more about using the OS2 Trace Facility sign up
  23. for the WARP Debug Series - Class 3, developed by the Solution
  24. Developer Operation of IBM.  You'll find this on MSE in the USA.  It's
  25. also known as P1097 or PS97 in the Education Catalogue.
  26.  
  27. *****************************************************************************
  28. *                                                                           *
  29. *                 R E A D    T H I S    W A R N I N G                       *
  30. *                                                                           *
  31. *WARNING: this is a low level tool that can be used to alter system memory. *
  32. *Incorrect usage of this tool could cause the system damage and unpredictable*
  33. *results, which in an extreme case could cause the loss of data.            *
  34. *                                                                           *
  35. *Dynamic Trace cannot be used at interrupt time or in certain critical      *
  36. *parts of the OS2 Kernel (e.g. Dynamic Trace itself).                       *
  37. *If APAR fix JR09673 is applied to OS2KRNL then dynamic tracing may be made *
  38. *at interrupt time - this should be available in Warp 3 fix pack 30 and     *
  39. *Warp 4 fix pack 2.                                                         *
  40. *                                                                           *
  41. *Major codes should be restricted to the range 245-255 so as not to conflict*
  42. *with pre-definied system tracepoints.                                      *
  43. *                                                                           *
  44. *****************************************************************************
  45.  
  46.  
  47. Feedback may be given directly to the author at VM node:
  48. MOORERJ/CROVM3 or INTERNET address: richardj_moorer@uk.ibm.com
  49.  
  50.  
  51. Introduction:
  52. ------------
  53.  
  54. Dynamic trace is a facility available within the OS/2 kernel. 
  55. Tracepoints are implemented by modifying dynamically code of modules
  56. loaded in memory. This is in contrast to Static tracepoints 
  57. which are implemented when applications call the DosSysTrace API. 
  58.  
  59. Dynamic tracepoints are implemented by replacing machine instructions
  60. at specified points within a module by INT3 instructions.  This is
  61. done by the DosDynamicTrace API.  When the INT3 instruction executes,
  62. control is passed to the system TRAP3 exception handler, which in turn
  63. passes control to Dynamic Trace if the TRAP3 was due to a known
  64. tracepoint.  Dynamic Trace interprets instructions, which are in
  65. Reverse Polish Notation, that were passed to it when the trace point
  66. was defined.  These instructions allow data to be logged in the system
  67. trace buffer and local variables associated with the tracepoint to be
  68. manipulated.  After the RPN instruction stream is complete, the
  69. original instruction is single-stepped then normal execution resumed.
  70.  
  71. The overhead of dynamic trace is a few milliseconds per tracepoint. 
  72. Normally this is small enough not to make a noticeable difference to 
  73. system performance.
  74.  
  75.  
  76. User Guide:
  77. ----------
  78.  
  79. Command Syntax:
  80.  
  81.        DTRACE APPLY trpgm_file [/h=hmte | /n=name] [/m=major] [/i=id] [/e|/c] [/q] [/d]
  82.        DTRACE BUILDTDF trpgm_file [tdf_file] [/m=major] [/n=name] [/i=id] [/q] [/d]
  83.        DTRACE REMOVE [trpgm_file | /h=hmte | /n=name] [/c] [/q] [/d]
  84.        DTRACE CLEARALL [/q] [/d]
  85.        DTRACE QUERY [/h=hmte | /n=name] [/a] [/i=id] [/x[=n]] [/q] [/d]
  86.        DTRACE GETVARS [/h=hmte | /n=name] [/i=id] [/v=n:m] [/z] [/r] [/q] [/d]
  87.  
  88. Numeric values may be specified in hexadecimal or decimal. Hexadecimal
  89. values are signified with either the (C -style) 0x prefix, e.g. 0x2f8; 
  90. or the (assembler-style) h suffix, e.g. 2f8h
  91.  
  92. Optional command line parameters (/i, /m,  /h and /n) set defaults which
  93. override the default settings in the header of the trace program file. 
  94. Overrides for specific tracepoints take precedence over the command line and
  95. the header in the trace program file.
  96.  
  97. hmte: module handle (any module with an MTE). May be specified also in
  98.       the trace program file. 
  99.  
  100. name: module name. 
  101.       name may specify a simple name, a name and extension or a
  102.       fully qualified name with path information.
  103.  
  104.       If a fully qualified name is specified then it is used without
  105.       modification to determine the module handle. If this is unsuccessful
  106.       the no attempt is made to search for the module.
  107.  
  108.       For partially specified names DTRACE attempts to work out the
  109.       module handle according to the following assumptions:
  110.  
  111.          if a simple name without extension is specified then .DLL is 
  112.          assumed. If the DLL is not loaded then LIBPATH is used to search
  113.          and load the DLL.
  114.  
  115.          All other module types must specify at the very least
  116.          name and extension. If the module is not already loaded then
  117.          PATH is searched for determine the fully qualified module name
  118.          and hence the module handle.
  119.  
  120.  
  121.       The following types of module may be traced:
  122.  
  123.          Physical Device Drivers 
  124.          Virtual Device Drivers 
  125.          File System Drivers 
  126.          Printer Drivers 
  127.          Queue Drivers 
  128.          Custom DLLs (DLLs with non-DLL extension names)
  129.          EXE modules
  130.          Custom EXE modules (EXEs with a non_EXE extension or no extension)
  131.          Base device drivers.
  132.          Any of the above in non-PATH or LIBPATH directories.
  133.  
  134.       For BASEDEVs the system records the path name as 
  135.       being the root directory of the boot drive regardless of which
  136.       directory the driver was loaded from. DTRACE will attempt to 
  137.       derive the module handle of a BASEDEV automatically if only 
  138.       name and extension are supplied.
  139.  
  140.       Build BUILDTDF may be used for non-DLL modules however under
  141.       OS/2 3.0+ JR09872 is required for the TRACE command to process 
  142.       TDFs for non-DLL modules.
  143.  
  144. major: The default major code. May also be specified in the trace program
  145.        file. Major codes specified with specific tracepoints in the trace
  146.        program file override any other specification.
  147.        With feature F180062 major codes may range from 1 through 0xffff,
  148.        otherwise the kernel will restrict them to the range 1 - 255.
  149.  
  150. id: Superset grouping of tracepoints. May include more than one major
  151.     code. Defaults to 0 when defining tracepoints. NB dynamic trace 
  152.     generated by TRCUST uses id=0, unless overridden by TDFID=. Id may 
  153.     be specified also in the trace program file. 
  154.  
  155.     Id is intended for use with the  QUERY and GETVARS functions. 
  156.     These functions will assume all non-zero ids are to be processed if 
  157.     id is not specified.
  158.  
  159. n:m Variables n to m. Dynamic Trace variables are referred to by index number
  160.     starting with 0. Number of variables defined is determined by the
  161.     vars= statement of the trace program file.
  162.  
  163. z:  Zero variables. 
  164.  
  165. r:  Read variables. 
  166.  
  167. q:  Suppress copyright and incidental informational messages.
  168.  
  169. d:  Debugging switch. This is provided for diagnosing problems with DTRACE.
  170.     It should only be used at the request of Service personnel.
  171.     Note: DTRACE also has associated DTRACE.TDF and TRC0063.TFF files which
  172.     permit internal tracing of DTRACE itself by means of TRACE ON DTRACE.EXE
  173.  
  174. c:  Will replace the tracepoints for the module specified it a DTO already exists
  175.     in the system.
  176.  
  177. e:  Will merge (APPLY) or de-merge tracepoints for the module if a DTO already exists.
  178.     Merge and De-merge are done by matching tracepoint locations.
  179.     In the case of merge, the RPN program, major and minor codes are updated for
  180.     each tracepoint. The merging ID overrides the previous ID. LOGMAX and VARS are
  181.     set to the maximum of the existing and new trace definition.
  182.  
  183.     in the case of de-merge, only those tracepoints that existed previously will be
  184.     de-merged. Any others in the de-merging definition will be ignored. LOGMAX and
  185.     VARS are maximised as for merge. The new ID overrides the previous ID.
  186.  
  187. a:  Requests dynamic trace definitions for all modules be queried. When /a is not
  188.     specified then only those modules that are loaded and have tracepoints in place
  189.     will be listed.
  190.  
  191. x:  Requests extended query. /X or /X=1 will cause all tracepoints for the given
  192.     module selection to be listed. For each tracepoint the following information is
  193.     displayed:
  194.  
  195.       The tracepoint number with in the module.
  196.  
  197.       The major and minor codes for the tracepoint.
  198.  
  199.       The object and offset of the tracepoint location.
  200.  
  201.       The opcode atf the tracepoint location.
  202.  
  203.       The tracepoint status. No status implies the tracepoint has been removed.
  204.       Other status shows degrees of initialisation of the tracepoint. Under normal
  205.       circumstances this shows a status of "fixed-up, compiled, valid, set". Other settings
  206.       are transient or rare states.
  207.  
  208.       Each state has the following meaning:
  209.  
  210.       fixedup   The tracepoint location has been resolved to a linear address
  211.       compiled  The PRN program has been validated
  212.       valid     The tracepoint is valid for the module
  213.       set       The tracepoint is installed (INT 3 set in code).
  214.       nocode    The code for this tracepoint is free
  215.       removed   The tracepoint has been removed from the code 
  216.       purged    The tracepoint has been purged from a debug alias
  217.       calldbg   The tracepoint should be handled as an exception
  218.  
  219.       /x=2 will list in addition to the above, the local variable values for each
  220.       trace object.
  221.  
  222.  
  223. trpgm_file: Trace program file. If a simple name is specified then
  224.     an extension of .RPN is assumed.
  225.     See below. for the file description.
  226.  
  227. tdf_fiie: The generated Trace Definition File name. See below.
  228.  
  229. Options that may also be specified in the trace program file are
  230. overridden when specified on the command line.
  231.  
  232.  
  233. DTRACE functions:
  234.  
  235. APPLY:    Insert dynamic tracepoints, specified by the trace program 
  236.           file for a module specified by name or hmte. A full 
  237.           description of the trace program file is given below.
  238.  
  239. BUILDTDF: Build a Trace Definition File (TDF) from the definitions 
  240.           supplied in the trace program file. The OS/2 TRACE command 
  241.           may be used subsequently to apply or removed all or selected 
  242.           tracepoints defined in the TDF.
  243.  
  244.           TFD files must be stored in the current directory, DPATH or 
  245.           in \OS2\SYSTEM\TRACE. 
  246.  
  247.           BUILDTDF permits group and type classifications to be 
  248.           specified with each tracepoint. These may be used by the
  249.           OS/2 TRACE command to select subsets of tracepoints to be 
  250.           activated. The TRACE command also permits specific minor 
  251.           codes, or ranges of minor codes to be specified.
  252.  
  253.           The syntax for the TRACE command using a TDF file is as 
  254.           follows:
  255.  
  256.                  TRACE ON|OFF tdf_file
  257.  
  258.             or   TRACE ON tdf_file(minor spec)
  259.  
  260.             or   TRACE ON tdf_file(group spec)
  261.  
  262.             or   TRACE ON tdf_file(type spec)
  263.  
  264.           where:
  265.             
  266.                  tdf_file is the file name, excluding path and 
  267.                  extension of the tdf_file.
  268.  
  269.                  minor spec is a combination of minor code or
  270.                  ranges of minor codes separated by commas.
  271.                  In the following example KERNEL minor codes 
  272.                  (decimal) 1, 2 through 10 and 401 are traced.
  273.  
  274.                     TRACE ON KERNEL(1,2-10,401)
  275.                    
  276.                  group spec is a combination of groups separated by 
  277.                  commas. Each group may further specify one or more 
  278.                  types.
  279.                  In the following example KERNEL group FS (with 
  280.                  all types) and TK with types PRE and POST is traced.
  281.  
  282.                     TRACE ON KERNEL(FS,TK:PRE+POST)
  283.  
  284.                  type spec is a combination of types separated by 
  285.                  commas. In the following example all KERNEL PRE and
  286.                  POST type tracepoints are traced.
  287.  
  288.                     TRACE ON KERNEL(PRE,POST)
  289.  
  290.           Notes: 
  291.  
  292.           Due to a limitation with the TRACE command, BUILDTDF 
  293.           can only be used to create TDFs for DLLs and OS2KRNL unless
  294.           JR09872 is installed.
  295.  
  296.           If the TRACE command fails to find the TDF in the DPATH it
  297.           will look in \OS2\SYSTEM\TRACE\SYSTEM.TDF before looking
  298.           finally for \OS2\SYSTEM\TRACE\tdf_file. The becomes an 
  299.           important consideration when one of the pre-existing system 
  300.           trace definitions is modified or replaced.
  301.  
  302.           The TRACE command fails to find OS2KRNL.TDF in 
  303.           in OS2\SYSTEM\TRACE if executed from a command line where
  304.           the current directory is other than on the boot drive.
  305.           APAR PJ23293 addresses this problem.
  306.  
  307.           See the accompanying TRCTOOLS documentation for further 
  308.           information of modifying and replacing system trace 
  309.           definitions.
  310.           
  311.  
  312. REMOVE:   Remove dynamic tracepoints for a module specified by name or
  313.           handle.
  314.  
  315. CLEARALL: Remove all dynamic tracepoints for all modules.
  316.  
  317. QUERY:    Query by id or hmte all traced modules, their ids and number 
  318.           of Dynamic Trace variables.
  319.  
  320.           Unless /i /n or /h is specified all zero and non-zero Ids 
  321.           are queried for active modules only. To query inactive modules
  322.           in addition, /a must be specified.
  323.  
  324.           Note: Standard system dynamic trace definitions and user 
  325.           definitions that are defined using TRCUST are always defined 
  326.           with id=0.
  327.  
  328. GETVARS:  Retrieve and/or set to zero the Dynamic Trace variables for 
  329.           a given id or module. 
  330.  
  331.           By default all variables of all non-zero ids are retrieved.
  332.  
  333.           Variables are displayed as a list in hexadecimal and decimal
  334.           formats.
  335.  
  336.       
  337. Format of the Trace Program File:
  338.  
  339. This file specifies one or more tracepoints for a module.  Each
  340. tracepoint may have an associated program that species to DynamicTrace
  341. what variables to manipulate and what data to log in the system trace
  342. buffer when the tracepoint fires.
  343.  
  344. Comments may appear after the instructions or on whole lines. They
  345. are prefixed with a semi-colon.
  346.  
  347. Blank, tab, bell and basckspace characters are ignored by DTRACE.
  348.  
  349. LF, CR, VT delimit a line.
  350.  
  351. Null lines are ignored.
  352.  
  353. The trace program consists of a header followed by one or more tracepoint
  354. definitions. Each tracepoint definition has a header followed by an 
  355. optional program specified as a sequence of Reverse Polish Notation
  356. instructions.  The RPN commands use a circular stack of 16 double-word
  357. elements as a work space.  The top element of the stack is the only
  358. immediately accessible element.  As each element is accessed the top
  359. of stack (TOS) pointer is moved to point to the preceding stack 
  360. element - this is referred to as a POP operation even though the 
  361. popped stack element is not actually removed from the stack.  Thus an
  362. RPN command that takes two stack parameters pops the two topmost
  363. elements from the stack.  Whenever data on the stack is referenced it
  364. is done so in integral numbers of elements.  Thus pushing or popping a
  365. word will move the stack pointer as if a double-word had been pushed
  366. or popped. Word and byte length data is always padded to a double-word 
  367. when pushed on to the stack.
  368.  
  369. The trace program may be used for three purposes (which may be 
  370. combined):
  371.  
  372. 1) To cause one or more items of data to be logged in the system
  373.    trace buffer.
  374.  
  375. 2) To update local variables which are associated with a particular 
  376.    module being traced.
  377.  
  378. 3) To detect a specific condition (value of a register, value in 
  379.    memory or code path) and force a System Dump when that condition 
  380.    occurs. 
  381.  
  382.    NB: this function is not available in all releases of OS/2.
  383.  
  384. The entire set of trace definitions and local variables for a 
  385. particular module is referred to as a Dynamic Trace Object (DTO).
  386.  
  387. One DTO may exist per module. DosDynamicTrace will not merge an 
  388. existing DTO with additional definitions for the same module.
  389.  
  390. DTOs for several modules may be grouped under the same id - see
  391. the /i parameter above and the id= parameter below.
  392.  
  393.  
  394.  
  395. RPN command syntax rules are as follows:
  396.  
  397. [label:] operator [operand1 [,operand2 [, ..... ]]] [; comment]
  398. [;comment]
  399.  
  400. Where:
  401.  
  402. label 
  403.       is an optional string of 1 - 255 characters, excluding ':',
  404.       initiated with a non-numeric character and delimited by a ':'.
  405.       A label must always precede a command, but the command my be
  406.       coded on the following line. Labels are for use by the jump
  407.       instructions as an alternative to coding an explicit numeric 
  408.       value. Backward jumping is not permitted.
  409.  
  410. operator
  411.       is one of the valid RPN commands listed below.
  412.  
  413. operand1,...
  414.       are operands as defined by each RPN command.
  415.  
  416. A comment is initiated by a ';' and may follow on the same line as a
  417. command or on a new line.
  418.  
  419. RPN commands,labels and operators are case insensitive.
  420.  
  421. Imbedded blanks are ignored.
  422.  
  423.  
  424.  
  425.  
  426. Data logged by DTRACE may be formatted using TRACEFMT. The format will be
  427. in hexadecimal bytes unless a custom trace format file has been generated
  428. using the TRCUST utility. When using TRCUST, specify the TP parameter as
  429. @STATIC. The prefixes %P and %R may be used. See the OS/2 Debugging 
  430. Handbook (SBOF-8617), the OS2PDP PACKAGE or the DDK for TRCUST.
  431.  
  432. The TRSPOOL utility may be used to capture trace data on disk files.
  433. See TRSPOOL PACKAGE on OS2TOOLS or in the OS/2 Debugging Handbook 
  434. (SBOF-8617).
  435.  
  436. Refer to the OS/2 Debugging Handbook, Volume 1 and 3 for further information
  437. on the system trace utility.
  438.  
  439.  
  440.  
  441. File header:
  442. ------------
  443.  
  444. Zero or more of the following may be specified, in any order:
  445.  
  446. vars=     Number of Dynamic Trace variables to be defined 
  447.           (initialised to zero).
  448. major=    Major code
  449. hmte=     Module handle
  450. id=       DTO grouping id - not to be confused with typedef or 
  451.           groupdef ids. This is a gouping of Dynamic Trace Objects. 
  452.           The default DTO id is 0. Id is used with GETVARS and QUERY
  453.           functions.
  454. logmax=   Maximum data to be logged in the trace buffer (default 512
  455.           bytes).
  456.  
  457.           With feature f180062 the maximum value for logmax is 
  458.           4099, prior to that the maximum was 512. Note: TRCUST 
  459.           allows a maximum of 4096 to be specified by MAXDATALENGTH or
  460.           the length parameter of memory logging parameters. Internally
  461.           the maximum log size will be increased by 3 to allow for the
  462.           3 byte memory logging prefix. DTRACE on the other hand operates
  463.           at a lower level and the value specified by logmax is presented
  464.           to the system unedited.
  465. name=     Module name. See name specification above.
  466. typedef=  Defines a type keyword. This is used only by the BUILDTDF
  467.           function. The definition is specified as:
  468.  
  469.                typedef=keyword,id.
  470.  
  471.            Keyword is a string, which is used by type statements, see
  472.            below. 
  473.  
  474.            id is a value equal to a power of two in the range 2**1 to
  475.            2**31.
  476.  
  477.            Multiple typedef statements my be specified.
  478.  
  479. groupdef= Defines a group keyword. This is used only by the BUILDTDF
  480.           function. The definition is specified as:
  481.  
  482.                groupdef=keyword,id.
  483.  
  484.            Keyword is a string, which is used by group statements, see
  485.            below. 
  486.  
  487.            id is a value in the range 0x to 0xffffffff.
  488.  
  489.            Multiple groupdef statements my be specified.
  490.  
  491.  
  492. Major code and hmte are required but may be specified or overridden by
  493. the command line parameters. 
  494.  
  495. If name and hmte are specified then the first parameter encountered 
  496. takes precedence.
  497.  
  498. id defaults to zero.
  499.  
  500. vars defaults to zero.
  501.  
  502. logmax defaults to 512.
  503.  
  504. The BUILDTDF function requires all definitions to be 
  505. completely specified within the trace program file. Furthermore
  506. name must be specified rather than a module's hmte.
  507.  
  508.  
  509.  
  510. Tracepoint header:
  511. ------------------
  512.  
  513. The following must be specified, in any order, with the
  514. exception that minor= must appear first.
  515.  
  516. minor=    Tracepoint minor code
  517.  
  518. major=    Tracepoint major code - this may be respecified for
  519.           each tracepoint and overrides the major code specified
  520.           in the file header. This applies to which the current
  521.           tracepoint.
  522.  
  523. opcode=   Byte of opcode in module where the tracepoint will be 
  524.           inserted. Not all instructions are allowed to be 
  525.           specified as tracepoints, in particular the following
  526.           are prohibited:
  527.  
  528.              int3, int3, int, into, bound, mul, imul, div, and idiv
  529.  
  530.           which have opcodes:
  531.  
  532.              0xcc, 0xc3, 0xcd, 0xce, 0x62, 0x69, 0x6b, and
  533.              0xf6nn and 0xf7nn when nn is ??1?????.
  534.  
  535.           Note: if an instruction has a prefix then the tracepoint must
  536.           be applied to the prefix and not the following byte. If this
  537.           is not observed then the effect of the prefix will be lost when
  538.           the instruction executes.
  539.  
  540.  
  541. object=   Relative object of module where trace point will be 
  542.           applied. Objects are numbered from 1.
  543.  
  544. offset=   Offset within object where tracepoint will be applied.
  545.  
  546. major=    The major code override for a specific tracepoint. The 
  547.           default major code must be specified in the header to the 
  548.           trace program file. 
  549.  
  550. type=     Type is an optional parameter that is used only by the 
  551.           BUILDTDF function. Its purpose is to associate with each 
  552.           tracepoint one or more types. These are used by the 
  553.           OS/2 TRACE command as a means of selecting a subset of the 
  554.           tracepoints defined in the generated TDF. The operand to the
  555.           type= statement is be specified as a sequence of one or more
  556.           keyword names defined by typedef statements, separated 
  557.           '+' signs as follows:
  558.  
  559.               type=[keyword1[+keyword2 ...]] 
  560.  
  561.           A typical use of the trace type is to associate a particular
  562.           tracepoint with a particular characteristic. For example,
  563.           tracepoints in DOSCALL1 and KERNEL use type=PRE for API
  564.           pre-invocation tracepoints and type=POST for 
  565.           API post-invocation tracepoints.
  566.  
  567.           Only one type statement is permissible per tracepoint.
  568.  
  569. group=    Group is an optional parameter that is used only by the 
  570.           BUILDTDF function. Its purpose is to associate related 
  571.           subsets of the set of tracepoints defined in the generated 
  572.           TDF. These are used by the OS/2 TRACE command as a means of 
  573.           selecting a subset of the tracepoints defined in the 
  574.           generated TDF. The operand to the group= statement is 
  575.           specified as a single keyword name that has been defined by 
  576.           the groupdef statements.
  577.  
  578.           A typical use of the trace group is to associate all 
  579.           tracepoints that relate to a particular component of the 
  580.           system. For example, the group FS is used to associate all
  581.           tracepionts in DOSCALL1 and KERNEL that relate to the 
  582.           file-system. 
  583.  
  584.           Group is intended to be an exclusive classification of 
  585.           tracepoints compared with Type. Only one group may be 
  586.           associated with a particular tracepoint, whereas a 
  587.           tracepoint may have several type.
  588.  
  589.           Only one group statement is permissible per tracepoint.
  590.  
  591.  
  592. The Trace Program
  593. -----------------
  594. Trace program may specify any meaningful combination of the following
  595. RPN instructions. (TOS = Top of Stack).
  596.  
  597. Leng  Mnem  Operand(s)  Description
  598. -th   -onic 
  599. Bytes
  600. ---------------------------------------------------------------------
  601. 1     Abort             Abort - Log No Information                
  602. 1     Add               Add top 2 DWORD stack elements            
  603. 1     Cnvrt DXS         Convert Dword to Segmented                
  604. 1     Cnvrt FXS         Convert Flat to Segmented                 
  605. 1     Cnvrt SXD         Convert Segmented to Dword                
  606. 1     Cnvrt SXF         Convert Segmented to Flat                 
  607. 3     Inc   V,word      Increment Immediate Variable              
  608. 1     Inc   VIi         Increment indexed Variable                
  609. 3     Jmp   N,word      Jump forward N bytes or to a label                      
  610. 3     Jmp   NN,word     Jump forward N bytes or to a label if TOS < 0           
  611. 3     Jmp   PN,word     Jump forward N bytes or to a label if TOS > 0           
  612. 3     Jmp   ZN,word     Jump forward N bytes or to a label if TOS = 0           
  613. 1     Log   ARF         Log ASCIIZ at Flat Range                  
  614. 1     Log   ARS         Log ASCIIZ at Segmented Range             
  615. 2     Log   DN,byte     Log N DWORDs                              
  616. 1     Log   MRF         Log Memory at Flat Range                  
  617. 1     Log   MRS         Log Memory at Segmented Range             
  618. 2     Log   WN,byte     Log N WORDs                               
  619. 3     Move  V,word      Move top of stack to Immediate Var.       
  620. 1     Move  VIi         Move top of stack to indexed Var.         
  621. 1     Mul               Multiply top 2 stack elements             
  622. 3     Or    V,word      OR immed. indexed variable with TOS       
  623. 2     Pop   N,byte      Rotate stack down (pop) N times           
  624. 1     Push  CS          Push contents of (CS)                     
  625. 5     Push  D,dword     Push DWORD Immediate                      
  626. 1     Push  DS          Push contents of (DS)                     
  627. 1     Push  EAX         Push contents of (EAX)                    
  628. 1     Push  EBP         Push contents of (EBP)                    
  629. 1     Push  EBX         Push contents of (EBX)                    
  630. 1     Push  ECX         Push contents of (ECX)                    
  631. 1     Push  EDI         Push contents of (EDI)                    
  632. 1     Push  EDX         Push contents of (EDX)                    
  633. 1     Push  EFlags      Push contents of (EFlags)                 
  634. 1     Push  EIP         Push contents of (EIP)                    
  635. 1     Push  ES          Push contents of (ES)                     
  636. 1     Push  ESI         Push contents of (ESI)                    
  637. 1     Push  ESP         Push contents of (ESP)                    
  638. 1     Push  FIF         Push Flat Indirect Flat                   
  639. 1     Push  FS          Push contents of (FS)                     
  640. 1     Push  GS          Push contents of (GS)                     
  641. 5     Push  OXF,dword   Push (DWORD Object to Flat Address)       
  642. 2     Push  OXS,byte    Push (Object to Selector)                 
  643. 1     Push  SIS         Push Segmented Indirect Segmented         
  644. 1     Push  SS          Push contents of (SS)                     
  645. 3     Push  V,word      Push Immediate Variable                   
  646. 1     Push  VIi         Push indexed Variable                     
  647. 3     Push  W,word      Push WORD Immediate                       
  648. 1     Push  WIS         Push WORD Indirect Segmented              
  649. 1     Remove            Remove the current tracepoint             
  650. 1     Sub               Subtract top 2 stack elements             
  651. 1     SysDump           Force a system Dump (*)
  652. 1     And               AND top 2 stack elements (*)         
  653. 1     Or                OR top 2 stack elements (*)         
  654. 1     Xor               XOR top 2 stack elements (*)         
  655. 1     Neg               1's complement TOS (*)
  656. 1     Exit              Log data and exit tracepoint (*)
  657. 3     SetMin W,word     Override the tracepoint minor code with 'word' (**)
  658. 1     SetMin            Override the tracepoint minor code from TOS    (**)
  659. 3     SetMaj W,word     Override the tracepoint major code with 'word' (**)
  660. 1     SetMaj            Override the tracepoint major code from TOS    (**)
  661. 1     Xchg              Swap top two elements on the stack.            (**)
  662.                         Recovery may not be possible.
  663. 1     Call KDB    (df)  Force immediate entry to the kernel debugger      
  664. 1     Call DD     (f)   Call any device drivers registered for Dynamic Trace Kernel Exits (***)
  665. 1     Call DBG    (f)   Generic debugger call. If the application is being debugged by
  666.                         an applicaiton debugger, this command will force entry as if a
  667.                         trap had occurred. If no application debugger is active and
  668.                         the traced module is running under the debug kernel then
  669.                         entry to the kernel debugger will be forced. If entry to
  670.                         the kernel debugger is desired in preference to an application
  671.                         debugger then the .O kernel debugger command must be used.
  672.                         Having entered the kernel debugger, the user may use G to
  673.                         continue execution.
  674.                         Where TRAPDUMP is defined in the system and neither the
  675.                         debug kernel, an application debugger or application
  676.                         exception handler continues execution then a system dump
  677.                         will be take.
  678.                         Once Call DBG is executed the tracepoint is disabled and
  679.                         the original instruction is restored.
  680.                   
  681. 2     Dup N,byte  (f)   Duplicate the TOS N times.
  682. 1     Dup         (f)   Pop a double word for duplication, and then a duplication
  683.                         count from the TOS and push the duplicand N+1 times.
  684. 1     Enter BIF   (fd)  Pop a byte from TOS then a flat address and store the byte
  685.                         at that address.
  686. 1     Enter WIF   (fd)  Pop a word from TOS then a flat address and store the word 
  687.                         at that address.                                           
  688. 1     Enter DIF   (fd)  Pop a double-word from TOS then a flat address and store the 
  689.                         double-word at that address.                                           
  690. 1     Enter BIS   (fd)  Pop a byte from the TOS, then an offset, then a selector and
  691.                         store a byte at the 16:16 segmented address.
  692. 1     Enter WIS   (fd)  Pop a word from the TOS, then an offset, then a selector and
  693.                         store a word at the 16:16 segmented address.                
  694. 1     Enter DIS   (fd)  Pop a double-word from the TOS, then an offset, then a selector and
  695.                         store a double-word at the 16:16 segmented address.                
  696. 1     Push BIF    (f)   Pops a flat address from the TOS then pushes a byte at that address.
  697. 1     Push BIS    (f)   Pops an offset then a segment from the TOS then pushes a byte at 
  698.                         that 16:16 address. 
  699. 1     Push DIS    (f)   Pops an offset then a segment from the TOS then pushes a 
  700.                         double-word at that 16:16 address.  
  701. 1     Push WIF    (f)   Pops a flat address from the TOS then pushes a word at that address. 
  702. 1     Push TSC    (fp)  Pushes the Pentium TSC high double-word then low-double word onto
  703.                         onto the TOS. On non-pentium systems, zero is stored.
  704. 1     Push TID    (f)   Pushes the current Thread Ordinal on to the TOS
  705. 1     Push PID    (f)   Pushes the current Process Id onto the TOS.
  706. 1     Push PROCID (fs)  Pushes the current Processor ID onto the TOS. Zero is stored for
  707.                         Uni-processor systems.
  708. 1     Push SLOT   (f)   Pushes the current thread slot number onto the TOS.
  709. 1     Push pTCB   (f)   Pushes the flat address of the current TCB to TOS.
  710. 1     Push pPTDA  (f)   Pushes the flat address of the current PTDA to TOS. 
  711. 1     Push pPCB   (fs)  Pushes the flat address of the current PCB to TOS. Zero is store
  712.                         on Uni-processor systems.
  713. 1     Suspend     (f)   Suspends system trace recording.
  714. 1     Resume      (f)   Resume system trace recording.
  715. 2     Rol N       (f)   Rotate TOS left N bits.
  716. 2     Ror N       (f)   Rotate TOS right N bits. 
  717. 2     Shl N       (f)   Shift TOS left N bits. 
  718. 2     Shr N       (f)   Shift TOS right N bits.
  719. 1     Rol         (f)   Pops a double-word then a count from TOS then rotates 
  720.                         the double word left N bits and replaces it on the TOS.
  721. 1     Ror         (f)   Pops a double-word then a count from TOS then rotates   
  722.                         the double word right N bits and replaces it on the TOS. 
  723. 1     Shl         (f)   Pops a double-word then a count from TOS then shifts    
  724.                         the double word left N bits and replaces it on the TOS.
  725. 1     Shr         (f)   Pops a double-word then a count from TOS then shifts    
  726.                         the double word right N bits and replaces it on the TOS. 
  727. 1     Vfa         (f)   Pops a flat address from the TOS.
  728.                         Verifies read access to a byte pointed to by the flat
  729.                         address. The TOS is replace by a 0 if access is given
  730.                         and by 1 if not.
  731.                   
  732. 1     Vsa         (f)   Pops and offset then a selector from the TOS.
  733.                         Verifies read access to a byte pointed to by the 16:16      
  734.                         address. The TOS is replace by a 0 if access is given 
  735.                         and by 1 if not.                                             
  736. 1     Push KEAX   (f)   If in the kernel, (Kmode) pushes the client EAX otherwise current EAX 
  737. 1     Push KECX   (f)   If in the kernel, (Kmode) pushes the client ECX otherwise current ECX 
  738. 1     Push KEDX   (f)   If in the kernel, (Kmode) pushes the client EDX otherwise current EDX 
  739. 1     Push KEBX   (f)   If in the kernel, (Kmode) pushes the client EBX otherwise current EBX 
  740. 1     Push KESP   (f)   If in the kernel, (Kmode) pushes the client ESP otherwise current ESP 
  741. 1     Push KEBP   (f)   If in the kernel, (Kmode) pushes the client EBP otherwise current EBP 
  742. 1     Push KESI   (f)   If in the kernel, (Kmode) pushes the client ESI otherwise current ESI 
  743. 1     Push KEDI   (f)   If in the kernel, (Kmode) pushes the client EDI otherwise current EDI 
  744. 1     Push KES    (f)   If in the kernel, (Kmode) pushes the client ES  otherwise current ES  
  745. 1     Push KCS    (f)   If in the kernel, (Kmode) pushes the client CS  otherwise current CS  
  746. 1     Push KSS    (f)   If in the kernel, (Kmode) pushes the client SS  otherwise current SS  
  747. 1     Push KDS    (f)   If in the kernel, (Kmode) pushes the client DS  otherwise current DS  
  748. 1     Push KEFLAG (f)   If in the kernel, (Kmode) pushes the client EFLAG otherwise current EFLAG
  749. 1     Push KEIP   (f)   If in the kernel, (Kmode) pushes the client EIP otherwise current EIP 
  750. 1     Push KFS    (f)   If in the kernel, (Kmode) pushes the client FS  otherwise current FS 
  751. 1     Push KGS    (f)   If in the kernel, (Kmode) pushes the client GS  otherwise current GS
  752. 1     Enter EAX   (fd)  Pops a double-word from the TOS and modifies the current EAX.
  753. 1     Enter EBX   (fd)  Pops a double-word from the TOS and modifies the current EBX.
  754. 1     Enter ECX   (fd)  Pops a double-word from the TOS and modifies the current ECX.
  755. 1     Enter EDX   (fd)  Pops a double-word from the TOS and modifies the current EDX.
  756. 1     Enter ESI   (fd)  Pops a double-word from the TOS and modifies the current ESI.
  757. 1     Enter EDI   (fd)  Pops a double-word from the TOS and modifies the current EDI.
  758. 1     Enter EBP   (fd)  Pops a double-word from the TOS and modifies the current EBP.
  759. 1     Enter DS    (fd)  Pops a double-word from the TOS and modifies the current DS.
  760. 1     Enter ES    (fd)  Pops a double-word from the TOS and modifies the current ES.
  761. 1     Enter FS    (fd)  Pops a double-word from the TOS and modifies the current FS.
  762. 1     Enter GS    (fd)  Pops a double-word from the TOS and modifies the current GS.
  763. 1     Push CR0    (f)   Pushes CR0 onto the TOS.
  764. 1     Push CR2    (f)   Pushes CR2 onto the TOS. 
  765. 1     Push CR3    (f)   Pushes CR3 onto the TOS. 
  766. 1     Push CR4    (f)   Pushes CR4 onto the TOS. 
  767. 1     Push DR0    (f)   Pushes DR0 onto the TOS. 
  768. 1     Push DR1    (f)   Pushes DR1 onto the TOS. 
  769. 1     Push DR2    (f)   Pushes DR2 onto the TOS. 
  770. 1     Push DR3    (f)   Pushes DR3 onto the TOS. 
  771. 1     Push DR6    (f)   Pushes DR6 onto the TOS. 
  772. 1     Push DR7    (f)   Pushes DR7 onto the TOS. 
  773. 1     Push TR     (f)   Pushes TR  onto the TOS. 
  774. 1     Push LDTR   (f)   Pushes LDTR onto the TOS. 
  775. 1     Push GDTR   (f)   Pushes GDTR FWORD onto the top two stack elements.
  776. 1     Push IDTR   (f)   Pushes GDTR FWORD onto the TOS two stack elements.  
  777. 1     Push MSR    (fp)  Pops a MSR register number from the TOS then pushes the high then low 
  778.                         double-words of the MSR onto the stack.
  779. 1     Push PMC    (fp)  Pops a PMC counter number from the TOS then pushes the high then low 
  780.                         double-words of the PMC onto the stack.                               
  781. 1     Push CPUID  (fp)  Pops a CPUID information number from the TOS then pushes the four
  782.                         double-words of the CPUID, highest first, onto the stack.                               
  783.  
  784.  
  785.  
  786. * Each of the commands flagged with (*) require APAR PJ22196 applying
  787. to the OS2KRNL.
  788.  
  789. * Each of the commands flagged with (**) will be supported the GA version 
  790. of OS/2 Warp 4.0 - they are not implemented in the public beta version.
  791.  
  792. * Each of the command flagged with (f) require feature F180062 to be installed.
  793.  
  794. * Each of the command flagged with (d) operate only under the debug kernel and
  795.   no-op on the retail kernel.
  796.  
  797. * Each of the command flagged with (s) operate only under SMP and no-op
  798.   otherwise.
  799.  
  800. * Each of the command flagged with (p) operate only under certain Pentium
  801.   processors and no-op, otherwise.
  802.  
  803.  
  804. Each of these commands acts as follows:
  805.  
  806.  
  807. PUSH: Push a value on to the RPN stack
  808.  
  809.    In Push SS and Push ESP the value of SS and ESP is dependent on whether the 
  810.    tracepoint occurred at ring 0 or not.
  811.  
  812.    In Push EIP, the EIP on the stack is one too large, due to the 
  813.    INT3.
  814.  
  815.    Push W takes a word operand, zero extends it, and pushes
  816.    it on to the RPN stack.
  817.  
  818.    Push OXS converts its byte operand into a selector,
  819.    zero extends that value, and pushes it on to the stack.
  820.    The byte operand is on object number of the module which
  821.    is currenlty being traced.
  822.    Because MTEs may eventually become nonresident, the selectors
  823.    (up to 256) are stored in an array by DynamicTrace  when the tracepoints
  824.    were inserted.  The word operand indexes this array to get the sel.
  825.  
  826.    Push WIS pops an offset, then a selector, from the RPN stack,
  827.    fetches the user word at that 16:16 address, zero extends it,
  828.    and pushes that on to the RPN stack.
  829.    If the address is invalid or not present, a GP fault or Page
  830.    fault record will be logged in the buffer, and the interpreter
  831.    will exit.
  832.  
  833.    Push SIS pops an offset, then a selector, from the RPN stack,
  834.    fetches the user dword at that 16:16 address and pushes that on to
  835.    the RPN stack in the segmented address format.     That is,
  836.    the high word (selector) is zero extended and pushed, and then
  837.    the low word (offset) is zero extended and pushed.
  838.    If the address is invalid or not present, a GP fault or Page
  839.    fault record will be logged in the buffer, and the interpreter
  840.    will exit.
  841.  
  842.    Push OXF converts its dword operand into a flat address,
  843.    and pushes that on to the stack. See description of PUSH OXS for
  844.    more details.
  845.  
  846.    Push FIF pops a Dword from the RPN stack, and then
  847.    pushes the dword at that flat address on to the stack.
  848.  
  849.    Push V takes a word operand. Push V uses that to index
  850.    to the Dynamic Trace variable in the current DTO, and pushes the value
  851.    it finds there.
  852.  
  853.    Push VIi fetches an index of a Dynamic Trace variable from
  854.    the top of the stack, (without doing a pop), and then
  855.    pushes the value of that variable on to the stack.
  856.  
  857. LOG: Log data in the system trace buffer.
  858.  
  859.    Log WN takes a byte operand, and repeats the following operation
  860.    that many times:
  861.       Pop the value from the top of the RPN stack
  862.       Log the low word of that value, ignoring the high word.
  863.    If the log overflows, the interpreter will exit without continuing,
  864.    but will record as much as it can.
  865.  
  866.    Log MRS pops the following from the RPN stack:
  867.      Offset
  868.      Selector
  869.      Length
  870.  
  871.    Log MRS then zero extends all these values, and attempts to
  872.    move Length number of bytes from the given 16:16 address into
  873.    the log buffer.
  874.  
  875.    The logged memory is prefixed by 3 bytes :
  876.      Token byte of 0,
  877.      Length word (length of logged information, in bytes)
  878.  
  879.    If an address is invalid or not present, a GP fault or Page
  880.    fault record will be logged in the buffer, and the interpreter
  881.    will exit.
  882.  
  883.    If the log overflows, the interpreter will exit without continuing,
  884.    and without logging the memory.
  885.  
  886.    Log ARS pops the following from the RPN stack:
  887.      Offset
  888.      Selector
  889.      Length
  890.  
  891.    Log ARS then zero extends all these values, and attempts to
  892.    move Length number of bytes from the given 16:16 address into
  893.    the log buffer.  The data transfer will be discontinued if a
  894.    null byte is fetched.  The null byte will not be logged.
  895.  
  896.    The logged string is prefixed by 3 bytes :
  897.      Token byte of 1,
  898.      Length word (length of logged information, in bytes)
  899.  
  900.    If an address is invalid or not present, a GP fault or Page
  901.    fault record will be logged in the buffer, and the interpreter
  902.    will exit.
  903.  
  904.    If the log overflows, the interpreter will exit without continuing,
  905.    and without logging the string.
  906.  
  907.    Log DN takes a byte operand, and repeats the following operation
  908.    that many times:
  909.       Pop the value from the top of the RPN stack
  910.       Log the value (as a DWORD)
  911.  
  912.    If the log overflows, the interpreter will exit without continuing,
  913.    but will record as much as it can.
  914.  
  915.    Log MRF pops the following from the RPN stack:
  916.       Flat Address
  917.       Length
  918.  
  919.    Log MRF then zero extends the length, and attempts to move
  920.    Length number of bytes from the given flat address into
  921.    the log buffer.
  922.  
  923.    The logged memory is prefixed by 3 bytes :
  924.       Token byte of 0,
  925.       Length word (length of logged information, in bytes)
  926.  
  927.    If an address is not present, a Page fault record will be
  928.    logged in the buffer, and the interpreter will exit.
  929.  
  930.    If the log overflows, the interpreter will exit without continuing,
  931.    and without logging the memory.
  932.  
  933.  
  934.    Log ARF pops the following from the RPN stack:
  935.       Flat Address
  936.       Length
  937.  
  938.    Log ARF then zero extends the length, and attempts to move
  939.    Length number of bytes from the given flat address into
  940.    the log buffer.  The data transfer will be discontinued if a
  941.    null byte is fetched.  The null byte will not be logged.
  942.  
  943.    The logged string is prefixed by 3 bytes :
  944.       Token byte of 1,
  945.       Length word (length of logged information, in bytes)
  946.  
  947.    If an address is not present, a Page fault record will be
  948.    logged in the buffer, and the interpreter will exit.
  949.  
  950.    If the log overflows, the interpreter will exit without continuing,
  951.    and without logging the string.
  952.  
  953.  
  954.    When memory references are invalid the token byte is set to one of
  955.    the following to indicate the type of error encountered:
  956.  
  957.       -1  Invalid Selector
  958.       -2  Selector not Present
  959.       -3  Page not Present
  960.  
  961.    The byte count is set to 4 and the data logged is the fault 
  962.    address.
  963.     
  964.  
  965. ADD/SUB/MUL/AND/OR/XOR: Add/Subtact/Multiply the top two stack 
  966.    elements
  967.  
  968.    Add pops two DWORDs from the RPN stack, and pushes their sum.
  969.  
  970.    Sub pops two DWORDs from the RPN stack, and pushes their
  971.    difference.   The first value popped is subtracted from the second.
  972.  
  973.    Mul pops two DWORDs from the RPN stack, and pushes their
  974.    product.
  975.  
  976.    And pops two DWORDs from the RPN stack, and pushes their
  977.    bit-wise AND.
  978.  
  979.    Or pops two DWORDs from the RPN stack, and pushes their
  980.    bit-wise Or.
  981.  
  982.    Xor pops two DWORDs from the RPN stack, and pushes their
  983.    bit-wise Xor.
  984.  
  985. NEG: 1's complement top of stack.
  986.    
  987.    Neg 1's complements the TOS. No data is pushed or popped.
  988.  
  989. CNVRT: Convert an address
  990.  
  991.    Cnvrt FXS pops a dword from the RPN stack, uses CRMA
  992.    to translate that flat pointer to a 16:16 segmented pointer.
  993.    It then pushes the selector (zero extended) and then the
  994.    offset (zero extended) on to the stack.
  995.  
  996.    If the flat address does not lie within the compatibility
  997.    region, the interpreter will exit immediately.
  998.  
  999.  
  1000.    Cnvrt SXF pops a selector, then an offset from the RPN stack,
  1001.    uses CRMA to translate that 16:16 pointer to a flat address,
  1002.    and pushes that flat address on to the stack.
  1003.  
  1004.    If the segmented address does not lie within the comparability
  1005.    region (GDT selector), the interpreter will exit immediately.
  1006.  
  1007.    Cnvrt DXS pops a DWORD, then pushes the high word (zero
  1008.    extended) and then the low word (zero extended).  No CRMA is
  1009.    applied.
  1010.  
  1011.    Cnvrt SXD pops a low word, then a high word, then
  1012.    concatenates them into a DWORD, and pushes the result.
  1013.  
  1014.  
  1015. POP: Pop a value from the RPN stack.
  1016.  
  1017.      Pop N takes a byte operand, and pops that many operands
  1018.      from the stack.  As the values are not actually removed from
  1019.      the 16-element circular stack, Pop N effectively rotates
  1020.      the stack down.
  1021.  
  1022.  
  1023. MOVE: Move a value to a variable.
  1024.  
  1025.    Move V takes a word operand. Move V then moves
  1026.    the value on the top of the stack to the Dynamic Trace variable
  1027.    in the current DTO at that index.  The top of stack pointer
  1028.    is not changed.
  1029.  
  1030.    Move VIi pops a variable index off the top of the stack,
  1031.    and then pops a value off the top of the stack.  The value is moved
  1032.    into the Dynamic Trace variable in the current DTO at that index.
  1033.    The variable and the index are then pushed back on to the stack,
  1034.    so that there is no net change on the stack at all.
  1035.  
  1036.    If the index is too large, the interpreter will exit with an error.
  1037.  
  1038. INC: Increment a variable.
  1039.  
  1040.    Inc V takes a word operand, and increments the value in the
  1041.    Dynamic Trace variable in the current DTO at that index.
  1042.  
  1043.    Inc VIi fetches an index of a Dynamic Trace variable from
  1044.    the top of the stack, (without doing a pop), and then
  1045.    increments the value of that variable.
  1046.  
  1047.    If the index is too large, the interpreter will exit with an error.
  1048.  
  1049.  
  1050. JMP: Jump forward in the RPN program.
  1051.  
  1052.    Jmp takes a word or label as operand.  Jmp causes an
  1053.    unconditional jump forward in the instruction stream by
  1054.    that number of bytes, relative to the first byte of the next
  1055.    instruction.
  1056.  
  1057.    Therefore, Jmp by 0 bytes is a NOP (i.e jmp n,0)
  1058.  
  1059.  
  1060.    Jmp ZN takes a word or label as operand.  Jmp ZN causes an
  1061.    unconditional jump forward in the instruction stream by
  1062.    that number of bytes, relative to the end of the instruction,
  1063.    but only if the value on the top of the stack is zero.
  1064.  
  1065.    Jmp NN takes a word or label operand.  JmpNN causes an
  1066.    unconditional jump forward in the instruction stream by
  1067.    that number of bytes, relative to the end of the instruction,
  1068.    but only if the value on the top of the stack is negative.
  1069.  
  1070.    Jmp PN takes a word or label operand.  Jmp PN causes an
  1071.    unconditional jump forward in the instruction stream by
  1072.    that number of bytes, relative to the end of the instruction,
  1073.    but only if the value on the top of the stack is positive.
  1074.  
  1075.    To prevent loops, no backward jumps are permitted.  Also, it is
  1076.    illegal to jump into the code stream for another tracepoint.
  1077.  
  1078.    If labels are specified, DTRACE calculates the relative forward
  1079.    offset.
  1080.  
  1081. REMOVE: Remove and Abort the current tracepoint.
  1082.  
  1083. ABORT:  Abort the tracepoint.
  1084.  
  1085.    Abort aborts the tracepoint entirely.  The interpreter
  1086.    exits, but does not log any information.  The data logged
  1087.    by this tracepoint is lost.
  1088.  
  1089.    However, alterations to the variables remain.
  1090.  
  1091.    By using Abort in combination with the Jmp
  1092.    instructions, unnecessary tracepoints can be filtered
  1093.    at run time, without crowding or overflowing the log buffer.
  1094.  
  1095. EXIT:  Exit the tracepoint.
  1096.  
  1097.    Exit terminates the tracepoint.  The interpreter
  1098.    exits, and logs any information requested so far. The tracepoint
  1099.    remains in tact.
  1100.  
  1101.    By using Exit in combination with the Jmp
  1102.    instructions, specific conditions can be detected before logging
  1103.    additional data.
  1104.  
  1105.    If Exit is not available (systems without PJ22196) then the 
  1106.    equivalent may be achieved by coding:
  1107.  
  1108.          jmp n,exit
  1109.          .
  1110.          .
  1111.          .
  1112.          .
  1113.    exit: jmp n,0 ;nop
  1114.  
  1115.  
  1116. ORV: OR a Dynamic Trace variable with TOS.
  1117.  
  1118. SYSDUMP: Force a System Dump.
  1119.  
  1120.    SysDump transfers control to the stand alone dump process. No 
  1121.    data is logged. No system shutdown is performed and normal 
  1122.    system execution is terminated immediately.
  1123.  
  1124.    Use this command with the Jmp instructions to detect illusive error
  1125.    conditions that require dump analysis at the point of error.
  1126.  
  1127.  
  1128. SETMAJ: Override the tracepoint major code
  1129.  
  1130.    SetMaj takes the word value from the TSO to override the tracepoint
  1131.    major code. The override remains in effect until the current RPN
  1132.    program exits. Since data is not logged to the system trace buffer
  1133.    until the RPN program exits, the major code may be overridden at any
  1134.    point and remain effective for the whole trace entry.
  1135.  
  1136.    SetMaj may be specified with the W,word operand form. In this case
  1137.    'word' forms the major code override.
  1138.  
  1139.    Note: Prior to feature F180062 the system trace facility admits only 
  1140.    major codes from 0 - 255. Any specification of a major code greater 
  1141.    than 255 will be treated as if the high-order byte value is zero. With
  1142.    F180062 the allowable range will be from 0-65535.
  1143.  
  1144.    This is provided to allow trace formatting templates to be 
  1145.    selected dynamically according to the data logged.
  1146.  
  1147. SETMIN: Override the tracepoint minor code
  1148.  
  1149.    SetMin takes the word value from the TOS to override the tracepoint
  1150.    minor code. The override remains in effect until the current RPN
  1151.    program exits. Since data is not logged to the system trace buffer
  1152.    until the RPN program exits, the minor code may be overridden at
  1153.    any point and remain effective for the whole trace entry.
  1154.  
  1155.    SetMin may be specified with the W,word operand form. In this case
  1156.    'word' forms the minor code override.
  1157.  
  1158.    The system trace facility admit minor codes in the range from
  1159.    0x0000 to 0xffff.
  1160.  
  1161.    This is provided to allow trace formatting templates to be 
  1162.    selected dynamically according to the data logged.
  1163.  
  1164.  
  1165. XCHG: Exchange the top two entries on the RPN Stack.
  1166.  
  1167.    Xchg pops the top two stack elements then pushes them back on to
  1168.    the stack in the reverse order.
  1169.  
  1170. ENTER: Alter memory or a register value. See Push
  1171.  
  1172. CALL: Exit to another facility. 
  1173.  
  1174.       CALL KDB forces immediate entry to the kernel debugger by means of a
  1175.       simulated TRAP 3. On uniprocessor kernels, execution may be continued 
  1176.       by using the G Kernel Debugger command, but any attempt to single-step 
  1177.       (T or P) or go from a particular address (T= or G=, or P=) may cause a 
  1178.       system failure.
  1179.  
  1180.       Under SMP kernels, recovery is generally not possible.
  1181.  
  1182.       Use CALL KDB only if you wish to force entry to the kernel debugger
  1183.       immediately rather than let normal trap processing determine how a
  1184.       TRAP 3 should be handled.
  1185.  
  1186.  
  1187.  
  1188.       CALL DBG is a generic call to a debugging facility. Depending on
  1189.       circumstance this could be: System Dump, Process Dump, Kernel Debugger
  1190.       or Application Debugger.
  1191.  
  1192.       CALL DBG removes the tracepoint and restores the original instruction.
  1193.       It then exits the Dynamic Trace facility via TRAPCommonFaultEntry.
  1194.       The effect of this is to simulate a trap 3 as if a real INT3 instruction
  1195.       had been coded in the trace code path, with the exception that the INT3
  1196.       is no longer in the code path. In essence CALL DBG inserts a temporary 
  1197.       breakpoint into the traced code path but removes it as soon as it fires.
  1198.       If the breakpoint is intercepted by a debugger then execution may be 
  1199.       continued as if a regular breakpoint had been activated. If debuggers are
  1200.       not active then dump processing may take effect if customised to do so.
  1201.       If no debuggers are active and no dump processing is specified then
  1202.       the application will receive a breakpoint exception. If it has exception
  1203.       handlers designed to handle this, it may recover otherwise it will be 
  1204.       terminated.
  1205.  
  1206.  
  1207.  
  1208.       CALL DD allow dynamic trace device driver exits to be called as an
  1209.       extension to the RPN command set. Each driver exit is called in the
  1210.       order they were registered. They have access to and may modify 
  1211.       the current log buffer, RPN Stack, Major and Minor codes. They may
  1212.       call SysTrace directly using DevHlp_RAS (DevHlp_SysTrace) to write
  1213.       additional trace records. Exits are also able to register a temporary
  1214.       fault handler address to allow them the recover from General Protection
  1215.       and Page faults from data accesses. Stack faults and other exceptions
  1216.       are not recoverable.
  1217.  
  1218.       A device driver registers a Dynamic Trace Exit using the 
  1219.       DevHlp_RegisterKrnlExit (dl = 6fh). This interface requires
  1220.       BX:SI to point to the exit address, AX the be the function code
  1221.       (0000h = delete, 1000h = add, 2000h = query) and CX = 0003h (DYN_Exit).
  1222.       Registration may take place at device driver initialisation time.
  1223.       
  1224.       On entry to the device driver's exit routine FS:DI points to a ddx_s 
  1225.       structure, defined . AX contains the driver's data segment and DS the 
  1226.       FLAT 32-bit 4Gb data selector.
  1227.       
  1228.       The driver may modify ddx_StackIndex if it wishes to reposition the
  1229.       current RPN stack pointer.
  1230.       
  1231.       The RPN stack may be modified. The Head of the stack is pointed to by
  1232.       ddx_StackStart. Each stack element is a DWORD. ddx_StackIndex indexes,
  1233.       by DWORD into the stack. The maximum number of stack elements are given
  1234.       in ddx_StackSize. The action of pushing onto the stack increments the
  1235.       stack index by 1 modulo ddx_StackSize. Conversely popping decrements
  1236.       ddx_StackIndex module ddx_StackSize.
  1237.       
  1238.       ddx_Major and ddx_Minor may be modified.
  1239.       
  1240.       The Driver may write to the log pointed to by ddx_LogStart, but must 
  1241.       update ddx_LogIndex to point to the next available byte in the Log buffer
  1242.       if new data is to be written or data removed. If data remains in the log
  1243.       buffer on normal completion of the current RPN program it will be written
  1244.       to the trace buffer as a single trace record. Therefore, the format of
  1245.       data in the log buffer is only required to conform with any TFF require to
  1246.       format it. The number of bytes written must not exceed ddx_LogSize.
  1247.       
  1248.       All pointers are 16:16 far pointers (i.e. ddx_LogStart and ddx_StackStart)
  1249.       The driver is called as if at interrupt time and is consequently restricted
  1250.       to the number of DevHlps available. DevHlp_SysTrace (DevHlp_RAS) may be used
  1251.       to log additional data instead of adding data to the original log buffer
  1252.       pointed to by ddx_LogStart. This provides a means of logging more than
  1253.       512 bytes per tracepoint. It DevHlp_SysTrace is called 
  1254.       then any trace record created by the current RPN program will follow
  1255.       chronologically from the static trace records created by the driver.
  1256.       While the major and minor codes used by the dynamic tracepoint might exceed
  1257.       255, DevHlp_SysTrace is currently restricted to maximum major and minor
  1258.       code values of 255. Attempts to use a higher value will result in it being
  1259.       truncated to a single byte. 
  1260.  
  1261.       Dynamic Tracepoints may not be placed in the Driver's exit code.
  1262.       
  1263.       The Device Driver may register a fault handler to receive control for
  1264.       data access exceptions causing Faults 13 (General Protection) and 14
  1265.       (Page Fault). This is done by placing the 16:16 address of the fault handler
  1266.       in ddx_pfnFault. When an exception occurs, dynamic trace will give control to
  1267.       the fault handler, having first disabled it. The driver may subsequently enable
  1268.       the fault handler by setting ddx_pfnFault. On entry to the fault handler AX 
  1269.       contains the driver's data segment. DS, ES, SS and ESP are destroyed.
  1270.       Other segment and general registers retain values from the point the fault
  1271.       occurred. If the driver does not register a fault handler then the 
  1272.       tracepoint is aborted if a fault occurs within the driver.
  1273.       
  1274.       SS, SP, DS, FS and DI must be restored by the driver on exit.
  1275.       
  1276.       The driver returns to the system using a far16 return.
  1277.       
  1278.       On exit, if EAX is zero then the next registered driver will be called
  1279.       otherwise control returns to Dynamic Trace.
  1280.       
  1281.       The driver exit runs as an extension to the system's trap 3 handler. No
  1282.       INT3 instructions may occur in the exit code path. Nor may the Kernel
  1283.       debugger BP, T or P commands be used. Breakpoints may be set using
  1284.       BR, but must be disabled before continuing execution. 
  1285.       G <to address> may not be used if the target address lies within the
  1286.       trap 3 code path and in particular the device driver exit code path.
  1287.       Traps other than 1 and 3 may be intercepted using VT. Always use 
  1288.       VC following entry to the kernel debugger after a vector trap.
  1289.       These restrictions apply because the commands list employ temporary INT3
  1290.       breakpoints as part of their mechanism.
  1291.  
  1292.  
  1293.    The structure definition for the DDX is as follows:
  1294.  
  1295. struct  ddx_s     {
  1296.         unsigned long ddx_StackStart;
  1297.         unsigned long ddx_StackSize;
  1298.         unsigned long ddx_StackIndex;
  1299.         unsigned long ddx_Major;
  1300.         unsigned long ddx_Minor;
  1301.         unsigned long ddx_LogStart;
  1302.         unsigned long ddx_LogSize;
  1303.         unsigned long ddx_LogIndex;
  1304.         unsigned long ddx_pfnFault;          
  1305. };
  1306.  
  1307. DUP/DUPN
  1308.    Causes the element at the TOS to be duplicated N time. In the case of DUP N
  1309.    the duplication count is immediate. With DUP the count is popped from the TOS
  1310.    following the duplicand. The duplicand is immediately popped back onto the stack
  1311.    before any duplication is performed.
  1312.  
  1313. ROL/ROR/SHL/SHR/ROLN/RORN/SHLN/SHRN
  1314.    Causes the element at the TOS to be rotated or shifted N times. In the case of xxxN
  1315.    the shift/rotation count is immediate, otherwise it is popped from the TOS following
  1316.    the element to be shifted/rotated.
  1317.  
  1318. ----------------------------------------------------------------------
  1319.  
  1320. Invalid Data - return code 13 errors
  1321.  
  1322. Return code 13 is issued for a variety of reasons from the DosDynamicTrace API.
  1323. However the majority potential reasons are caught by DTRACE before the API
  1324. call is made and an explanatory message is issued. The remaining cases that
  1325. cause DosDynamicTrace to return ERROR_INVALID_DATA are:
  1326.  
  1327. 1) Variables out of range. An RPN command references an undefined local variable or
  1328.    the GETVARS function references undefined local variables.
  1329.  
  1330. 2) Logmax exceeds the maximum value currently implemented by system trace. The maximum
  1331.    prior to f180062 was 512. With feature f180062 this has been increased to 4099.
  1332.  
  1333. 3) Major exceed the maximum value currently implemented by system trace. Prior to
  1334.    feature f180062 (Warp 3.0 fix pack 34) the maximum value is 255 (0xff). With feature 
  1335.    f180062 the maximum value allowed is 65535 (0xffff).
  1336.  
  1337. 4) Opcode does not match that at the specified object and offset.
  1338.    This could imply that the hmte is incorrect.
  1339.  
  1340. 5) The object and offset are not defined within the specified module. 
  1341.    This could imply that the hmte is incorrect.
  1342.  
  1343. 6) Opcode specifies a prohibited instruction. These are: 
  1344.    int3, int, into, bound, mul, imul, div, and idiv
  1345.    0xcc, 0xcd, 0xce, 0x62, 0x69, 0x6b,  0xf6nn and 0xf7nn when nn is ??1?????.
  1346.    Version 4.3 of DTRACE checks for prohibited opcodes where possible. If an one
  1347.    is found DTRACE raises an error. If a tracepoints falls on an instruction prefix,
  1348.    or a 0xf6 or 0xf7 opcode then a warning is given since DTRACE is unable to determine
  1349.    the true instruction type. 
  1350.  
  1351. 7) Too many unique jump targets within a single tracepoint. The current maximum is 256.
  1352.  
  1353. 8) Unsupported RPN commands. The RPN command set has been increased over several releases
  1354.    and fix pack for OS/2. It is possible that DTRACE would permit the coding of an
  1355.    unsupported RPN command on an earlier release.
  1356.  
  1357. ----------------------------------------------------------------------
  1358.  
  1359. Trace Program Examples:
  1360.  
  1361. The following examples illustrate common usages of the RPN commands.
  1362.  
  1363. 1) Log AX and BX registers:
  1364.  
  1365.        Push EBX
  1366.        Push EAX
  1367.        Log  WN,2 ;lower 16 bits of each DWORD
  1368.  
  1369. 2) Log EIP, EBP and EAX:
  1370.  
  1371.        Push EAX
  1372.        Push EBP
  1373.        Push EIP
  1374.        Log  DN,3  ;3 DWORDs from the stack
  1375.  
  1376. 3) Log value at EBP+ESI:
  1377.  
  1378.        Push W,4  ; push immediate value 4 - length to log
  1379.        Push EBP
  1380.        Push ESI
  1381.        Add       ; add top two DWORDs - puts EBP+ESI on stack
  1382.        Log  MRF  ; log memory at flat address range
  1383.  
  1384. 4) Log value at SS:SP using 16-bit segmented addressing:
  1385.  
  1386.        Push W,9  ; push immediate  value 9 - length to log
  1387.        Push SS
  1388.        Push ESP
  1389.        Log  MRS  ; log memory at segmented address range
  1390.  
  1391. 5) Log 16 bytes of data pointed to by the flat address at SS:SP+8
  1392.  
  1393.        Push W,16 ; push immediate value 16 - length to log
  1394.        Push SS
  1395.        Push ESP
  1396.        Push 8    ; offset 8
  1397.        Add       ; 8 added to ESP value on stack
  1398.        Push SIS  ; pop ESP then SS and pop Dword at that address
  1399. ; as two Words extended to Dwords (as if it was a sel:offset).
  1400. ; stack now contains the length and split address of data to log
  1401.        Cnvrt SXD ; Concatenate the two words to form a flat address
  1402.        Log  MRF  ; log the data. 
  1403.  
  1404. 6) This example shows an RPN fragment that extracts and logs the
  1405.    Tid and Slot number of the thread making the trace entry.
  1406.    The current TCB is located via the SAS and the Tid/Slot are taken
  1407.    from the 1st word of the TCB. This example requires 2 local 
  1408.    variables defining for temporary use.
  1409.  
  1410. ; get the slot and tid from the SAS
  1411. ; requires 2 variables to be defined for temporary use.
  1412. push  w,0x70;SAS selector (used later)
  1413. push  w,0x70;SAS selector
  1414. push  w,0x0e;offset to tasking section offset 
  1415. push  wis
  1416. move  v,0   ;save tasking section offset
  1417. push  w,0xa ;offset to slot no address
  1418. add         ;TOS=sel:off-> @tasknumber
  1419. push  sis   ;(using first push w,0x70)
  1420. cnvrt sxd   ;TOS->tasknumber
  1421. push  fif   ;fetch slot number
  1422. push  w,4   ;scale by 4
  1423. mul         ;convert to index into tcb ptrs table
  1424. move  v,1   ;save offset into TCB table
  1425. pop   n,1
  1426. push  w,0x70
  1427. push  v,0   ;offset into tasking section
  1428. push  w,0x6 ;offset to @TCB ptrs addr
  1429. add
  1430. push  sis 
  1431. cnvrt sxd   ;address of @tcb table on stack 
  1432. push  fif   ;addres of tcb table on TOS
  1433. push  v,1   ;offset into table for current thread
  1434. add
  1435. push  fif   ;current tcb address on stack
  1436. push  fif   ;slot/tid on TOS
  1437. log   dn,1  ;w2=slot w1=tid
  1438.  
  1439. ----------------------------------------------------------------------
  1440.  
  1441. Complete Examples:
  1442.  
  1443. In the following examples, object, offset and opcode must be altered
  1444. accordingly before running any of these on an OS/2 system.
  1445.  
  1446. 1) Trace DOSREAD and DOSWRIT. Dump the SS:ESP and 0x20 bytes of the stack.
  1447.    Define 1 Dynamic Trace variable and increment it each time the tracepoint
  1448.    fires.
  1449.  
  1450. major=0xfc
  1451. vars=1
  1452. id=2
  1453. ;
  1454. ;DOSREAD
  1455. ;
  1456. minor=1
  1457. opcode=0x55; push
  1458. object=0x3
  1459. offset=0x4008
  1460. push ss
  1461. push esp
  1462. log wn,2
  1463. push W,0x20
  1464. push ss
  1465. push esp
  1466. log mrs
  1467. inc v,0
  1468. ;
  1469. ;DOSWRITE 
  1470. ;
  1471. minor=2
  1472. opcode=0xc8 ;enter
  1473. object=0x5
  1474. offset=0x9a4
  1475. push ss
  1476. push esp
  1477. log wn,2
  1478. push W,0x20
  1479. push ss
  1480. push esp
  1481. log mrs
  1482. ;
  1483.  
  1484.  
  1485. 2) Monitor the number of calls to WinSendMsg and WinPostMsg. 
  1486.  
  1487. major=0xfb
  1488. vars=2
  1489. id=1
  1490. ;
  1491. ;WinSendMsg
  1492. ;
  1493. minor=1
  1494. opcode=0x58 ;push
  1495. object=0x1
  1496. offset=0x2730
  1497. inc v,0
  1498. abort
  1499. ;
  1500. ;WinPostMsg
  1501. ;
  1502. minor=2
  1503. opcode=0x36
  1504. object=1
  1505. offset=0xde73
  1506. inc v,1
  1507. abort
  1508.  
  1509. 3) Trace 4 entry points to HPFS.IFS. Log the stack pointer and 20 bytes of
  1510. data.
  1511.  
  1512.  
  1513. major=0xfd
  1514. ;
  1515. ;FS_READ - HPFS
  1516. ;
  1517. minor=1
  1518. opcode=0xc8 ;enter
  1519. object=0x1
  1520. offset=0x11ac
  1521. push ss
  1522. push esp
  1523. log wn,2
  1524. push W,0x20
  1525. push ss
  1526. push esp
  1527. log mrs
  1528. ;
  1529. ;FS_WRITE - HPFS
  1530. ;
  1531. minor=2
  1532. opcode=0xc8 ;enter
  1533. object=0x1
  1534. offset=0x114c
  1535. push ss
  1536. push esp
  1537. log wn,2
  1538. push W,0x20
  1539. push ss
  1540. push esp
  1541. log mrs
  1542. ;FS_CHDIR - HPFS
  1543. ;
  1544. minor=3
  1545. opcode=0xc8 ;enter
  1546. object=0x2
  1547. offset=0x1fc
  1548. push ss
  1549. push esp
  1550. log wn,2
  1551. push W,0x20
  1552. push ss
  1553. push esp
  1554. log mrs
  1555. ;FS_CLOSE - HPFS
  1556. ;
  1557. minor=4
  1558. opcode=0xc8 ;enter
  1559. object=0x1
  1560. offset=0x5cc
  1561. push ss
  1562. push esp
  1563. log wn,2
  1564. push W,0x20
  1565. push ss
  1566. push esp
  1567. log mrs
  1568. ;FS_OPENCREATE - HPFS
  1569. ;
  1570. minor=5
  1571. opcode=0xc8 ;enter
  1572. object=0x2
  1573. offset=0x2168
  1574. push ss
  1575. push esp
  1576. log wn,2
  1577. push W,0x20
  1578. push ss
  1579. push esp
  1580. log mrs
  1581.  
  1582.  
  1583. 4) Trace all the entry points to HPFS386 with custom formatting.
  1584.  
  1585. The HPFS386.RPN file is as follows:
  1586.  
  1587. ;
  1588. major=0xfa
  1589. ;
  1590. ;
  1591. ; Trace HPFS386 FSD entry points
  1592. ;
  1593. ;
  1594. ;0005:001C HPFS386:CODE16:FS_ALLOCATEPAGESPACE
  1595. minor=0x100
  1596. object=5
  1597. offset=0x1c
  1598. opcode=0xb8 ;move
  1599. push ss
  1600. push esp
  1601. log wn,2
  1602. push w,0x20
  1603. push ss
  1604. push esp
  1605. log mrs
  1606. ;
  1607. ;0005:002C HPFS386:CODE16:FS_CANCELLOCKREQUEST
  1608. minor=0x101
  1609. object=5
  1610. offset=0x2c
  1611. opcode=0xb8 ;move
  1612. push ss
  1613. push esp
  1614. log wn,2
  1615. push w,0x20
  1616. push ss
  1617. push esp
  1618. log mrs
  1619. ;0005:003C HPFS386:CODE16:FS_CHDIR
  1620. minor=0x102
  1621. object=5
  1622. offset=0x3c
  1623. opcode=0xb8 ;move
  1624. push ss
  1625. push esp
  1626. log wn,2
  1627. push w,0x20
  1628. push ss
  1629. push esp
  1630. log mrs
  1631. ;0005:004C HPFS386:CODE16:FS_CHGFILEPTR
  1632. minor=0x103
  1633. object=5
  1634. offset=0x4c
  1635. opcode=0xb8 ;move
  1636. push ss
  1637. push esp
  1638. log wn,2
  1639. push w,0x20
  1640. push ss
  1641. push esp
  1642. log mrs
  1643. ;0005:005C HPFS386:CODE16:FS_CLOSE
  1644. minor=0x104
  1645. object=5
  1646. offset=0x5c
  1647. opcode=0xb8 ;move
  1648. push ss
  1649. push esp
  1650. log wn,2
  1651. push w,0x20
  1652. push ss
  1653. push esp
  1654. log mrs
  1655. ;0005:006C HPFS386:CODE16:FS_COMMIT
  1656. minor=0x105
  1657. object=5
  1658. offset=0x6c
  1659. opcode=0xb8 ;move
  1660. push ss
  1661. push esp
  1662. log wn,2
  1663. push w,0x20
  1664. push ss
  1665. push esp
  1666. log mrs
  1667. ;0005:007C HPFS386:CODE16:FS_DELETE
  1668. minor=0x106
  1669. object=5
  1670. offset=0x7c
  1671. opcode=0xb8 ;move
  1672. push ss
  1673. push esp
  1674. log wn,2
  1675. push w,0x20
  1676. push ss
  1677. push esp
  1678. log mrs
  1679. ;0005:008C HPFS386:CODE16:FS_DOPAGEIO
  1680. minor=0x107
  1681. object=5
  1682. offset=0x8c
  1683. opcode=0xb8 ;move
  1684. push ss
  1685. push esp
  1686. log wn,2
  1687. push w,0x20
  1688. push ss
  1689. push esp
  1690. log mrs
  1691. ;0005:009C HPFS386:CODE16:FS_EXIT
  1692. minor=0x108
  1693. object=5
  1694. offset=0x9c
  1695. opcode=0xb8 ;move
  1696. push ss
  1697. push esp
  1698. log wn,2
  1699. push w,0x20
  1700. push ss
  1701. push esp
  1702. log mrs
  1703. ;0005:00AC HPFS386:CODE16:FS_FILEATTRIBUTE
  1704. minor=0x109
  1705. object=5
  1706. offset=0xac
  1707. opcode=0xb8 ;move
  1708. push ss
  1709. push esp
  1710. log wn,2
  1711. push w,0x20
  1712. push ss
  1713. push esp
  1714. log mrs
  1715. ;0005:00BC HPFS386:CODE16:FS_FILEINFO
  1716. minor=0x10a
  1717. object=5
  1718. offset=0xbc
  1719. opcode=0xb8 ;move
  1720. push ss
  1721. push esp
  1722. log wn,2
  1723. push w,0x20
  1724. push ss
  1725. push esp
  1726. log mrs
  1727. ;0005:00CC HPFS386:CODE16:FS_FILEIO
  1728. minor=0x10b
  1729. object=5
  1730. offset=0xcc
  1731. opcode=0xb8 ;move
  1732. push ss
  1733. push esp
  1734. log wn,2
  1735. push w,0x20
  1736. push ss
  1737. push esp
  1738. log mrs
  1739. ;0005:00DC HPFS386:CODE16:FS_FILELOCKS
  1740. minor=0x10c
  1741. object=5
  1742. offset=0xdc
  1743. opcode=0xb8 ;move
  1744. push ss
  1745. push esp
  1746. log wn,2
  1747. push w,0x20
  1748. push ss
  1749. push esp
  1750. log mrs
  1751. ;0005:00EC HPFS386:CODE16:FS_FINDCLOSE
  1752. minor=0x10d
  1753. object=5
  1754. offset=0xec
  1755. opcode=0xb8 ;move
  1756. push ss
  1757. push esp
  1758. log wn,2
  1759. push w,0x20
  1760. push ss
  1761. push esp
  1762. log mrs
  1763. ;0005:00FC HPFS386:CODE16:FS_FINDFIRST
  1764. minor=0x10e
  1765. object=5
  1766. offset=0xfc
  1767. opcode=0xb8 ;move
  1768. push ss
  1769. push esp
  1770. log wn,2
  1771. push w,0x20
  1772. push ss
  1773. push esp
  1774. log mrs
  1775. ;0005:010C HPFS386:CODE16:FS_FINDFROMNAME
  1776. minor=0x10f
  1777. object=5
  1778. offset=0x10c
  1779. opcode=0xb8 ;move
  1780. push ss
  1781. push esp
  1782. log wn,2
  1783. push w,0x20
  1784. push ss
  1785. push esp
  1786. log mrs
  1787. ;0005:011C HPFS386:CODE16:FS_FINDNEXT
  1788. minor=0x110
  1789. object=5
  1790. offset=0x11c
  1791. opcode=0xb8 ;move
  1792. push ss
  1793. push esp
  1794. log wn,2
  1795. push w,0x20
  1796. push ss
  1797. push esp
  1798. log mrs
  1799. ;0005:012C HPFS386:CODE16:FS_FINDNOTIFYCLOSE
  1800. minor=0x111
  1801. object=5
  1802. offset=0x12c
  1803. opcode=0xb8 ;move
  1804. push ss
  1805. push esp
  1806. log wn,2
  1807. push w,0x20
  1808. push ss
  1809. push esp
  1810. log mrs
  1811. ;0005:013C HPFS386:CODE16:FS_FINDNOTIFYFIRST
  1812. minor=0x112
  1813. object=5
  1814. offset=0x13c
  1815. opcode=0xb8 ;move
  1816. push ss
  1817. push esp
  1818. log wn,2
  1819. push w,0x20
  1820. push ss
  1821. push esp
  1822. log mrs
  1823. ;0005:014C HPFS386:CODE16:FS_FINDNOTIFYNEXT
  1824. minor=0x113
  1825. object=5
  1826. offset=0x14c
  1827. opcode=0xb8 ;move
  1828. push ss
  1829. push esp
  1830. log wn,2
  1831. push w,0x20
  1832. push ss
  1833. push esp
  1834. log mrs
  1835. ;0005:015C HPFS386:CODE16:FS_FLUSHBUF
  1836. minor=0x114
  1837. object=5
  1838. offset=0x15c
  1839. opcode=0xb8 ;move
  1840. push ss
  1841. push esp
  1842. log wn,2
  1843. push w,0x20
  1844. push ss
  1845. push esp
  1846. log mrs
  1847. ;0005:016C HPFS386:CODE16:FS_FSCTL
  1848. minor=0x115
  1849. object=5
  1850. offset=0x16c
  1851. opcode=0xb8 ;move
  1852. push ss
  1853. push esp
  1854. log wn,2
  1855. push w,0x20
  1856. push ss
  1857. push esp
  1858. log mrs
  1859. ;0005:017C HPFS386:CODE16:FS_FSINFO
  1860. minor=0x116
  1861. object=5
  1862. offset=0x17c
  1863. opcode=0xb8 ;move
  1864. push ss
  1865. push esp
  1866. log wn,2
  1867. push w,0x20
  1868. push ss
  1869. push esp
  1870. log mrs
  1871. ;0005:018C HPFS386:CODE16:FS_IOCTL
  1872. minor=0x117
  1873. object=5
  1874. offset=0x18c
  1875. opcode=0xb8 ;move
  1876. push ss
  1877. push esp
  1878. log wn,2
  1879. push w,0x20
  1880. push ss
  1881. push esp
  1882. log mrs
  1883. ;0005:019C HPFS386:CODE16:FS_MKDIR
  1884. minor=0x118
  1885. object=5
  1886. offset=0x19c
  1887. opcode=0xb8 ;move
  1888. push ss
  1889. push esp
  1890. log wn,2
  1891. push w,0x20
  1892. push ss
  1893. push esp
  1894. log mrs
  1895. ;0005:01AC HPFS386:CODE16:FS_MOUNT
  1896. minor=0x119
  1897. object=5
  1898. offset=0x1ac
  1899. opcode=0xb8 ;move
  1900. push ss
  1901. push esp
  1902. log wn,2
  1903. push w,0x20
  1904. push ss
  1905. push esp
  1906. log mrs
  1907. ;0005:01BC HPFS386:CODE16:FS_MOVE
  1908. minor=0x11a
  1909. object=5
  1910. offset=0x1bc
  1911. opcode=0xb8 ;move
  1912. push ss
  1913. push esp
  1914. log wn,2
  1915. push w,0x20
  1916. push ss
  1917. push esp
  1918. log mrs
  1919. ;0005:01CC HPFS386:CODE16:FS_NEWSIZE
  1920. minor=0x11b
  1921. object=5
  1922. offset=0x1cc
  1923. opcode=0xb8 ;move
  1924. push ss
  1925. push esp
  1926. log wn,2
  1927. push w,0x20
  1928. push ss
  1929. push esp
  1930. log mrs
  1931. ;0005:01DC HPFS386:CODE16:FS_OPENCREATE
  1932. minor=0x11c
  1933. object=5
  1934. offset=0x1dc
  1935. opcode=0xb8 ;move
  1936. push ss
  1937. push esp
  1938. log wn,2
  1939. push w,0x20
  1940. push ss
  1941. push esp
  1942. log mrs
  1943. ;0005:01EC HPFS386:CODE16:FS_OPENPAGEFILE
  1944. minor=0x11d
  1945. object=5
  1946. offset=0x1ec
  1947. opcode=0xb8 ;move
  1948. push ss
  1949. push esp
  1950. log wn,2
  1951. push w,0x20
  1952. push ss
  1953. push esp
  1954. log mrs
  1955. ;0005:01FC HPFS386:CODE16:FS_PATHINFO
  1956. minor=0x11e
  1957. object=5
  1958. offset=0x1fc
  1959. opcode=0xb8 ;move
  1960. push ss
  1961. push esp
  1962. log wn,2
  1963. push w,0x20
  1964. push ss
  1965. push esp
  1966. log mrs
  1967. ;0005:020C HPFS386:CODE16:FS_READ
  1968. minor=0x11f
  1969. object=5
  1970. offset=0x20c
  1971. opcode=0xb8 ;move
  1972. push ss
  1973. push esp
  1974. log wn,2
  1975. push w,0x20
  1976. push ss
  1977. push esp
  1978. log mrs
  1979. ;0005:021C HPFS386:CODE16:FS_RMDIR
  1980. minor=0x120
  1981. object=5
  1982. offset=0x21c
  1983. opcode=0xb8 ;move
  1984. push ss
  1985. push esp
  1986. log wn,2
  1987. push w,0x20
  1988. push ss
  1989. push esp
  1990. log mrs
  1991. ;0005:022C HPFS386:CODE16:FS_SHUTDOWN
  1992. minor=0x121
  1993. object=5
  1994. offset=0x22c
  1995. opcode=0xb8 ;move
  1996. push ss
  1997. push esp
  1998. log wn,2
  1999. push w,0x20
  2000. push ss
  2001. push esp
  2002. log mrs
  2003. ;0005:023C HPFS386:CODE16:FS_WRITE
  2004. minor=0x122
  2005. object=5
  2006. offset=0x23c
  2007. opcode=0xb8 ;move
  2008. push ss
  2009. push esp
  2010. log wn,2
  2011. push w,0x20
  2012. push ss
  2013. push esp
  2014. log mrs
  2015. ;
  2016. ;
  2017. ;
  2018.  
  2019. The TSF file for TRCUST is as follows:
  2020.  
  2021. MODNAME = HPFS386
  2022. MAJOR   = 250
  2023. MAXDATALENGTH = 512
  2024.  
  2025.  
  2026. TRACE MINOR = 0x100
  2027. TP    = @STATIC
  2028. DESC  = "HPFS386 FS_ALLOCATEPAGESPACE"
  2029. FMT   = "SS:ESP=%A"
  2030. FMT   = "Stack %R%W"
  2031.  
  2032. TRACE MINOR = 0x101
  2033. TP    = @STATIC
  2034. DESC  = "HPFS386 FS_CANCELLOCKREQUEST"
  2035. FMT   = "SS:ESP=%A"
  2036. FMT   = "Stack %R%W"
  2037.  
  2038. TRACE MINOR = 0x102
  2039. TP    = @STATIC
  2040. DESC  = "HPFS386 FS_CHDIR"
  2041. FMT   = "SS:ESP=%A"
  2042. FMT   = "Stack %R%W"
  2043.  
  2044. TRACE MINOR = 0x103
  2045. TP    = @STATIC
  2046. DESC  = "HPFS386 FS_CHGFILEPTR"
  2047. FMT   = "SS:ESP=%A"
  2048. FMT   = "Stack %R%W"
  2049.  
  2050. TRACE MINOR = 0x104
  2051. TP    = @STATIC
  2052. DESC  = "HPFS386 FS_CLOSE"
  2053. FMT   = "SS:ESP=%A"
  2054. FMT   = "Stack %R%W"
  2055.  
  2056. TRACE MINOR = 0x105
  2057. TP    = @STATIC
  2058. DESC  = "HPFS386 FS_COMMIT"
  2059. FMT   = "SS:ESP=%A"
  2060. FMT   = "Stack %R%W"
  2061.  
  2062. TRACE MINOR = 0x106
  2063. TP    = @STATIC
  2064. DESC  = "HPFS386 FS_DELETE"
  2065. FMT   = "SS:ESP=%A"
  2066. FMT   = "Stack %R%W"
  2067.  
  2068. TRACE MINOR = 0x107
  2069. TP    = @STATIC
  2070. DESC  = "HPFS386 FS_DOPAGEIO"
  2071. FMT   = "SS:ESP=%A"
  2072. FMT   = "Stack %R%W"
  2073.  
  2074. TRACE MINOR = 0x108
  2075. TP    = @STATIC
  2076. DESC  = "HPFS386 FS_EXIT"
  2077. FMT   = "SS:ESP=%A"
  2078. FMT   = "Stack %R%W"
  2079.  
  2080. TRACE MINOR = 0x109
  2081. TP    = @STATIC
  2082. DESC  = "HPFS386 FS_FILEATTRIBUTE"
  2083. FMT   = "SS:ESP=%A"
  2084. FMT   = "Stack %R%W"
  2085.  
  2086. TRACE MINOR = 0x10a
  2087. TP    = @STATIC
  2088. DESC  = "HPFS386 FS_FILEINFO"
  2089. FMT   = "SS:ESP=%A"
  2090. FMT   = "Stack %R%W"
  2091.  
  2092. TRACE MINOR = 0x10b
  2093. TP    = @STATIC
  2094. DESC  = "HPFS386 FS_FILEIO"
  2095. FMT   = "SS:ESP=%A"
  2096. FMT   = "Stack %R%W"
  2097.  
  2098. TRACE MINOR = 0x10c
  2099. TP    = @STATIC
  2100. DESC  = "HPFS386 FS_FILELOCKS"
  2101. FMT   = "SS:ESP=%A"
  2102. FMT   = "Stack %R%W"
  2103.  
  2104. TRACE MINOR = 0x10d
  2105. TP    = @STATIC
  2106. DESC  = "HPFS386 FS_FINDCLOSE"
  2107. FMT   = "SS:ESP=%A"
  2108. FMT   = "Stack %R%W"
  2109.  
  2110. TRACE MINOR = 0x10e
  2111. TP    = @STATIC
  2112. DESC  = "HPFS386 FS_FINDFIRST"
  2113. FMT   = "SS:ESP=%A"
  2114. FMT   = "Stack %R%W"
  2115.  
  2116. TRACE MINOR = 0x10f
  2117. TP    = @STATIC
  2118. DESC  = "HPFS386 FS_FINDFROMNAME"
  2119. FMT   = "SS:ESP=%A"
  2120. FMT   = "Stack %R%W"
  2121.  
  2122. TRACE MINOR = 0x110
  2123. TP    = @STATIC
  2124. DESC  = "HPFS386 FS_FINDNEXT"
  2125. FMT   = "SS:ESP=%A"
  2126. FMT   = "Stack %R%W"
  2127.  
  2128. TRACE MINOR = 0x111
  2129. TP    = @STATIC
  2130. DESC  = "HPFS386 FS_FINDNOTIFYCLOSE"
  2131. FMT   = "SS:ESP=%A"
  2132. FMT   = "Stack %R%W"
  2133.  
  2134. TRACE MINOR = 0x112
  2135. TP    = @STATIC
  2136. DESC  = "HPFS386 FS_FINDNOTIFYFIRST"
  2137. FMT   = "SS:ESP=%A"
  2138. FMT   = "Stack %R%W"
  2139.  
  2140. TRACE MINOR = 0x113
  2141. TP    = @STATIC
  2142. DESC  = "HPFS386 FS_FINDNOTIFYNEXT"
  2143. FMT   = "SS:ESP=%A"
  2144. FMT   = "Stack %R%W"
  2145.  
  2146. TRACE MINOR = 0x114
  2147. TP    = @STATIC
  2148. DESC  = "HPFS386 FS_FLUSHBUF"
  2149. FMT   = "SS:ESP=%A"
  2150. FMT   = "Stack %R%W"
  2151.  
  2152. TRACE MINOR = 0x115
  2153. TP    = @STATIC
  2154. DESC  = "HPFS386 FS_FSCTL"
  2155. FMT   = "SS:ESP=%A"
  2156. FMT   = "Stack %R%W"
  2157.  
  2158. TRACE MINOR = 0x116
  2159. TP    = @STATIC
  2160. DESC  = "HPFS386 FS_FSINFO"
  2161. FMT   = "SS:ESP=%A"
  2162. FMT   = "Stack %R%W"
  2163.  
  2164. TRACE MINOR = 0x117
  2165. TP    = @STATIC
  2166. DESC  = "HPFS386 FS_IOCTL"
  2167. FMT   = "SS:ESP=%A"
  2168. FMT   = "Stack %R%W"
  2169.  
  2170. TRACE MINOR = 0x118
  2171. TP    = @STATIC
  2172. DESC  = "HPFS386 FS_MKDIR"
  2173. FMT   = "SS:ESP=%A"
  2174. FMT   = "Stack %R%W"
  2175.  
  2176. TRACE MINOR = 0x119
  2177. TP    = @STATIC
  2178. DESC  = "HPFS386 FS_MOUNT"
  2179. FMT   = "SS:ESP=%A"
  2180. FMT   = "Stack %R%W"
  2181.  
  2182. TRACE MINOR = 0x11a
  2183. TP    = @STATIC
  2184. DESC  = "HPFS386 FS_MOVE"
  2185. FMT   = "SS:ESP=%A"
  2186. FMT   = "Stack %R%W"
  2187.  
  2188. TRACE MINOR = 0x11b
  2189. TP    = @STATIC
  2190. DESC  = "HPFS386 FS_NEWSIZE"
  2191. FMT   = "SS:ESP=%A"
  2192. FMT   = "Stack %R%W"
  2193.  
  2194. TRACE MINOR = 0x11c
  2195. TP    = @STATIC
  2196. DESC  = "HPFS386 FS_OPENCREATE"
  2197. FMT   = "SS:ESP=%A"
  2198. FMT   = "Stack %R%W"
  2199.  
  2200. TRACE MINOR = 0x11d
  2201. TP    = @STATIC
  2202. DESC  = "HPFS386 FS_OPENPAGEFILE"
  2203. FMT   = "SS:ESP=%A"
  2204. FMT   = "Stack %R%W"
  2205.  
  2206. TRACE MINOR = 0x11e
  2207. TP    = @STATIC
  2208. DESC  = "HPFS386 FS_PATHINFO"
  2209. FMT   = "SS:ESP=%A"
  2210. FMT   = "Stack %R%W"
  2211.  
  2212. TRACE MINOR = 0x11f
  2213. TP    = @STATIC
  2214. DESC  = "HPFS386 FS_READ"
  2215. FMT   = "SS:ESP=%A"
  2216. FMT   = "Stack %R%W"
  2217.  
  2218. TRACE MINOR = 0x120
  2219. TP    = @STATIC
  2220. DESC  = "HPFS386 FS_RMDIR"
  2221. FMT   = "SS:ESP=%A"
  2222. FMT   = "Stack %R%W"
  2223.  
  2224. TRACE MINOR = 0x121
  2225. TP    = @STATIC
  2226. DESC  = "HPFS386 FS_SHUTDOWN"
  2227. FMT   = "SS:ESP=%A"
  2228. FMT   = "Stack %R%W"
  2229.  
  2230. TRACE MINOR = 0x122
  2231. TP    = @STATIC
  2232. DESC  = "HPFS386 FS_WRITE"
  2233. FMT   = "SS:ESP=%A"
  2234. FMT   = "Stack %R%W"
  2235.  
  2236. The formatting file is generated using TRCUST and the resulting
  2237. TRC00FA.TFF is copied to OS2\SYSTEM\TRACE
  2238.  
  2239. The commands executed to record the trace and spool the data to
  2240. a disk files are (where hmte has been first obtained from a source
  2241. such as Theseus/2 or the Kernel Debugger or the Dump Formatter):
  2242.  
  2243. DTRACE APPLY HPFS386.RPN /h=0x"hmte"
  2244. TRSPOOL /W
  2245.  
  2246.  
  2247. Change history:
  2248. ---------------
  2249.  5  Feb  96  Richard Moore  1.0 Created               
  2250.  
  2251.  10 Feb  96  Richard Moore  1.1 QUERY/GETVARS added.          
  2252.  
  2253.  20 Mar  96  Richard Moore  1.2 SysDump/And/Or/Xor/Not/Exit/  
  2254.                                 ProcDump RPN support added.   
  2255.  
  2256.  27 Mar  96  Richard Moore  1.3 Add /Q Quiet option and Fix /R.                      
  2257.  
  2258.  2  Apr  96  Richard Moore  2.0 Added support for labels in the RPN 
  2259.                                 program.
  2260.  
  2261.  3  Apr  96  Richard Moore  2.1 Minor bug fix, where ':' in comment is
  2262.                                 not processes correctly.
  2263.                                 Added more RPN examples.
  2264.  
  2265.  5  May  96  Richard Moore  2.2 Allow name to be specified in the RPN
  2266.                                 file. Allow the RPNs program to be 
  2267.                                 optional. Fix error handling and add
  2268.                                 information messages. Document logmax.                      
  2269.  
  2270.  17 Jun  96  Richard Moore  2.3 Add SetMaj/SetMajW SetMin/SetMinW Xchg                     
  2271.  
  2272.  16 Aug  96  Richard Moore  2.3a Documentation update. Define DTO and
  2273.                                 Remove reference to TRACE command in
  2274.                                 examples.
  2275.  
  2276.  17 Aug  96  Richard Moore  2.4 Allow name to specify a file
  2277.                                 extension. Allow OS2KRNLx and 
  2278.                                 OS2KRNL to be aliases of DOSCALLS.DLL                 
  2279.                                 Ignore any ctrl chars in rpn file.
  2280.  
  2281.  18 Aug  96  Richard Moore  2.5 Allow Major code overrides. Clarify
  2282.                                 error messages. Fix REMOVE file_name.         
  2283.                                 Allow DTRACE to be compatible with
  2284.                                 TDFLST output. This introduces four 
  2285.                                 new keywords that are recognised but 
  2286.                                 ignored. These are: 
  2287.                                 GROUPDEF, TYPEDEF, GROUP, TYPE
  2288.  
  2289.  23 Aug  96  Richard Moore  2.6 Fix PUSH CS, was erroneously
  2290.                                 PUSH ECS.
  2291.  
  2292.  1  Sep  96  Richard Moore  3.0 Implement the BUILDTDF function.
  2293.                                 Benign bug fix: erroneous PUSH EAX was 
  2294.                                 being generated after each tracepoint 
  2295.                                 definition.
  2296.  20 Sep  96  Richard Moore  3.1 Delay DosFreeModule until after 
  2297.                                 DosDynamicTrace. Fix doc error in example.
  2298.  16 Dec  96  Richard Moore  3.1a minor editorial changes to the 
  2299.                                 documentation.
  2300.  
  2301.  09 Jan  97  Richard Moore  3.2 Add support for non *.DLL named modules. 
  2302.                                 Clarify use if id and name parameters.
  2303.                                 Add info on use of TRACE.EXE with non-*.DLL
  2304.                                 modules and dynamic tracing at interrupt 
  2305.                                 time.
  2306.  
  2307.  16 Jan  97  Richard Moore  3.3 Add support for *.EXEs, both with standard
  2308.                                 and non-standard extensions.
  2309.  21 Feb  97  Richard Moore  3.4 Improved module search for all module types.         
  2310.                                 Simple names and names with extension may
  2311.                                 be specified for any DLL that is in LIBPATH
  2312.                                 or current directory or other module in PATH.
  2313.                                 GETVARS now displays hex/dec values.   
  2314.                                 Made .RPN the default extension for RPN files.
  2315.                                 Fix PRN cmd parser error.      
  2316.                                 Added /D switch for debugging DTRACE.      
  2317.                                 Disable dosfreemodule to avoid IPEs.                          
  2318.  25 Feb  97  Richard Moore  3.4a @0004                         
  2319.                                 Improved error processing. Fixed hang when 
  2320.                                 taking an error path and DosKillProcess is     
  2321.                                 outstanding. 
  2322.  29 Apr  97  Richard Moore  3.5  @0005                         
  2323.                                 Fixed label limit. Improved /Q. Allowed 
  2324.                                 /M /N /Q /D with BUILDTDF. Added /M to help 
  2325.                                 and documentation. 
  2326.  
  2327.  23 May  97  Richard Moore  3.6  @0006                         
  2328.                                 Add error checking to numeric values. Allow 
  2329.                                 assembler style hexadecimal constants (xxxxh).
  2330.                                 Diagnostic DTRACE.TDF and TRC0063.TFF generated.
  2331.  24 May  97  Richard Moore  3.7  @0007                         
  2332.                                 Fix CLEARALL /Q         
  2333.  07 Juk  97  Richard Moore  3.7a minor correction to debug msg 
  2334.                                                                
  2335.  10 Sep  97  Richard Moore  3.8 @0008                          
  2336.                                 Added new RPN commands for f180062                        
  2337.                                                               
  2338.  06 Oct  97  Richard Moore  4.0 @0009 F180062 additions:       
  2339.                                 1) Enhanced Query /x=[n] n=0-1 
  2340.                                 2) Fix Query and Getvars to    
  2341.                                    access non-active DTOs.     
  2342.                                 3) Add /a for Query all DTOs.  
  2343.                                 4) Add merge factity to APPLY  
  2344.                                    and REMOVE (/e).            
  2345.                                 5) REMOVE with /c @0010        
  2346.                                 6) Expanded help  @0010        
  2347.                                                               
  2348.  23 Oct  97  Richard Moore  4.1 @0010 correct info message for REMOVE /E                  
  2349.  
  2350.  07 Nov  97  Richard Moore  4.2 @0011 correct DTR status info
  2351.  05 Dec  97  Richard Moore  4.2 @0012 minor help corrections   
  2352.  
  2353.  06 Sep  98  Richard Moore  4.3 @0013 fix logic for handling Base Device Drivers
  2354.                                       Add Opcode validation.
  2355.                                       Allow whitespace and tab characters.
  2356.