home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / GDT.ZIP / GDT.DOC < prev    next >
Text File  |  1989-03-15  |  11KB  |  244 lines

  1. GDT.EXE -- An OS/2 Global Descriptor Table Debugger
  2.         (may also be used to wrap fish or clean baseboards)
  3.  
  4.                         "To tell you the honest truth, I get a little
  5.                         uneasy at the thought of device drivers by the
  6.                         masses."
  7.                             -- Noel J. Bergman
  8.                                CIS PCmagnet, 25-Oct-1988
  9.  
  10.                         "Protected mode?  What protected mode?"
  11.                             -- Ross Nelson
  12.                                BIX os.2/kernel #909
  13.  
  14.     GDT.EXE (version 0.30103) walks through the 286 protected-mode
  15. Global Descriptor Table (GDT) as used by OS/2.  It relies on a small
  16. device driver, DEVHLP.SYS, which must be installed in your CONFIG.SYS
  17. file (device=devhlp.sys).  DEVHLP.SYS is an OS/2 device driver that
  18. allows normal OS/2 Ring 3 applications (like GDT.EXE) to make DevHlp
  19. calls.  (DEVHLP.SYS has been undergoing changes, so you should use
  20. the version of DEVHLP.SYS found in GDT.ARC, even if you already have
  21. a version of DEVHLP.SYS.)
  22.  
  23.     GDT.EXE comes with a state-of-the-art graphical windowed
  24. user-interface.  Just kidding!  (Perhaps) it _should_ come with such
  25. an interface, but actually GDT.EXE works more like EDLIN or DEBUG.
  26.  
  27.     To print out the entire GDT, just type W (and a carriage
  28. return), and the programs does a "walk" through the entire 
  29. table.  The display looks like this:
  30.  
  31.     GDT at 11FE80 <limit 05095> <636 entries>
  32.     Type H for help
  33.     $ w
  34.     [seg 0008] 11FE80 <limit 05095> <lar 93> [Writable data]
  35.     [seg 0010] 009BE4 <limit 00043> <lar 83> [Busy TSS gate]
  36.     [seg 0018] 121A88 <limit 01023> <lar 92> [Writable data]
  37.     [seg 0020] 000000 <limit 01023> <lar 93> [Writable data]
  38.     [seg 0028] 1F5A60 <limit 02047> <lar 82> [LDT]
  39.     [seg 0030] 1F5A60 <limit 02047> <lar 93> [Writable data]
  40.     [seg 0038] 1F94A0 <limit 02897> <lar 93> [Writable data]
  41.     [seg 0040] 000400 <limit 00959> <lar 93> [Writable data]
  42.     [seg 0050] 009780 <limit 32501> <lar 93> [Writable data]
  43.     [seg 0060] 009A00 <limit 00071> <lar F1> [Read-only data]
  44.     [seg 0070] 009780 <limit 32501> <lar 90> [Read-only data]
  45.     [seg 0078] 1F1980 <limit 00145> <lar 93> [Writable data]
  46.     ....
  47.  
  48.     [seg] is the segment number in hex.  Since the protection level
  49. is encoded inside the segment number, for each segment number shown
  50. here, there are another three aliases.  The segment numbers shown by
  51. GDT.EXE are for Ring 0.
  52.  
  53.     The next entry, which looks like 123456, is the 24-bit physical
  54. address of the base of this segment.  (Note that these are 24-bit
  55. physical addresses, not the 20-bit ones you're used to from DOS.)
  56. This number is in hex.
  57.  
  58.     In a 286 operating system (and OS/2 is right now very much a 286
  59. OS, even if you're running it on a 386 machine), a segment can be
  60. from 0 to 64k bytes long.  The offset into the segment of the very
  61. last byte is indicated by the next entry in GDT.EXE's display, which
  62. looks like <limit 65535>.  This number is in decimal.
  63.  
  64.     Segments can have various attributes, also known as access
  65. rights.  The next entry displays the hex code for a segment's access
  66. rights, for example <lar 93>.  Since this is available using the LAR
  67. instruction, in GDT.EXE the information itself is called the LAR,
  68. even though that isn't quite right.
  69.  
  70.     Since few people can be expected to remember that, e.g., E4 is a
  71. call gate, the next (and last) entry displayed when you do a walk is
  72. a brief textual description of the segment like "Readable code",
  73. "Writable data," "Pungent aroma."
  74.  
  75.     One type of segment is so different from the others that it's
  76. displayed quite differently, however.  This is the call gate.  (This
  77. documentation is not intended to teach the workings of the 286.  For
  78. that, turn to a good book on the 286, repeat, 286, not 386 [trying to
  79. decipher the GDT under OS/2 using documentation for the 386 is a
  80. mistake; take my word for it], such as Stephen P. Morse and Douglas
  81. J. Albert, THE 80286 ARCHITECTURE; Ed Strauss, INSIDE THE 80286, or
  82. Marcel Proust, A LA RECHERCHE DU 286.)
  83.  
  84.     For a call gate, the display looks like this:
  85.  
  86. <Call gate 0F10:0000> <code 00B0:0B4E> <phys 115AEE> DOSALLOCSHRSEG (5 wds)
  87. <Call gate 0F18:0000> <code 00B0:0B8A> <phys 115B2A> DOSGETSHRSEG (4 wds)
  88. <Call gate 0F20:0000> <code 00B0:0BC2> <phys 115B62> DOSGIVESEG (4 wds)
  89. <Call gate 0F28:0000> <code 00B0:0BF8> <phys 115B98> DOSGETSEG (1 wds)
  90.  
  91.     Rather than display the segment number as [seg 0F10], for a call
  92. gate the same information is displayed as <Call gate 0F10:0000>.  This
  93. is the address you would get back from calling DosGetProcAddr on a
  94. DOSCALLS (OS/2 kernel) function.  Actually, it's not quite what you
  95. would get back:  0F10:0000 represents a Ring 0 segment; its Ring 3
  96. equivalent is 0F13:0000.
  97.  
  98.     The next field, e.g., <code 00B0:0B4E>, shows the code that
  99. the call gate points to.  Note that segment 00B0 (in this case) is
  100. just another entry in the GDT.  (I'll jump ahead of myself and
  101. tell you that if you just wanted to find out about segment 00B0,
  102. you could type . b0 [a dot followed by a space followed by B0,
  103. followed of course by the carriage return].)  This other entry had
  104. better be code, or we're in trouble.
  105.  
  106.     The next field, e.g., <phys 115AEE>, is the 24-bit physical
  107. address for the first opcode of the code pointed to by the call gate
  108. in the house that Jack built.  (In fact, all this code seems to have
  109. as its first instruction yet another CALL, so there's even one more
  110. level of indirection.)  This physical address is derived by adding
  111. together the physical address of the base of segment 00B0 (in this
  112. case) and the offset given in the call gate itself.
  113.  
  114.     The next field, e.g., DOSGETFRAMIS, represents the name of the
  115. OS/2 function for which the call gate is the entry point.  If the
  116. name is followed by an asterisk, this indicates that this is either
  117. a new and/or undocumented function, e.g., DOSICANONICALIZE or 
  118. DOSR2STACKREALLOC.
  119.  
  120.     The final field, e.g., (4 wds), indicates that this function 
  121. expects 4 words (8 bytes) worth of arguments.  Of course, this isn't
  122. such a revelation when you're talking about DOSGETFRAMIS (which,
  123. as we all know, does in fact take 4 words:  WORD, PTR WORD, WORD),
  124. but it might be useful for someone to know that the undocumented (?)
  125. DOSQSYSINFO takes 4 words.
  126.  
  127.     The LAR for a call gate is E4, and if you just wanted to display
  128. all call gates, you could ask GDT.EXE to "search" for them:
  129.  
  130.         $ s e4
  131.  
  132.     Likewise, if you were interested in finding segments marked
  133. as read-only data, one thing to try would be:
  134.  
  135.         $ s f1
  136.         [seg 0060] 009A00 <limit 00071> <lar F1> [Read-only data]
  137.         [seg 03E0] 1FBE20 <limit 00481> <lar F1> [Read-only data]
  138.     
  139.     Now, segment 0x60 is sort of interesting: it's the global
  140. information segment maintained by OS/2 (so far most of the data
  141. structures we've been looking at are pure 286, having little or
  142. nothing to do with OS/2 per se, but this one is certainly an OS/2
  143. data structure).
  144.  
  145.     To actually look at the bytes in segment 0x60, we can once
  146. again rely on the intuitive user-friendly interface of GDT.EXE.
  147. In this case, use the ? command:
  148.  
  149. $ ? 60
  150. [seg 0060] 009A00 <limit 00071> <lar F1> [Read-only data]
  151. 009A00  55 97 AD 23 84 2A 7B 00 17 39 09 03 FF FF 36 01    U...............
  152. 009A10  13 0C C4 07 01 0A 0A 00 05 10 05 01 09 00 01 03    ................
  153. 009A20  20 00 F8 00 01 00 00 00 00 00 00 00 00 00 00 00    ................
  154. 009A30  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
  155. 009A40  00 00 00 00 00 00 10                               .......
  156.  
  157.     You can continually type ? x60 at the $ prompt (or, if you have
  158. the ALIAS command-line editor, you can just press the up-arrow key),
  159. and each time you display the GIS it will be a little different, since
  160. OS/2 updates the time kept in the GIS.
  161.  
  162.     One can use the ? command to display any segment.  However, in
  163. the case of a call gate, it won't do you much good since (a) it's
  164. code you want, and (b) in a call gate the fields are all mixed up.
  165. Therefore, GDT.EXE provides the U command (for unassemble).
  166.  
  167.     Actually, it's not GDT.EXE that provides this -- I wouldn't know
  168. where to begin to write an unassembler, so CodeView (CVP.EXE) is run
  169. as a child process.  In the case of the call gate:
  170.  
  171. <Call gate 0F10:0000> <code 00B0:0B4E> <phys 115AEE> DOSALLOCSHRSEG (5 wds)
  172.  
  173. you would issue the command:
  174.  
  175.         $ u 00b0:0b4e
  176.  
  177. because you want to disassemble the code at 00B0:0B4E (remember, it's
  178. "just" a call gate at 0F10:0000).  GDT.EXE will bring up CodeView
  179. (which takes quite a while!), and all sorts of trash will be spewed
  180. out to your screen, including a line like 
  181.  
  182.         garbage     RET                         ; BR0
  183.  
  184. Ignore that!  It's just control returning to the debugger, at which
  185. point it picks up our instruction to unassemble.  With most of
  186. these DOSxxxx call gates, what you'll probably see as the first
  187. instruction is a line like
  188.  
  189.         garbage garbage garbage     CALL 74A0
  190.  
  191. At the CodeView prompt, you can now type
  192.  
  193.         > u 74a0
  194.  
  195. and so on.  Just q (quit) when you're done.  You'll be returned to
  196. the GDT.EXE $ prompt.
  197.  
  198.     When you tire of GDT.EXE, type q to quit back to OS/2.
  199.  
  200.     Other GDT.EXE commands include:
  201.  
  202.         ! <string> -- run another OS/2 program
  203.             $ ! cd \os2\forth && start forth
  204.             $ ! cd \os2\xlisp && start os2xlisp
  205.             $ ! dir
  206.  
  207.         H -- displays an out-of-date help message
  208.  
  209.         P -- displays bytes at an arbitrary physical address
  210.             $ p b 8000 40
  211.             $ p f e008 100
  212.  
  213.         R -- change radix (radix always entered in decimal)
  214.             $ r 10
  215.             $ r 16
  216.  
  217. Not-so-blue-sky:  Since in GDT.EXE we can manipulate call gates as data,
  218. we can probably also make them point to our own code, just an interrupt
  219. handler under MS-DOS.  This would be useful for writing front-ends to,
  220. or replacements for, various DOSxxxx calls.  Presumably one would name
  221. this facility DosSetProcAddr, since we already have DosGetProcAddr.
  222. Or, since there is VioRegister and KbdRegister, perhaps the facilities
  223. provided in DEVHLP.SYS could be used to build a DosRegister (not to
  224. be confused with a bridal registry, by the way).  I can think of one
  225. DOSxxx function that could use a better front-end, for example:
  226. DosGetProcAddr doesn't accept ASCIIZ names for DOSCALLS; couldn't
  227. we just write a preprocessor for it, point the call gate at our
  228. code (presumably fiddling around with protection levels), have our
  229. code call ("chain_intr," as it were) to the code that the call gate
  230. originally pointed to?  This would also be handy for writing home-brew
  231. profilers.
  232.  
  233. -- Andrew Schulman
  234.    32 Andrew (!) Street
  235.    Cambridge MA 02139
  236.    617-876-2102 (h)
  237.    617-577-8500 x7148 (w)
  238.  
  239.    18 December 1988     // twas the week before Xmas...
  240.    31 December 1988     // revised: the great new year's eve debug session
  241.  
  242.  
  243.  
  244.