Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

400 lines
7.7 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. trap.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Author:
  8. Ken Reneris
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. typedef struct {
  16. ULONG Mask;
  17. PUCHAR String;
  18. } BITENCODING, *PBITENCODING;
  19. typedef unsigned __int64 ULONGLONG;
  20. void DumpNpxULongLong (PUCHAR s, ULONGLONG l);
  21. void DumpNpxExtended (PUCHAR str, PUCHAR Value);
  22. void DumpNpxBits (ULONG, PUCHAR, PBITENCODING);
  23. PUCHAR NpxPrecisionControl[] = { "24Bits", "?1?", "53Bits", "64Bits" };
  24. PUCHAR NpxRoundingControl[] = { "Nearest", "Down", "Up", "Chop" };
  25. PUCHAR NpxTagWord[] = { " ", "ZR", "SP", " " };
  26. BITENCODING NpxStatusBits[] = {
  27. 1 << 8, "C0",
  28. 1 << 9, "C1",
  29. 1 << 10, "C2",
  30. 1 << 14, "C3",
  31. 0x8000, "Busy",
  32. 0x0001, "InvalidOp",
  33. 0x0002, "Denormal",
  34. 0x0004, "ZeroDivide",
  35. 0x0008, "Overflow",
  36. 0x0010, "Underflow",
  37. 0x0020, "Precision",
  38. 0x0040, "StackFault",
  39. 0x0080, "Summary",
  40. 0, 0
  41. };
  42. PUCHAR NpxOpD8[] = {
  43. "fadd", "fmul", "fcom", "fcomp", "fsub", "fsubr", "fdiv", "fdivr"
  44. };
  45. PUCHAR NpxOpD9[] = {
  46. "fld", "??3", "fst", "fstp", "fldenv", "fldcw", "fstenv", "fstcw"
  47. };
  48. PUCHAR NpxOpDA[] = {
  49. "fiadd", "fimul", "ficom", "ficomp", "fisub", "fisubr", "fidiv", "fidivr"
  50. };
  51. PUCHAR NpxOpDB[] = {
  52. "fild", "??4", "fist", "fistp", "??5", "fld", "??6", "fstp"
  53. };
  54. PUCHAR NpxOpDF[] = {
  55. "fild", "??4", "fist", "fistp", "fbld", "fild", "fbstp", "fstp"
  56. };
  57. PUCHAR *NpxSmOpTable[] = {
  58. NpxOpD8,
  59. NpxOpD9,
  60. NpxOpDA,
  61. NpxOpDB,
  62. NpxOpD8, // DC
  63. NpxOpD9, // DD
  64. NpxOpDA, // DE
  65. NpxOpDF
  66. };
  67. DECLARE_API( npx )
  68. /*++
  69. Routine Description:
  70. Dumps FNSAVE area format of NPX state
  71. Arguments:
  72. args -
  73. Return Value:
  74. None
  75. --*/
  76. {
  77. ULONG64 Address;
  78. UCHAR s[300], Reg[100];
  79. PUCHAR Stack, p;
  80. ULONG i, j, t, tos, Tag;
  81. ULONG ControlWord, StatusWord;
  82. // X86_ONLY_API
  83. if (TargetMachine != IMAGE_FILE_MACHINE_I386) {
  84. dprintf("!npx is X86 Only API\n");
  85. return E_INVALIDARG;
  86. }
  87. Address = GetExpression(args);
  88. if ( InitTypeRead(
  89. Address,
  90. FLOATING_SAVE_AREA)) {
  91. dprintf("unable to read floating save area\n");
  92. return E_INVALIDARG;
  93. }
  94. ControlWord = (ULONG) ReadField(ControlWord);
  95. dprintf ("EIP.......: %08x ControlWord: %s-%s mask: %02x Cr0NpxState: %08x\n",
  96. (ULONG) ReadField(ErrorOffset),
  97. NpxPrecisionControl [(ControlWord >> 8) & 0x3],
  98. NpxRoundingControl [(ControlWord >> 10) & 0x3],
  99. ControlWord & 0x3f,
  100. (ULONG) ReadField(Cr0NpxState)
  101. );
  102. DumpNpxBits ( StatusWord = (ULONG) ReadField(StatusWord), s, NpxStatusBits);
  103. tos = (StatusWord >> 11) & 7,
  104. dprintf ("StatusWord: %04x TOS:%x %s (tagword: %04x)\n",
  105. StatusWord & 0xffff,
  106. tos,
  107. s,
  108. (ULONG) ReadField(TagWord) & 0xffff
  109. );
  110. GetFieldValue(Address, "FLOATING_SAVE_AREA", "RegisterArea", Reg);
  111. Stack = &Reg[0];
  112. Tag = (ULONG) ReadField(TagWord);
  113. for (i=0; i < 8; i++) {
  114. j = (tos + i) & 7;
  115. t = (Tag >> (j*2)) & 3;
  116. if (t != 3) {
  117. sprintf (s, "%x%c%s",
  118. j,
  119. j == tos ? '>' : '.',
  120. NpxTagWord [t]
  121. );
  122. DumpNpxExtended (s, Stack);
  123. }
  124. Stack += 10; // next stack location
  125. }
  126. dprintf ("\n");
  127. return S_OK;
  128. }
  129. void DumpNpxBits (
  130. ULONG Value,
  131. PUCHAR Str,
  132. PBITENCODING Bits
  133. )
  134. {
  135. BOOLEAN Flag;
  136. Flag = FALSE;
  137. *Str = 0;
  138. while (Bits->Mask) {
  139. if (Bits->Mask & Value) {
  140. if (Flag) {
  141. Str += sprintf (Str, ", %s", Bits->String);
  142. } else {
  143. Str += sprintf (Str, "%s", Bits->String);
  144. Flag = TRUE;
  145. }
  146. }
  147. Bits += 1;
  148. }
  149. }
  150. void
  151. DumpNpxULongLong (
  152. PUCHAR s,
  153. ULONGLONG l
  154. )
  155. {
  156. UCHAR c;
  157. UCHAR t[80], *p;
  158. if (l == 0) {
  159. *(s++)= '0';
  160. }
  161. p = t;
  162. while (l) {
  163. c = (UCHAR) ((ULONGLONG) l % 10);
  164. *(p++) = c + '0';
  165. l /= 10;
  166. }
  167. while (p != t) {
  168. *(s++) = *(--p);
  169. }
  170. *(s++) = 0;
  171. }
  172. void
  173. DumpNpxExtended (
  174. PUCHAR str,
  175. PUCHAR Value
  176. )
  177. {
  178. UCHAR *p, *o, c, out[100], t[100], ssig[100], ExponSign, SigSign;
  179. ULONG i, indent, mag, scale;
  180. LONG expon, delta;
  181. ULONGLONG sig;
  182. p = Value;
  183. c = 0;
  184. o = out+90;
  185. indent = strlen (str) + 1;
  186. dprintf ("%s ", str);
  187. //
  188. // Build string of bits
  189. //
  190. *(--o) = 0;
  191. while (c < 80) {
  192. *(--o) = (*p & 0x01) + '0';
  193. *p >>= 1;
  194. c += 1;
  195. if ((c % 8) == 0) {
  196. p += 1;
  197. }
  198. }
  199. p = o;
  200. //dprintf (" %s\n", o);
  201. //dprintf ("%*s", indent, "");
  202. //
  203. // print bit string seperated into fields
  204. //
  205. p = o;
  206. //dprintf ("%c %15.15s 1%c%s\n", p[0], p+1, '.', p+1+15);
  207. //dprintf ("%*s", indent, "");
  208. //
  209. // Pull out exponent
  210. //
  211. expon = 0;
  212. p = o + 1;
  213. for (i=0; i < 15; i++) {
  214. expon *= 2;
  215. if (p[i] == '1') {
  216. expon += 1;
  217. }
  218. }
  219. expon -= 16383; // take out exponent bias
  220. //
  221. // Build sig into big #
  222. //
  223. p = o + 1+15;
  224. scale = 0;
  225. for (i=0; p[i]; i++) {
  226. if (p[i] == '1') {
  227. scale = i+1;
  228. }
  229. }
  230. SigSign = p[i-1] == '0' ? '+' : '-';
  231. sig = 0;
  232. for (i=0; i < scale; i++) {
  233. sig <<= 1;
  234. if (p[i] == '1') {
  235. sig += 1;
  236. }
  237. }
  238. delta = expon - (scale - 1);
  239. //dprintf ("delta %d, expon %d, scale %d\n", delta, expon, scale);
  240. //
  241. // Print values of each field
  242. //
  243. DumpNpxULongLong (ssig, sig);
  244. p = o;
  245. ExponSign = p[0] == '0' ? '+' : '-';
  246. dprintf ("%c %15.15s (%+5d) %c%c%s\n",
  247. ExponSign,
  248. p + 1,
  249. expon,
  250. p[1+15], '.', p+1+15+1
  251. );
  252. dprintf ("%*s", indent, "");
  253. if (expon == -16383) {
  254. if (SigSign == '+') {
  255. dprintf ("Denormal\n\n");
  256. } else {
  257. dprintf ("Pseudodenormal\n\n");
  258. }
  259. return ;
  260. }
  261. if (expon == 1024) {
  262. if (scale == 1) {
  263. dprintf ("%c Infinity\n", ExponSign);
  264. } else {
  265. p = o + 1+15;
  266. c = 0;
  267. for (i=0; p[i]; i++) {
  268. if (p[i] == '1') {
  269. c++;
  270. }
  271. }
  272. if (SigSign == '+') {
  273. dprintf ("Signaling NaN\n");
  274. } else {
  275. if (c == 1) {
  276. dprintf ("Indefinite - quite NaN\n");
  277. } else {
  278. dprintf ("Quite NaN\n");
  279. }
  280. }
  281. }
  282. dprintf ("%*s", indent, "");
  283. }
  284. //dprintf ("%*s%c %15d %s (delta %d)\n",
  285. // indent, "", // indent
  286. // p[0] == '0' ? '+' : '-', // sign of exponent
  287. // expon, ssig,
  288. // delta
  289. // );
  290. //dprintf ("%*s", indent, "");
  291. t[0] = 0;
  292. p = t;
  293. if (delta < 0) {
  294. p += sprintf (p, "/ ");
  295. delta = -delta;
  296. } else if (delta > 0) {
  297. p += sprintf (p, "* ");
  298. }
  299. if (delta) {
  300. if (delta < 31) {
  301. p += sprintf (p, "%d", 1 << delta);
  302. } else {
  303. p += sprintf (p, "2^%d", delta);
  304. }
  305. }
  306. dprintf ("%s %s\n",
  307. ssig,
  308. t
  309. );
  310. }