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

/******************************Module*Header*******************************\
* Module Name: math.cxx
*
* Copyright (c) 2000 Microsoft Corporation
*
\**************************************************************************/
#include "precomp.hxx"
#include <limits.h>
HRESULT
GetAddressAndLength(
OutputControl &OutCtl,
PCSTR args,
PBOOL UnknownArg,
PDEBUG_VALUE Address,
PDEBUG_VALUE Length
)
{
HRESULT hr = S_OK;
BOOL ArgsOk = TRUE;
DEBUG_VALUE Addr;
DEBUG_VALUE Len;
ULONG RemIndex;
if (UnknownArg != NULL) *UnknownArg = FALSE;
if (Address != NULL) Address->Type = DEBUG_VALUE_INVALID;
if (Length != NULL) Length->Type = DEBUG_VALUE_INVALID;
Addr.Type = DEBUG_VALUE_INVALID;
Len.Type = DEBUG_VALUE_INVALID;
while (isspace(*args)) args++;
while (hr == S_OK && ArgsOk && *args != '\0')
{
if (*args == '-')
{
ArgsOk = FALSE;
do
{
args++;
} while (*args != '\0' && !isspace(*args));
}
else if (Addr.Type == DEBUG_VALUE_INVALID)
{
hr = OutCtl.Evaluate(args, DEBUG_VALUE_INT64, &Addr, &RemIndex);
if (hr == S_OK && Addr.I64 != 0)
{
args += RemIndex;
}
else
{
PCHAR pEOA;
CHAR EOAChar;
ArgsOk = FALSE;
if (hr == S_OK)
{
pEOA = (PCHAR)&args[RemIndex];
EOAChar = *pEOA;
*pEOA = '\0';
}
OutCtl.OutErr("Invalid Address: %s\n", args);
if (hr == S_OK)
{
*pEOA = EOAChar;
}
}
}
else if (Len.Type == DEBUG_VALUE_INVALID)
{
hr = OutCtl.Evaluate(args, DEBUG_VALUE_INT32, &Len, &RemIndex);
if (hr == S_OK && Len.I64 != 0)
{
args += RemIndex;
}
else
{
PCHAR pEOA;
CHAR EOAChar;
ArgsOk = FALSE;
if (hr == S_OK)
{
pEOA = (PCHAR)&args[RemIndex];
EOAChar = *pEOA;
*pEOA = '\0';
}
OutCtl.OutErr("Invalid Length: %s\n", args);
if (hr == S_OK)
{
*pEOA = EOAChar;
}
}
}
else
{
ArgsOk = FALSE;
}
while (isspace(*args)) args++;
}
if (hr == S_OK)
{
if (UnknownArg != NULL) *UnknownArg = !ArgsOk;
if (Address != NULL) *Address = Addr;
if (Length != NULL) *Length = Len;
}
return hr;
}
/******************************Public*Routine******************************\
*
* Routine Name:
*
* dfloat
*
\**************************************************************************/
DECLARE_API( dfloat )
{
dprintf("Extension 'dfloat' is not converted.\n");
#if ENABLE_OLD_EXTS // DOES NOT SUPPORT API64
ULONG Num;
ULONG Adr;
BOOL List=FALSE;
ULONG Value;
PARSE_ARGUMENTS(dfloat_help);
if(ntok<1) {
goto dfloat_help;
}
//find valid tokens - ignore the rest
tok_pos = parse_iFindSwitch(tokens, ntok, 'l');
if(tok_pos>=0) {
List = TRUE;
if((tok_pos+1)>=ntok) {
goto dfloat_help; //-l requires an argument and it can't be the last arg
}
tok_pos++;
Num = (LONG)GetExpression(tokens[tok_pos]);
}
//find first non-switch token not preceeded by a -l
tok_pos = -1;
do {
tok_pos = parse_FindNonSwitch(tokens, ntok, tok_pos+1);
} while ( (tok_pos!=-1)&&(parse_iIsSwitch(tokens, tok_pos-1, 'l')));
if(tok_pos==-1) {
goto dfloat_help;
}
Adr = (ULONG)GetExpression(tokens[tok_pos]);
if(List) {
for(ULONG i=0; i<Num; i++) {
move(Value, Adr);
dprintf("%lx: %lx %g\n", Adr, Value, *(float *)&Value);
Adr+=sizeof(ULONG);
}
} else {
dprintf("%g\n", *(float *)&Adr);
}
return;
dfloat_help:
dprintf("Usage: dfloat [-?] [-l num] Value");
dprintf("Displays the 32bit Value as an IEEE float\n");
dprintf("if the -l option is specified the Value is interpreted as a pointer\n"
"and an array of num 32bit values is displayed starting at the pointer\n");
#endif // DOES NOT SUPPORT API64
EXIT_API(S_OK);
}
/******************************Public*Routine******************************\
*
* Routine Name:
*
* efloat address [count]
*
* Routine Description:
*
* dumps an EFLOAT
*
* Arguments:
*
* address [count]
*
* Return Value:
*
* none
*
\**************************************************************************/
DECLARE_API( efloat )
{
#if 1
HRESULT hr = E_POINTER;
PDEBUG_SYMBOLS Symbols;
OutputControl OutCtl(Client);
DEBUG_VALUE Addr;
DEBUG_VALUE Length;
BOOL UnknownArg;
if (Client == NULL ||
(hr = Client->QueryInterface(__uuidof(IDebugSymbols),
(void **)&Symbols)) != S_OK)
{
return hr;
}
BEGIN_API( efloat );
hr = GetAddressAndLength(OutCtl, args, &UnknownArg, &Addr, &Length);
if (hr != S_OK || UnknownArg || Addr.Type != DEBUG_VALUE_INT64)
{
OutCtl.Output("Usage: efloat <EFLOAT Address> [Length]\n");
}
else
{
if (Length.Type != DEBUG_VALUE_INT32)
{
Length.I32 = 1;
}
OutputReader OutputBuffer;
OutputState OutState(Client, FALSE);
ULONG64 Module;
ULONG TypeId;
ULONG Size;
PSTR TypeDump;
if ((hr = OutState.Setup(0, &OutputBuffer)) == S_OK &&
(hr = GetTypeId(Client, "EFLOAT", &TypeId, &Module)) == S_OK &&
(hr = Symbols->GetTypeSize(Module, TypeId, &Size)) == S_OK)
{
if (Size == 0)
{
OutCtl.OutErr("EFLOAT type has 0 size.\n");
hr = S_FALSE;
}
else
{
ULONG64 LastAddr = Addr.I64 + Size*Length.I32;
ULONG BytesRead;
while (Addr.I64 < LastAddr &&
OutCtl.GetInterrupt() != S_OK)
{
OutCtl.Output("0x%p ", Addr.I64);
OutputBuffer.DiscardOutput();
hr = OutState.OutputTypeVirtual(Addr.I64,
Module,
TypeId,
DEBUG_OUTTYPE_NO_INDENT |
DEBUG_OUTTYPE_NO_OFFSET |
DEBUG_OUTTYPE_COMPACT_OUTPUT);
if (hr == S_OK &&
(hr = OutputBuffer.GetOutputCopy(&TypeDump)) == S_OK)
{
for (PSTR psz = TypeDump; *psz != '\0'; psz++)
{
if (*psz == '\n') *psz = ' ';
}
OutCtl.Output("%s", TypeDump);
OutputEFLOAT_S(Client, &OutCtl,
Module, TypeId,
TypeDump,
DEBUG_OUTTYPE_NO_INDENT |
DEBUG_OUTTYPE_NO_OFFSET |
DEBUG_OUTTYPE_COMPACT_OUTPUT,
NULL);
OutputBuffer.FreeOutputCopy(TypeDump);
}
else
{
OutCtl.Output("?");
}
OutCtl.Output("\n");
Addr.I64 += Size;
}
}
}
}
Symbols->Release();
return hr;
#else
INIT_API();
ULONG64 EFloatAddr;
ULONG EFloatSize;
int count;
char ach[64];
PARSE_POINTER(efloat_help);
tok_pos = parse_FindNonSwitch(tokens, ntok, tok_pos+1);
if (tok_pos==-1)
{
count=1;
}
else
{
if (sscanf(tokens[tok_pos], "%d", &count) == EOF ||
count <= 0)
{
goto efloat_help;
}
}
EFloatAddr = arg;
EFloatSize = GetTypeSize(GDIType(EFLOAT));
while (count > 0 && !CheckControlC())
{
for (ULONG offset = 0; offset < EFloatSize; offset+=sizeof(DWORD))
{
ULONG64 Value;
GetFieldValue(EFloatAddr+offset, "DWORD", NULL, Value);
sprintf(ach, " %%0%dx", 2*min(sizeof(DWORD), EFloatSize-offset));
dprintf(ach, (DWORD)Value);
}
dprintf(" = ");
sprintEFLOAT(Client, ach, EFloatAddr );
dprintf("%s\n", ach);
EFloatAddr += EFloatSize;
count--;
}
EXIT_API(S_OK);
efloat_help:
dprintf("Usage: efloat [-?] address [count]\n");
EXIT_API(S_OK);
#endif
}
/******************************Public*Routine******************************\
*
* Routine Name:
*
* sprintEFLOAT
*
\**************************************************************************/
#if ENABLE_OLD_EXTS // DOES NOT SUPPORT API64
// Here for reference
int sprintEFLOAT_Old(char *ach, EFLOAT& ef)
{
EFLOATEXT efInt;
EFLOATEXT efFrac;
LONG lInt, lFrac;
char chSign;
efFrac = ef;
if (efFrac.bIsNegative()) {
efFrac.vNegate();
chSign = '-';
}
else
chSign = '+';
efFrac.bEfToLTruncate(lInt);
efInt = lInt;
efFrac -= efInt;
efFrac *= (LONG) 1000000;
efFrac.bEfToLTruncate(lFrac);
return(sprintf(ach,"%c%d.%06d", chSign, lInt, lFrac));
}
#endif // DOES NOT SUPPORT API64
int sprintEFLOAT_I386(PDEBUG_CLIENT Client, char *ach, ULONG64 offEF)
{
ULONG64 lMant;
LONG lExp;
ULONG lInt, lFrac;
ULONG64 fx3232;
ULONG error;
char chSign = '+';
if (error = (ULONG)InitTypeRead(offEF, win32k!EFLOAT_S))
{
dprintf(" Unable to get contents of EFLOAT\n");
dprintf(" (InitTypeRead returned %s)\n", pszWinDbgError(error));
return 0;
}
lMant = ReadField(lMant);
lExp = (LONG)ReadField(lExp);
if (lMant & 0x80000000) // EFLOAT::bIsNegative
{
// EFLOAT::vNegate()
if ((lMant & 0x7FFFFFFF) == 0)
{
lMant = 0x40000000;
lExp += 1;
}
else
{
lMant = - (LONG)lMant;
}
chSign = '-';
}
// EFLOAT::bEfToLTruncate
if (lExp > 32)
return(sprintf(ach,"Overflow: exponent %d > 32", lExp));
if (lExp < -32)
return(sprintf(ach,"%c0.000000", chSign));
if (lExp < 0)
{
fx3232 = lMant >> -lExp;
}
else
{
fx3232 = lMant << lExp;
}
lInt = (ULONG) (fx3232 >> 32);
lFrac = (ULONG) ( ( (fx3232 & 0xFFFFFFFF) * 1000000 + 0x80000000) >> 32);
if (lFrac > 1000000)
{
return(sprintf(ach,"Bug in sprintEFLOAT_I386: fraction above 1000000"));
}
if (lFrac == 1000000)
{
lInt++;
lFrac = 0;
}
return(sprintf(ach,"%c%u.%06d", chSign, lInt, lFrac));
}
int sprintEFLOAT_IA64(PDEBUG_CLIENT Client, char *ach, ULONG64 offEF)
{
return(sprintf(ach,"EFLOAT parser needs written for IA64"));
}
int sprintEFLOAT(PDEBUG_CLIENT Client, char *ach, ULONG64 offEF)
{
switch (TargetMachine)
{
case IMAGE_FILE_MACHINE_I386:
return(sprintEFLOAT_I386(Client, ach, offEF));
case IMAGE_FILE_MACHINE_IA64:
return(sprintEFLOAT_IA64(Client, ach, offEF));
default:
return(sprintf(ach,"EFLOAT parser needs written for machine type %X", TargetMachine));
}
}
/**************************************************************************\
*
* Routine Name:
*
* OutputEFLOAT_S
*
* Routine Description:
*
* Outputs an EFLOAT_S
*
\**************************************************************************/
HRESULT
OutputEFLOAT_S(
PDEBUG_CLIENT Client,
OutputControl *OutCtl,
ULONG64 Module,
ULONG TypeId,
PSTR Buffer,
ULONG Flags,
PULONG BufferUsed
)
{
HRESULT hr = S_FALSE;
TypeOutputParser Parser(Client);
DEBUG_VALUE Mant, Exp;
if (Parser.LookFor(&Mant, "lMant", DEBUG_VALUE_INT32) == S_OK &&
Parser.Parse(Buffer, NULL) == S_OK &&
Parser.Complete() == S_OK &&
Parser.LookFor(&Exp, "lExp", DEBUG_VALUE_INT32) == S_OK &&
Parser.Parse(Buffer, NULL) == S_OK &&
Parser.Complete() == S_OK)
{
LONG lMant = Mant.I32;
LONG lExp = Exp.I32;
ULONG lInt, lFrac;
ULONG64 fx3232;
char chSign = '+';
if (lMant < 0) // EFLOAT::bIsNegative
{
// EFLOAT::vNegate()
if (lMant == LONG_MIN)
{
lMant = -(LONG_MIN/2);
lExp += 1;
}
else
{
lMant = -lMant;
}
chSign = '-';
}
// EFLOAT::bEfToLTruncate
if (lExp > 32)
return OutCtl->Output("Overflow: exponent %d > 32", lExp);
if (lExp < -32)
return OutCtl->Output("%c0.000000", chSign);
fx3232 = (lExp < 0) ? (((ULONG64) lMant) >> -lExp) : (((ULONG64) lMant) << lExp);
lInt = (ULONG) (fx3232 >> 32);
lFrac = (ULONG) ( ( (fx3232 & 0xFFFFFFFF) * 1000000 + 0x80000000) >> 32);
if (lFrac > 1000000)
{
OutCtl->Output(DEBUG_OUTPUT_NORMAL | DEBUG_OUTPUT_ERROR,
"Bug in sprintEFLOAT_I386: fraction above 1000000");
}
else
{
if (lFrac == 1000000)
{
lInt++;
lFrac = 0;
}
hr = OutCtl->Output("%c%u.%06d", chSign, lInt, lFrac);
}
}
else
{
hr = OutCtl->Output("%s", Buffer);
}
return hr;
}
/**************************************************************************\
*
* Routine Name:
*
* OutputFLOATL
*
* Routine Description:
*
* Outputs a FLOAT from a DEBUG_VALUE regardless of Type
*
\**************************************************************************/
HRESULT
OutputFLOATL(
OutputControl *OutCtl,
PDEBUG_CLIENT Client,
PDEBUG_VALUE Value
)
{
if (OutCtl == NULL || Value == NULL)
{
return E_INVALIDARG;
}
return OutCtl->Output("%#g", (double) Value->F32);
}
/******************************Public*Routine******************************\
* FLOATL
*
* dumps an array of FLOAT's
*
* History:
* Wed 24-Apr-1996 10:00:27 by Kirk Olynyk [kirko]
* Wrote it.
\**************************************************************************/
DECLARE_API( floatl )
{
HRESULT hr = E_POINTER;
PDEBUG_SYMBOLS Symbols;
OutputControl OutCtl(Client);
DEBUG_VALUE Addr;
DEBUG_VALUE Length;
BOOL UnknownArg;
if (Client == NULL ||
(hr = Client->QueryInterface(__uuidof(IDebugSymbols),
(void **)&Symbols)) != S_OK)
{
return hr;
}
BEGIN_API( floatl );
hr = GetAddressAndLength(OutCtl, args, &UnknownArg, &Addr, &Length);
if (hr != S_OK || UnknownArg || Addr.Type != DEBUG_VALUE_INT64)
{
OutCtl.Output("Usage: floatl <FLOATL Address> [Count]\n");
}
else
{
if (Length.Type != DEBUG_VALUE_INT32)
{
Length.I32 = 1;
}
ULONG64 Module;
ULONG TypeId;
ULONG Size;
DEBUG_VALUE Value;
if ((hr = GetTypeId(Client, "FLOATL", &TypeId, &Module)) == S_OK &&
(hr = Symbols->GetTypeSize(Module, TypeId, &Size)) == S_OK)
{
if (Size == 0 || Size > sizeof(Value.RawBytes))
{
OutCtl.OutErr("FLOATL type has unexpected size.\n");
hr = S_FALSE;
}
else
{
ULONG64 LastAddr = Addr.I64 + Size*Length.I32;
ULONG BytesRead;
while (Addr.I64 < LastAddr &&
OutCtl.GetInterrupt() != S_OK)
{
OutCtl.Output("0x%p ", Addr.I64);
if (Symbols->ReadTypedDataVirtual(Addr.I64,
Type_Module.Base,
TypeId,
&Value,
Size,
&BytesRead) == S_OK &&
BytesRead == Size)
{
OutputFLOATL(&OutCtl, Client, &Value);
}
else
{
OutCtl.Output("?");
}
OutCtl.Output("\n");
Addr.I64 += Size;
}
}
}
}
Symbols->Release();
return hr;
}
/******************************Public*Routine******************************\
*
* Routine Name:
*
* vDumpMATRIX
*
\**************************************************************************/
void vDumpMATRIX(PDEBUG_CLIENT Client, ULONG64 offMX)
{
DumpType(Client, "MATRIX", offMX);
}
/******************************Public*Routine******************************\
* MATRIX
*
\**************************************************************************/
DECLARE_API( matrix )
{
return ExtDumpType(Client, "matrix", "MATRIX", args);
}
/******************************Public*Routine******************************\
*
* Routine Name:
*
* mx
*
\**************************************************************************/
DECLARE_API( mx )
{
return ExtDumpType(Client, "mx", "MATRIX", args);
}