Leaked source code of windows server 2003
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.

730 lines
18 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: math.cxx
  3. *
  4. * Copyright (c) 2000 Microsoft Corporation
  5. *
  6. \**************************************************************************/
  7. #include "precomp.hxx"
  8. #include <limits.h>
  9. HRESULT
  10. GetAddressAndLength(
  11. OutputControl &OutCtl,
  12. PCSTR args,
  13. PBOOL UnknownArg,
  14. PDEBUG_VALUE Address,
  15. PDEBUG_VALUE Length
  16. )
  17. {
  18. HRESULT hr = S_OK;
  19. BOOL ArgsOk = TRUE;
  20. DEBUG_VALUE Addr;
  21. DEBUG_VALUE Len;
  22. ULONG RemIndex;
  23. if (UnknownArg != NULL) *UnknownArg = FALSE;
  24. if (Address != NULL) Address->Type = DEBUG_VALUE_INVALID;
  25. if (Length != NULL) Length->Type = DEBUG_VALUE_INVALID;
  26. Addr.Type = DEBUG_VALUE_INVALID;
  27. Len.Type = DEBUG_VALUE_INVALID;
  28. while (isspace(*args)) args++;
  29. while (hr == S_OK && ArgsOk && *args != '\0')
  30. {
  31. if (*args == '-')
  32. {
  33. ArgsOk = FALSE;
  34. do
  35. {
  36. args++;
  37. } while (*args != '\0' && !isspace(*args));
  38. }
  39. else if (Addr.Type == DEBUG_VALUE_INVALID)
  40. {
  41. hr = OutCtl.Evaluate(args, DEBUG_VALUE_INT64, &Addr, &RemIndex);
  42. if (hr == S_OK && Addr.I64 != 0)
  43. {
  44. args += RemIndex;
  45. }
  46. else
  47. {
  48. PCHAR pEOA;
  49. CHAR EOAChar;
  50. ArgsOk = FALSE;
  51. if (hr == S_OK)
  52. {
  53. pEOA = (PCHAR)&args[RemIndex];
  54. EOAChar = *pEOA;
  55. *pEOA = '\0';
  56. }
  57. OutCtl.OutErr("Invalid Address: %s\n", args);
  58. if (hr == S_OK)
  59. {
  60. *pEOA = EOAChar;
  61. }
  62. }
  63. }
  64. else if (Len.Type == DEBUG_VALUE_INVALID)
  65. {
  66. hr = OutCtl.Evaluate(args, DEBUG_VALUE_INT32, &Len, &RemIndex);
  67. if (hr == S_OK && Len.I64 != 0)
  68. {
  69. args += RemIndex;
  70. }
  71. else
  72. {
  73. PCHAR pEOA;
  74. CHAR EOAChar;
  75. ArgsOk = FALSE;
  76. if (hr == S_OK)
  77. {
  78. pEOA = (PCHAR)&args[RemIndex];
  79. EOAChar = *pEOA;
  80. *pEOA = '\0';
  81. }
  82. OutCtl.OutErr("Invalid Length: %s\n", args);
  83. if (hr == S_OK)
  84. {
  85. *pEOA = EOAChar;
  86. }
  87. }
  88. }
  89. else
  90. {
  91. ArgsOk = FALSE;
  92. }
  93. while (isspace(*args)) args++;
  94. }
  95. if (hr == S_OK)
  96. {
  97. if (UnknownArg != NULL) *UnknownArg = !ArgsOk;
  98. if (Address != NULL) *Address = Addr;
  99. if (Length != NULL) *Length = Len;
  100. }
  101. return hr;
  102. }
  103. /******************************Public*Routine******************************\
  104. *
  105. * Routine Name:
  106. *
  107. * dfloat
  108. *
  109. \**************************************************************************/
  110. DECLARE_API( dfloat )
  111. {
  112. dprintf("Extension 'dfloat' is not converted.\n");
  113. #if ENABLE_OLD_EXTS // DOES NOT SUPPORT API64
  114. ULONG Num;
  115. ULONG Adr;
  116. BOOL List=FALSE;
  117. ULONG Value;
  118. PARSE_ARGUMENTS(dfloat_help);
  119. if(ntok<1) {
  120. goto dfloat_help;
  121. }
  122. //find valid tokens - ignore the rest
  123. tok_pos = parse_iFindSwitch(tokens, ntok, 'l');
  124. if(tok_pos>=0) {
  125. List = TRUE;
  126. if((tok_pos+1)>=ntok) {
  127. goto dfloat_help; //-l requires an argument and it can't be the last arg
  128. }
  129. tok_pos++;
  130. Num = (LONG)GetExpression(tokens[tok_pos]);
  131. }
  132. //find first non-switch token not preceeded by a -l
  133. tok_pos = -1;
  134. do {
  135. tok_pos = parse_FindNonSwitch(tokens, ntok, tok_pos+1);
  136. } while ( (tok_pos!=-1)&&(parse_iIsSwitch(tokens, tok_pos-1, 'l')));
  137. if(tok_pos==-1) {
  138. goto dfloat_help;
  139. }
  140. Adr = (ULONG)GetExpression(tokens[tok_pos]);
  141. if(List) {
  142. for(ULONG i=0; i<Num; i++) {
  143. move(Value, Adr);
  144. dprintf("%lx: %lx %g\n", Adr, Value, *(float *)&Value);
  145. Adr+=sizeof(ULONG);
  146. }
  147. } else {
  148. dprintf("%g\n", *(float *)&Adr);
  149. }
  150. return;
  151. dfloat_help:
  152. dprintf("Usage: dfloat [-?] [-l num] Value");
  153. dprintf("Displays the 32bit Value as an IEEE float\n");
  154. dprintf("if the -l option is specified the Value is interpreted as a pointer\n"
  155. "and an array of num 32bit values is displayed starting at the pointer\n");
  156. #endif // DOES NOT SUPPORT API64
  157. EXIT_API(S_OK);
  158. }
  159. /******************************Public*Routine******************************\
  160. *
  161. * Routine Name:
  162. *
  163. * efloat address [count]
  164. *
  165. * Routine Description:
  166. *
  167. * dumps an EFLOAT
  168. *
  169. * Arguments:
  170. *
  171. * address [count]
  172. *
  173. * Return Value:
  174. *
  175. * none
  176. *
  177. \**************************************************************************/
  178. DECLARE_API( efloat )
  179. {
  180. #if 1
  181. HRESULT hr = E_POINTER;
  182. PDEBUG_SYMBOLS Symbols;
  183. OutputControl OutCtl(Client);
  184. DEBUG_VALUE Addr;
  185. DEBUG_VALUE Length;
  186. BOOL UnknownArg;
  187. if (Client == NULL ||
  188. (hr = Client->QueryInterface(__uuidof(IDebugSymbols),
  189. (void **)&Symbols)) != S_OK)
  190. {
  191. return hr;
  192. }
  193. BEGIN_API( efloat );
  194. hr = GetAddressAndLength(OutCtl, args, &UnknownArg, &Addr, &Length);
  195. if (hr != S_OK || UnknownArg || Addr.Type != DEBUG_VALUE_INT64)
  196. {
  197. OutCtl.Output("Usage: efloat <EFLOAT Address> [Length]\n");
  198. }
  199. else
  200. {
  201. if (Length.Type != DEBUG_VALUE_INT32)
  202. {
  203. Length.I32 = 1;
  204. }
  205. OutputReader OutputBuffer;
  206. OutputState OutState(Client, FALSE);
  207. ULONG64 Module;
  208. ULONG TypeId;
  209. ULONG Size;
  210. PSTR TypeDump;
  211. if ((hr = OutState.Setup(0, &OutputBuffer)) == S_OK &&
  212. (hr = GetTypeId(Client, "EFLOAT", &TypeId, &Module)) == S_OK &&
  213. (hr = Symbols->GetTypeSize(Module, TypeId, &Size)) == S_OK)
  214. {
  215. if (Size == 0)
  216. {
  217. OutCtl.OutErr("EFLOAT type has 0 size.\n");
  218. hr = S_FALSE;
  219. }
  220. else
  221. {
  222. ULONG64 LastAddr = Addr.I64 + Size*Length.I32;
  223. ULONG BytesRead;
  224. while (Addr.I64 < LastAddr &&
  225. OutCtl.GetInterrupt() != S_OK)
  226. {
  227. OutCtl.Output("0x%p ", Addr.I64);
  228. OutputBuffer.DiscardOutput();
  229. hr = OutState.OutputTypeVirtual(Addr.I64,
  230. Module,
  231. TypeId,
  232. DEBUG_OUTTYPE_NO_INDENT |
  233. DEBUG_OUTTYPE_NO_OFFSET |
  234. DEBUG_OUTTYPE_COMPACT_OUTPUT);
  235. if (hr == S_OK &&
  236. (hr = OutputBuffer.GetOutputCopy(&TypeDump)) == S_OK)
  237. {
  238. for (PSTR psz = TypeDump; *psz != '\0'; psz++)
  239. {
  240. if (*psz == '\n') *psz = ' ';
  241. }
  242. OutCtl.Output("%s", TypeDump);
  243. OutputEFLOAT_S(Client, &OutCtl,
  244. Module, TypeId,
  245. TypeDump,
  246. DEBUG_OUTTYPE_NO_INDENT |
  247. DEBUG_OUTTYPE_NO_OFFSET |
  248. DEBUG_OUTTYPE_COMPACT_OUTPUT,
  249. NULL);
  250. OutputBuffer.FreeOutputCopy(TypeDump);
  251. }
  252. else
  253. {
  254. OutCtl.Output("?");
  255. }
  256. OutCtl.Output("\n");
  257. Addr.I64 += Size;
  258. }
  259. }
  260. }
  261. }
  262. Symbols->Release();
  263. return hr;
  264. #else
  265. INIT_API();
  266. ULONG64 EFloatAddr;
  267. ULONG EFloatSize;
  268. int count;
  269. char ach[64];
  270. PARSE_POINTER(efloat_help);
  271. tok_pos = parse_FindNonSwitch(tokens, ntok, tok_pos+1);
  272. if (tok_pos==-1)
  273. {
  274. count=1;
  275. }
  276. else
  277. {
  278. if (sscanf(tokens[tok_pos], "%d", &count) == EOF ||
  279. count <= 0)
  280. {
  281. goto efloat_help;
  282. }
  283. }
  284. EFloatAddr = arg;
  285. EFloatSize = GetTypeSize(GDIType(EFLOAT));
  286. while (count > 0 && !CheckControlC())
  287. {
  288. for (ULONG offset = 0; offset < EFloatSize; offset+=sizeof(DWORD))
  289. {
  290. ULONG64 Value;
  291. GetFieldValue(EFloatAddr+offset, "DWORD", NULL, Value);
  292. sprintf(ach, " %%0%dx", 2*min(sizeof(DWORD), EFloatSize-offset));
  293. dprintf(ach, (DWORD)Value);
  294. }
  295. dprintf(" = ");
  296. sprintEFLOAT(Client, ach, EFloatAddr );
  297. dprintf("%s\n", ach);
  298. EFloatAddr += EFloatSize;
  299. count--;
  300. }
  301. EXIT_API(S_OK);
  302. efloat_help:
  303. dprintf("Usage: efloat [-?] address [count]\n");
  304. EXIT_API(S_OK);
  305. #endif
  306. }
  307. /******************************Public*Routine******************************\
  308. *
  309. * Routine Name:
  310. *
  311. * sprintEFLOAT
  312. *
  313. \**************************************************************************/
  314. #if ENABLE_OLD_EXTS // DOES NOT SUPPORT API64
  315. // Here for reference
  316. int sprintEFLOAT_Old(char *ach, EFLOAT& ef)
  317. {
  318. EFLOATEXT efInt;
  319. EFLOATEXT efFrac;
  320. LONG lInt, lFrac;
  321. char chSign;
  322. efFrac = ef;
  323. if (efFrac.bIsNegative()) {
  324. efFrac.vNegate();
  325. chSign = '-';
  326. }
  327. else
  328. chSign = '+';
  329. efFrac.bEfToLTruncate(lInt);
  330. efInt = lInt;
  331. efFrac -= efInt;
  332. efFrac *= (LONG) 1000000;
  333. efFrac.bEfToLTruncate(lFrac);
  334. return(sprintf(ach,"%c%d.%06d", chSign, lInt, lFrac));
  335. }
  336. #endif // DOES NOT SUPPORT API64
  337. int sprintEFLOAT_I386(PDEBUG_CLIENT Client, char *ach, ULONG64 offEF)
  338. {
  339. ULONG64 lMant;
  340. LONG lExp;
  341. ULONG lInt, lFrac;
  342. ULONG64 fx3232;
  343. ULONG error;
  344. char chSign = '+';
  345. if (error = (ULONG)InitTypeRead(offEF, win32k!EFLOAT_S))
  346. {
  347. dprintf(" Unable to get contents of EFLOAT\n");
  348. dprintf(" (InitTypeRead returned %s)\n", pszWinDbgError(error));
  349. return 0;
  350. }
  351. lMant = ReadField(lMant);
  352. lExp = (LONG)ReadField(lExp);
  353. if (lMant & 0x80000000) // EFLOAT::bIsNegative
  354. {
  355. // EFLOAT::vNegate()
  356. if ((lMant & 0x7FFFFFFF) == 0)
  357. {
  358. lMant = 0x40000000;
  359. lExp += 1;
  360. }
  361. else
  362. {
  363. lMant = - (LONG)lMant;
  364. }
  365. chSign = '-';
  366. }
  367. // EFLOAT::bEfToLTruncate
  368. if (lExp > 32)
  369. return(sprintf(ach,"Overflow: exponent %d > 32", lExp));
  370. if (lExp < -32)
  371. return(sprintf(ach,"%c0.000000", chSign));
  372. if (lExp < 0)
  373. {
  374. fx3232 = lMant >> -lExp;
  375. }
  376. else
  377. {
  378. fx3232 = lMant << lExp;
  379. }
  380. lInt = (ULONG) (fx3232 >> 32);
  381. lFrac = (ULONG) ( ( (fx3232 & 0xFFFFFFFF) * 1000000 + 0x80000000) >> 32);
  382. if (lFrac > 1000000)
  383. {
  384. return(sprintf(ach,"Bug in sprintEFLOAT_I386: fraction above 1000000"));
  385. }
  386. if (lFrac == 1000000)
  387. {
  388. lInt++;
  389. lFrac = 0;
  390. }
  391. return(sprintf(ach,"%c%u.%06d", chSign, lInt, lFrac));
  392. }
  393. int sprintEFLOAT_IA64(PDEBUG_CLIENT Client, char *ach, ULONG64 offEF)
  394. {
  395. return(sprintf(ach,"EFLOAT parser needs written for IA64"));
  396. }
  397. int sprintEFLOAT(PDEBUG_CLIENT Client, char *ach, ULONG64 offEF)
  398. {
  399. switch (TargetMachine)
  400. {
  401. case IMAGE_FILE_MACHINE_I386:
  402. return(sprintEFLOAT_I386(Client, ach, offEF));
  403. case IMAGE_FILE_MACHINE_IA64:
  404. return(sprintEFLOAT_IA64(Client, ach, offEF));
  405. default:
  406. return(sprintf(ach,"EFLOAT parser needs written for machine type %X", TargetMachine));
  407. }
  408. }
  409. /**************************************************************************\
  410. *
  411. * Routine Name:
  412. *
  413. * OutputEFLOAT_S
  414. *
  415. * Routine Description:
  416. *
  417. * Outputs an EFLOAT_S
  418. *
  419. \**************************************************************************/
  420. HRESULT
  421. OutputEFLOAT_S(
  422. PDEBUG_CLIENT Client,
  423. OutputControl *OutCtl,
  424. ULONG64 Module,
  425. ULONG TypeId,
  426. PSTR Buffer,
  427. ULONG Flags,
  428. PULONG BufferUsed
  429. )
  430. {
  431. HRESULT hr = S_FALSE;
  432. TypeOutputParser Parser(Client);
  433. DEBUG_VALUE Mant, Exp;
  434. if (Parser.LookFor(&Mant, "lMant", DEBUG_VALUE_INT32) == S_OK &&
  435. Parser.Parse(Buffer, NULL) == S_OK &&
  436. Parser.Complete() == S_OK &&
  437. Parser.LookFor(&Exp, "lExp", DEBUG_VALUE_INT32) == S_OK &&
  438. Parser.Parse(Buffer, NULL) == S_OK &&
  439. Parser.Complete() == S_OK)
  440. {
  441. LONG lMant = Mant.I32;
  442. LONG lExp = Exp.I32;
  443. ULONG lInt, lFrac;
  444. ULONG64 fx3232;
  445. char chSign = '+';
  446. if (lMant < 0) // EFLOAT::bIsNegative
  447. {
  448. // EFLOAT::vNegate()
  449. if (lMant == LONG_MIN)
  450. {
  451. lMant = -(LONG_MIN/2);
  452. lExp += 1;
  453. }
  454. else
  455. {
  456. lMant = -lMant;
  457. }
  458. chSign = '-';
  459. }
  460. // EFLOAT::bEfToLTruncate
  461. if (lExp > 32)
  462. return OutCtl->Output("Overflow: exponent %d > 32", lExp);
  463. if (lExp < -32)
  464. return OutCtl->Output("%c0.000000", chSign);
  465. fx3232 = (lExp < 0) ? (((ULONG64) lMant) >> -lExp) : (((ULONG64) lMant) << lExp);
  466. lInt = (ULONG) (fx3232 >> 32);
  467. lFrac = (ULONG) ( ( (fx3232 & 0xFFFFFFFF) * 1000000 + 0x80000000) >> 32);
  468. if (lFrac > 1000000)
  469. {
  470. OutCtl->Output(DEBUG_OUTPUT_NORMAL | DEBUG_OUTPUT_ERROR,
  471. "Bug in sprintEFLOAT_I386: fraction above 1000000");
  472. }
  473. else
  474. {
  475. if (lFrac == 1000000)
  476. {
  477. lInt++;
  478. lFrac = 0;
  479. }
  480. hr = OutCtl->Output("%c%u.%06d", chSign, lInt, lFrac);
  481. }
  482. }
  483. else
  484. {
  485. hr = OutCtl->Output("%s", Buffer);
  486. }
  487. return hr;
  488. }
  489. /**************************************************************************\
  490. *
  491. * Routine Name:
  492. *
  493. * OutputFLOATL
  494. *
  495. * Routine Description:
  496. *
  497. * Outputs a FLOAT from a DEBUG_VALUE regardless of Type
  498. *
  499. \**************************************************************************/
  500. HRESULT
  501. OutputFLOATL(
  502. OutputControl *OutCtl,
  503. PDEBUG_CLIENT Client,
  504. PDEBUG_VALUE Value
  505. )
  506. {
  507. if (OutCtl == NULL || Value == NULL)
  508. {
  509. return E_INVALIDARG;
  510. }
  511. return OutCtl->Output("%#g", (double) Value->F32);
  512. }
  513. /******************************Public*Routine******************************\
  514. * FLOATL
  515. *
  516. * dumps an array of FLOAT's
  517. *
  518. * History:
  519. * Wed 24-Apr-1996 10:00:27 by Kirk Olynyk [kirko]
  520. * Wrote it.
  521. \**************************************************************************/
  522. DECLARE_API( floatl )
  523. {
  524. HRESULT hr = E_POINTER;
  525. PDEBUG_SYMBOLS Symbols;
  526. OutputControl OutCtl(Client);
  527. DEBUG_VALUE Addr;
  528. DEBUG_VALUE Length;
  529. BOOL UnknownArg;
  530. if (Client == NULL ||
  531. (hr = Client->QueryInterface(__uuidof(IDebugSymbols),
  532. (void **)&Symbols)) != S_OK)
  533. {
  534. return hr;
  535. }
  536. BEGIN_API( floatl );
  537. hr = GetAddressAndLength(OutCtl, args, &UnknownArg, &Addr, &Length);
  538. if (hr != S_OK || UnknownArg || Addr.Type != DEBUG_VALUE_INT64)
  539. {
  540. OutCtl.Output("Usage: floatl <FLOATL Address> [Count]\n");
  541. }
  542. else
  543. {
  544. if (Length.Type != DEBUG_VALUE_INT32)
  545. {
  546. Length.I32 = 1;
  547. }
  548. ULONG64 Module;
  549. ULONG TypeId;
  550. ULONG Size;
  551. DEBUG_VALUE Value;
  552. if ((hr = GetTypeId(Client, "FLOATL", &TypeId, &Module)) == S_OK &&
  553. (hr = Symbols->GetTypeSize(Module, TypeId, &Size)) == S_OK)
  554. {
  555. if (Size == 0 || Size > sizeof(Value.RawBytes))
  556. {
  557. OutCtl.OutErr("FLOATL type has unexpected size.\n");
  558. hr = S_FALSE;
  559. }
  560. else
  561. {
  562. ULONG64 LastAddr = Addr.I64 + Size*Length.I32;
  563. ULONG BytesRead;
  564. while (Addr.I64 < LastAddr &&
  565. OutCtl.GetInterrupt() != S_OK)
  566. {
  567. OutCtl.Output("0x%p ", Addr.I64);
  568. if (Symbols->ReadTypedDataVirtual(Addr.I64,
  569. Type_Module.Base,
  570. TypeId,
  571. &Value,
  572. Size,
  573. &BytesRead) == S_OK &&
  574. BytesRead == Size)
  575. {
  576. OutputFLOATL(&OutCtl, Client, &Value);
  577. }
  578. else
  579. {
  580. OutCtl.Output("?");
  581. }
  582. OutCtl.Output("\n");
  583. Addr.I64 += Size;
  584. }
  585. }
  586. }
  587. }
  588. Symbols->Release();
  589. return hr;
  590. }
  591. /******************************Public*Routine******************************\
  592. *
  593. * Routine Name:
  594. *
  595. * vDumpMATRIX
  596. *
  597. \**************************************************************************/
  598. void vDumpMATRIX(PDEBUG_CLIENT Client, ULONG64 offMX)
  599. {
  600. DumpType(Client, "MATRIX", offMX);
  601. }
  602. /******************************Public*Routine******************************\
  603. * MATRIX
  604. *
  605. \**************************************************************************/
  606. DECLARE_API( matrix )
  607. {
  608. return ExtDumpType(Client, "matrix", "MATRIX", args);
  609. }
  610. /******************************Public*Routine******************************\
  611. *
  612. * Routine Name:
  613. *
  614. * mx
  615. *
  616. \**************************************************************************/
  617. DECLARE_API( mx )
  618. {
  619. return ExtDumpType(Client, "mx", "MATRIX", args);
  620. }