Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

559 lines
13 KiB

#include "insignia.h"
#include "host_def.h"
/*
* SoftPC Revision 3.0
*
* Title : Trace function
*
* Description : This function will output a trace to the log device.
* The device is set up in the main function module. Options
* are provided to VPC memory/register data.
*
* Author : Henry Nash
*
* Notes : None
*
* SccsID : @(#)trace.c 1.36 06/02/95
*
* (c)Copyright Insignia Solutions Ltd., 1990-1994. All rights reserved.
*/
#ifdef SEGMENTATION
/*
* The following #include specifies the code segment into which this
* module will by placed by the MPW C compiler on the Mac II running
* MultiFinder.
*/
#include "SOFTPC_ERROR.seg"
#endif
/*
* O/S include files.
*/
#include <stdlib.h>
#include <stdio.h>
#include TypesH
/*
* SoftPC include files
*/
#include "xt.h"
#define CPU_PRIVATE /* Request the CPU private interface as well */
#include CpuH
#undef CPU_PRIVATE
#include "sas.h"
#include "gvi.h"
#include "trace.h"
#ifdef CPU_40_STYLE
FORWARD CHAR *host_get_287_reg_as_string IPT2(IU32, reg_num, BOOL, in_hex);
FORWARD IU32 get_287_tag_word IPT0();
FORWARD IU32 get_287_control_word IPT0();
FORWARD IU32 get_287_status_word IPT0();
FORWARD IU32 get_287_sp IPT0();
#endif
FILE *trace_file;
#ifndef PROD
#ifdef SPC386
#include "decode.h"
#define DASM_INTERNAL
#include <dasm.h>
#else /* SPC386 */
IMPORT word dasm IPT5(char *, i_output_stream, word, i_atomicsegover,
word, i_segreg, word, i_segoff, int, i_nInstr);
#endif /* SPC386 */
int disk_trace = 0; /* value of 1 indicates temp disk trace */
static int trace_state = 0;
#endif /* nPROD */
static int trace_start = 0;
GLOBAL IU32 io_verbose = 0;
GLOBAL IU32 sub_io_verbose = 0;
#ifdef RDCHK
#include "egacpu.h"
void get_lar()
{
#ifndef PROD
printf( "There's no such thing as the last_address_read anymore.\n" );
printf( "Perhaps you'd like the latches instead: %x\n", getVideolatches() );
#endif
}
#endif
#if !defined(PROD) && defined(SPC386)
LOCAL IS32 read_from_la IFN1(LIN_ADDR, addr)
{
return (IS32)sas_hw_at(addr);
}
/*
********************* dump386Registers **********************************
*
* This functions dumps the CPU registers to the indicated file, taking
* account of code and stack segment sizes.
*/
LOCAL void
dump386Registers IFN2(FILE *, fp, IUM32, dump_info)
{
IBOOL is32BitCS = FALSE;
IBOOL is32BitSS = FALSE;
IU32 offset;
IUM32 i;
sys_addr desc_addr; /* the descriptor's address */
IU16 temp;
if (getPE() && !getVM()) {
/*
* Is it a 16 or 32 bit code segment?
*/
is32BitCS = CsIsBig(getCS());
/*
* Is it a 16 or 32 bit stack segment? (i.e do we use ESP or SP)
* (The test is the same as for a big CS!)
*/
is32BitSS = CsIsBig(getSS());
}
if (dump_info & DUMP_REG)
{
if (is32BitSS || is32BitCS
|| (getEAX() & 0xFFFF0000)
|| (getEBX() & 0xFFFF0000)
|| (getECX() & 0xFFFF0000)
|| (getEDX() & 0xFFFF0000)
|| (getEIP() & 0xFFFF0000)
|| (getEDI() & 0xFFFF0000)
|| (getESI() & 0xFFFF0000)
|| (getEBP() & 0xFFFF0000)
|| (getESP() & 0xFFFF0000)) {
fprintf(fp, "EAX:%000008x EBX:%000008x ECX:%000008x EDX:%000008x\n",
getEAX(), getEBX(), getECX(), getEDX());
fprintf(fp, "ESP:%000008x EBP:%000008x ESI:%000008x EDI:%000008x\n",
getESP(), getEBP(), getESI(), getEDI());
fprintf(fp, "DS:%04x ES:%04x FS:%04x GS:%04x %sSS:%04x %sCS:%04x EIP:%08x\n",
getDS(), getES(), getFS(), getGS(),
is32BitSS ? "Big-" : "", getSS(),
is32BitCS ? "32-" : "", getCS(), getEIP());
} else {
fprintf(fp,"AX:%04x BX:%04x CX:%04x DX:%04x",
getAX(), getBX(), getCX(), getDX());
fprintf(fp, " SP:%04x", getSP());
fprintf(fp, " BP:%04x SI:%04x DI:%04x\n",
getBP(), getSI(), getDI());
fprintf(fp,"DS:%04x ES:%04x FS:%04x GS:%04x SS:%04x CS:%04x IP:%04x\n",
getDS(), getES(), getFS(), getGS(), getSS(), getCS(), getIP());
}
}
if (dump_info & DUMP_INST)
{
char buff[256];
char *fmt, *newline;
IU32 eip = GetInstructionPointer();
/* We use the internal dasm so that we can disassemble
* instructions at (CS_BASE+eip) rather than
* effective_addr(getCS(), getEIP()), since the latter
* produces garbage just after changing the PE bit.
*/
if ( eip & 0xffff0000 )
{
fmt = "%04x:%08x ";
newline = "\n ";
}
else
{
fmt = "%04x:%04x ";
newline = "\n ";
}
(void)dasm_internal(buff,
getCS(),
eip,
is32BitCS ? THIRTY_TWO_BIT : SIXTEEN_BIT,
getCS_BASE() + eip,
read_from_la,
fmt,
newline);
fprintf (fp, "%s", buff);
}
if (dump_info & DUMP_CODE) {
IU32 cs_base = getCS_BASE();
fprintf(fp,"Code dump: Last 16 words\n\n");
i = GetInstructionPointer() - 31;
if (is32BitCS)
fprintf(fp, "%08x: ", i);
else
fprintf(fp, "%04x: ", i);
for(; i < getIP() - 15; i+=2)
{
sas_loadw((cs_base + i), &temp);
fprintf(fp, " %04x", temp);
}
fprintf(fp, "\n%x: ", i);
for(; i <= GetInstructionPointer(); i+=2)
{
sas_loadw((cs_base + i), &temp);
fprintf(fp, " %04x", temp);
}
fprintf(fp,"\n\n");
}
#ifdef SPC486
if (dump_info & DUMP_FLAGS)
{
fprintf(fp, "C:%1d P:%1d A:%1d Z:%1d S:%1d T:%1d I:%1d D:%1d O:%1d\n",
getCF(), getPF(), getAF(), getZF(), getSF(),
getTF(), getIF(), getDF(), getOF());
fprintf(fp, "NT:%1d IOPL:%1d WP:%1d NE:%1d ET:%1d TS:%1d EM:%1d MP:%1d PE:%1d CPL:%1d PG:%1d VM:%1d\n",
getNT(), getIOPL(), getWP(), getNE(), getET(), getTS(), getEM(), getMP(), getPE(),
getCPL(), getPG(),
getVM());
}
#else /* SPC486 */
if (dump_info & DUMP_FLAGS)
{
fprintf(fp,
"C:%1d P:%1d A:%1d Z:%1d S:%1d T:%1d I:%1d D:%1d O:%1d\nNT:%1d IOPL:%1d TS:%1d EM:%1d MP:%1d PE:%1d CPL:%1d PG:%1d VM:%1d\n",
getCF(), getPF(), getAF(), getZF(), getSF(),
getTF(), getIF(), getDF(), getOF(),
getNT(), getIOPL(), getTS(), getEM(), getMP(), getPE(),
getCPL(), getPG(),
getVM()
);
}
#endif /* SPC486 */
}
#endif /* !PROD && SPC386 */
void trace(error_msg, dump_info)
char *error_msg;
int dump_info;
{
#ifndef PROD
word temp;
half_word tempb;
sys_addr i,j;
if (disk_trace != trace_state) /* change of state */
{
if (disk_trace == 1)
{
/* start of disk tracing */
if (trace_file == stdout)
{
trace_file = fopen("disk_trace", "a");
trace_state = 1;
}
else
disk_trace = 0;
}
else
{
fclose(trace_file);
trace_file = stdout;
trace_state = 0;
}
}
if (trace_start > 0) {
trace_start--;
return;
}
#if defined(CPU_40_STYLE) && !defined(CCPU)
EnterDebug("Trace");
#endif /* CPU_40_STYLE && !CCPU */
/*
* Dump the error message
*/
fprintf(trace_file, "*** Trace point *** : %s\n", error_msg);
/*
* Now dump what has been asked for
*/
#if defined(NPX) && !(defined(NTVDM) && defined(MONITOR))
#ifdef CPU_40_STYLE
if (dump_info & DUMP_NPX)
{
IU32 i;
IU32 npx_reg;
IS32 last;
IBOOL any_empty = FALSE;
IU32 stat287 = get_287_status_word();
IU32 cntl287 = get_287_control_word();
IU32 sp287 = get_287_sp();
IU32 tag287 = get_287_tag_word();
fprintf(trace_file, "NPX Status:%04x Control:%04x ST:%d 287Tag:%04x\n", stat287, cntl287, sp287, tag287);
fprintf(trace_file, "NPX Stack: ");
last = -1;
npx_reg = stat287>>11;
npx_reg &= 7;
for (i=0;i<8;i++)
{
if ( ((tag287 >> (2*npx_reg))&3) == 3 )
{
if ( last+1 == i )
fprintf(trace_file, "%cST(%d)", any_empty?',':' ', i);
any_empty = TRUE;
}
else
{
if ( last+2 < i )
fprintf(trace_file, "-ST(%d)", i-1);
last = i;
}
npx_reg = (npx_reg+1)&7;
}
if ( last < 6 )
fprintf(trace_file, "-ST(7)");
fprintf(trace_file, any_empty ? " empty\n" : "\n");
npx_reg = stat287>>11;
npx_reg &= 7;
for (i=0;i<8;i++)
{
if ( ((tag287 >> (2*npx_reg))&3) != 3 )
fprintf(trace_file, "ST(%d): %s\n", i, host_get_287_reg_as_string(i, FALSE));
npx_reg = (npx_reg+1)&7;
}
fprintf(trace_file, "\n");
}
#else /* CPU_40_STYLE */
if (dump_info & DUMP_NPX)
{
int i;
extern CHAR *host_get_287_reg_as_string IPT2(int, reg_no, BOOL, in_hex);
extern int get_287_sp();
extern word get_287_tag_word IPT0();
extern ULONG get_287_control_word();
extern ULONG get_287_status_word();
int stat287 = get_287_status_word();
int cntl287 = get_287_control_word();
int sp287 = get_287_sp();
int tag287 = get_287_tag_word();
fprintf(trace_file, "NPX Status:%04x Control:%04x ST:%d 287Tag:%04x\n", stat287, cntl287, sp287, tag287);
fprintf(trace_file, "NPX Stack: ");
for (i=0;i<8;i++)
fprintf(trace_file, " %10s", host_get_287_reg_as_string(i, FALSE));
fprintf(trace_file, "\n");
}
#endif /* CPU_40_STYLE */
#endif /* NPX && YODA */
#ifdef SPC386
dump386Registers(trace_file, (IUM32)dump_info);
#else
if (dump_info & DUMP_REG)
{
fprintf(trace_file,"AX:%04x BX:%04x CX:%04x DX:%04x SP:%04x BP:%04x SI:%04x DI:%04x ",
getAX(), getBX(), getCX(), getDX(),
getSP(), getBP(), getSI(), getDI());
fprintf(trace_file,"DS:%04x ES:%04x SS:%04x CS:%04x IP:%04x\n",
getDS(), getES(), getSS(), getCS(), getIP());
}
if (dump_info & DUMP_INST)
{
dasm((char *)0, 0, getCS(), getIP(), 1);
}
if (dump_info & DUMP_CODE)
{
fprintf(trace_file,"Code dump: Last 16 words\n\n");
i = getIP() - 31;
fprintf(trace_file, "%04x: ", i);
for(; i < getIP() - 15; i+=2)
{
sas_loadw(effective_addr(getCS(), i), &temp);
fprintf(trace_file, " %04x", temp);
}
fprintf(trace_file, "\n%x: ", i);
for(; i <= getIP(); i+=2)
{
sas_loadw(effective_addr(getCS(), i), &temp);
fprintf(trace_file, " %04x", temp);
}
fprintf(trace_file,"\n\n");
}
if (dump_info & DUMP_FLAGS)
{
#ifdef PM
fprintf(trace_file,
"C:%1d P:%1d A:%1d Z:%1d S:%1d T:%1d I:%1d D:%1d O:%1d NT:%1d IOPL:%1d TS:%1d EM:%1d MP:%1d PE:%1d CPL:%1d\n",
getCF(), getPF(), getAF(), getZF(), getSF(),
getTF(), getIF(), getDF(), getOF(),
getNT(), getIOPL(), getTS(), getEM(), getMP(), getPE(), getCPL()
);
#else
fprintf(trace_file,
"CF:%1d PF:%1d AF:%1d ZF:%1d SF:%1d TF:%1d IF:%1d DF:%1d OF:%1d\n",
getCF(), getPF(), getAF(), getZF(), getSF(),
getTF(), getIF(), getDF(), getOF()
);
#endif /* PM */
}
#endif /* SPC386 else*/
if (dump_info & DUMP_SCREEN)
{
#ifdef SFELLOW
printf("Screen dump not supported on Stringfellows\n");
#else /* SFELLOW */
fprintf(trace_file,"Screen dump:\n\n");
i = gvi_pc_low_regen;
while (i <= gvi_pc_high_regen)
{
fprintf(trace_file,"%4x: ", (word)(i - gvi_pc_low_regen));
for(j=0; j<16; j++)
{
sas_load(i+j, &tempb);
fprintf(trace_file, "%-3x", tempb);
}
fprintf(trace_file," ");
for(j=0; j<16; j++)
{
sas_load(i+j, &tempb);
if (tempb < 0x20)
tempb = '.';
fprintf(trace_file, "%c", tempb);
}
fprintf(trace_file, "\n");
i += 16;
}
fprintf(trace_file, "\n");
#endif /* SFELLOW */
}
#if defined(CPU_40_STYLE) && !defined(CCPU)
LeaveDebug();
#endif /* CPU_40_STYLE && !CCPU */
#else /* PROD */
UNUSED(error_msg);
UNUSED(dump_info);
#endif /* PROD */
}
void trace_init()
{
#if !defined(PROD) || defined(HUNTER)
char *trace_env, *start;
trace_env = host_getenv("TRACE");
/*
* Set up the trace file
*------------------------*/
if (trace_env == NULL)
trace_file = stdout;
else
{
trace_file = fopen(trace_env, "w");
if (trace_file == NULL)
trace_file = stdout;
start = host_getenv("TRACE_START");
if(start == NULL)
trace_start = 0;
else
trace_start = atoi(start);
}
#endif /* !PROD || HUNTER */
}
/* Get the code for 4.0 style CPUs */
#ifndef PROD
#ifdef CPU_40_STYLE
#if defined(NPX)
GLOBAL IU32 get_287_sp IFN0()
{
#ifdef CCPU
IMPORT IU32 getNpxStatusReg IPT0();
IU32 stat287 = getNpxStatusReg();
#else
IMPORT IU32 a_getNpxStatusReg IPT0();
IU32 stat287 = a_getNpxStatusReg();
#endif
return((stat287&0x3800) >> 11);
}
GLOBAL IU32 get_287_control_word IFN0()
{
#ifdef CCPU
IMPORT IU32 getNpxControlReg IPT0();
return(getNpxControlReg());
#else
IMPORT IU32 a_getNpxControlReg IPT0();
return(a_getNpxControlReg());
#endif
}
GLOBAL IU32 get_287_status_word IFN0()
{
#ifdef CCPU
IMPORT IU32 getNpxStatusReg IPT0();
return(getNpxStatusReg());
#else
IMPORT IU32 a_getNpxStatusReg IPT0();
return(a_getNpxStatusReg());
#endif
}
GLOBAL IU32 get_287_tag_word IFN0()
{
#ifdef CCPU
IMPORT IU32 getNpxTagwordReg IPT0();
return(getNpxTagwordReg());
#else
IMPORT IU32 a_getNpxTagwordReg IPT0();
return(a_getNpxTagwordReg());
#endif
}
GLOBAL CHAR *host_get_287_reg_as_string IFN2(IU32, reg_num, BOOL, in_hex)
{
SAVED CHAR dumpStore[80];
#ifdef CCPU
IMPORT CHAR *getNpxStackReg IPT2(IU32, reg_num, CHAR *, dumpStore);
return(getNpxStackReg(reg_num, dumpStore));
#else
IMPORT CHAR *a_getNpxStackReg IPT2(IU32, reg_num, CHAR *, dumpStore);
return(a_getNpxStackReg(reg_num, dumpStore));
#endif
}
#endif /* NPX */
#endif /* CPU_40_STYLE */
#endif /* !PROD */