Charles.Forsyth20060303644188019 years agoHistory
1850 lines · 44.6 KB · C
RawDownload
#include <lib9.h>#include <bio.h>#include "mach.h" /* * i386-specific debugger interface */ static	char	*i386excep(Map*, Rgetter); static	int	i386trace(Map*, ulong, ulong, ulong, Tracer);static	ulong	i386frame(Map*, ulong, ulong, ulong, ulong);static	int	i386foll(Map*, ulong, Rgetter, ulong*);static	int	i386inst(Map*, ulong, char, char*, int);static	int	i386das(Map*, ulong, char*, int);static	int	i386instlen(Map*, ulong); static	char	STARTSYM[] =	"_main";static	char	PROFSYM[] =	"_mainp";static	char	FRAMENAME[] =	".frame";static char *excname[] ={	"divide error",			/* 0 */	"debug exception",		/* 1 */	0,0,				/* 2, 3 */	"overflow",			/* 4 */	"bounds check",			/* 5 */	"invalid opcode",		/* 6 */	"math coprocessor emulation",	/* 7 */	"double fault",			/* 8 */	"math coprocessor overrun",	/* 9 */	"invalid TSS",			/* 10 */	"segment not present",		/* 11 */	"stack exception",		/* 12 */	"general protection violation",	/* 13 */	"page fault",			/* 14 */	0,				/* 15 */	"math coprocessor error",	/* 16 */	0,0,0,0,0,0,0,			/* 17-23 */	"clock",			/* 24 */	"keyboard",			/* 25 */	0,				/* 26 */	"modem status",			/* 27 */	"serial line status",		/* 28 */	0,				/* 29 */	"floppy disk",			/* 30 */	0,0,0,0,0,			/* 31-35 */	"mouse",			/* 36 */	"math coprocessor",		/* 37 */	"hard disk",			/* 38 */	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,/* 39-54 */	0,0,0,0,0,0,0,0,0,		/* 55-63 */	"system call",			/* 64 */}; Machdata i386mach ={	{0xCC, 0, 0, 0},	/* break point: INT 3 */	1,			/* break point size */ 	leswab,			/* convert short to local byte order */	leswal,			/* convert long to local byte order */	leswav,			/* convert vlong to local byte order */	i386trace,		/* C traceback */	i386frame,		/* frame finder */	i386excep,		/* print exception */	0,			/* breakpoint fixup */	leieeesftos,		/* single precision float printer */	leieeedftos,		/* double precision float printer */	i386foll,		/* following addresses */	i386inst,		/* print instruction */	i386das,		/* dissembler */	i386instlen,		/* instruction size calculation */}; static char*i386excep(Map *map, Rgetter rget){	ulong c;	ulong pc;	static char buf[16]; 	c = (*rget)(map, "TRAP");	if(c > 64 || excname[c] == 0) {		if (c == 3) {			pc = (*rget)(map, "PC");			if (get1(map, pc, (uchar*)buf, machdata->bpsize) > 0)			if (memcmp(buf, machdata->bpinst, machdata->bpsize) == 0)				return "breakpoint";		}		sprint(buf, "exception %ld", c);		return buf;	} else		return excname[c];} static inti386trace(Map *map, ulong pc, ulong sp, ulong link, Tracer trace){	int i;	ulong osp;	Symbol s, f; 	USED(link);	i = 0;	osp = 0;	while(findsym(pc, CTEXT, &s)) {		if (osp == sp)			break;		osp = sp; 		if(strcmp(STARTSYM, s.name) == 0 || strcmp(PROFSYM, s.name) == 0)			break; 		if(pc != s.value) {	/* not at first instruction */			if(findlocal(&s, FRAMENAME, &f) == 0)				break;			sp += f.value-mach->szaddr;		} 		if (get4(map, sp, (long *) &pc) < 0)			break; 		if(pc == 0)			break; 		(*trace)(map, pc, sp, &s);		sp += mach->szaddr; 		if(++i > 40)			break;	}	return i;} static ulongi386frame(Map *map, ulong addr, ulong pc, ulong sp, ulong link){	Symbol s, f; 	USED(link);	while (findsym(pc, CTEXT, &s)) {		if(strcmp(STARTSYM, s.name) == 0 || strcmp(PROFSYM, s.name) == 0)			break; 		if(pc != s.value) {	/* not first instruction */			if(findlocal(&s, FRAMENAME, &f) == 0)				break;			sp += f.value-mach->szaddr;		} 		if (s.value == addr)			return sp; 		if (get4(map, sp, (long *)&pc) < 0)			break;		sp += mach->szaddr;	}	return 0;} 	/* I386/486 - Disassembler and related functions */ /* *  an instruction */typedef struct Instr Instr;struct	Instr{	uchar	mem[1+1+1+1+2+1+1+4+4];		/* raw instruction */	ulong	addr;		/* address of start of instruction */	int	n;		/* number of bytes in instruction */	char	*prefix;	/* instr prefix */	char	*segment;	/* segment override */	uchar	jumptype;	/* set to the operand type for jump/ret/call */	char	osize;		/* 'W' or 'L' */	char	asize;		/* address size 'W' or 'L' */	uchar	mod;		/* bits 6-7 of mod r/m field */	uchar	reg;		/* bits 3-5 of mod r/m field */	char	ss;		/* bits 6-7 of SIB */	char	index;		/* bits 3-5 of SIB */	char	base;		/* bits 0-2 of SIB */	short	seg;		/* segment of far address */	ulong	disp;		/* displacement */	ulong 	imm;		/* immediate */	ulong 	imm2;		/* second immediate operand */	char	*curr;		/* fill level in output buffer */	char	*end;		/* end of output buffer */	char	*err;		/* error message */}; 	/* 386 register (ha!) set */enum{	AX=0,	CX,	DX,	BX,	SP,	BP,	SI,	DI,};	/* Operand Format codes *//*%A	-	address size register modifier (!asize -> 'E')%C	-	Control register CR0/CR1/CR2%D	-	Debug register DR0/DR1/DR2/DR3/DR6/DR7%I	-	second immediate operand%O	-	Operand size register modifier (!osize -> 'E')%T	-	Test register TR6/TR7%S	-	size code ('W' or 'L')%X	-	Weird opcode: OSIZE == 'W' => "CBW"; else => "CWDE"%d	-	displacement 16-32 bits%e	-	effective address - Mod R/M value%f	-	floating point register F0-F7 - from Mod R/M register%g	-	segment register%i	-	immediate operand 8-32 bits%p	-	PC-relative - signed displacement in immediate field%r	-	Reg from Mod R/M%x	-	Weird opcode: OSIZE == 'W' => "CWD"; else => "CDQ"*/ typedef struct Optable Optable;struct Optable{	char	operand[2];	void	*proto;		/* actually either (char*) or (Optable*) */};	/* Operand decoding codes */enum {	Ib = 1,			/* 8-bit immediate - (no sign extension)*/	Ibs,			/* 8-bit immediate (sign extended) */	Jbs,			/* 8-bit sign-extended immediate in jump or call */	Iw,			/* 16-bit immediate -> imm */	Iw2,			/* 16-bit immediate -> imm2 */	Iwd,			/* Operand-sized immediate (no sign extension)*/	Awd,			/* Address offset */	Iwds,			/* Operand-sized immediate (sign extended) */	RM,			/* Word or long R/M field with register (/r) */	RMB,			/* Byte R/M field with register (/r) */	RMOP,			/* Word or long R/M field with op code (/digit) */	RMOPB,			/* Byte R/M field with op code (/digit) */	RMR,			/* R/M register only (mod = 11) */	RMM,			/* R/M memory only (mod = 0/1/2) */	R0,			/* Base reg of Mod R/M is literal 0x00 */	R1,			/* Base reg of Mod R/M is literal 0x01 */	FRMOP,			/* Floating point R/M field with opcode */	FRMEX,			/* Extended floating point R/M field with opcode */	JUMP,			/* Jump or Call flag - no operand */	RET,			/* Return flag - no operand */	OA,			/* literal 0x0a byte */	PTR,			/* Seg:Displacement addr (ptr16:16 or ptr16:32) */	AUX,			/* Multi-byte op code - Auxiliary table */	PRE,			/* Instr Prefix */	SEG,			/* Segment Prefix */	OPOVER,			/* Operand size override */	ADDOVER,		/* Address size override */};	static Optable optab0F00[8]={	0,0,		"MOVW	LDT,%e",	/* 0x00 */	0,0,		"MOVW	TR,%e",		/* 0x01 */	0,0,		"MOVW	%e,LDT",	/* 0x02 */	0,0,		"MOVW	%e,TR",		/* 0x03 */	0,0,		"VERR	%e",		/* 0x04 */	0,0,		"VERW	%e",		/* 0x05 */}; static Optable optab0F01[8]={	0,0,		"MOVL	GDTR,%e",	/* 0x00 */	0,0,		"MOVL	IDTR,%e",	/* 0x01 */	0,0,		"MOVL	%e,GDTR",	/* 0x02 */	0,0,		"MOVL	%e,IDTR",	/* 0x03 */	0,0,		"MOVW	MSW,%e",	/* 0x04 */	/* word */	0,0,		"",			/* 0x05 */	0,0,		"MOVW	%e,MSW",	/* 0x06 */	/* word */}; static Optable optab0FBA[8]={	0,0,		"",			/* 0x00 */	0,0,		"",			/* 0x01 */	0,0,		"",			/* 0x02 */	0,0,		"",			/* 0x03 */	Ib,0,		"BT%S	%i,%e",		/* 0x04 */	Ib,0,		"BTS%S	%i,%e",		/* 0x05 */	Ib,0,		"BTR%S	%i,%e",		/* 0x06 */	Ib,0,		"BTC%S	%i,%e",		/* 0x07 */}; static Optable optab0F[256]={	RMOP,0,		optab0F00,		/* 0x00 */	RMOP,0,		optab0F01,		/* 0x01 */	RM,0,		"LAR	%e,%r",		/* 0x02 */	RM,0,		"LSL	%e,%r",		/* 0x03 */	0,0,		"",			/* 0x04 */	0,0,		"",			/* 0x05 */	0,0,		"CLTS",			/* 0x06 */	0,0,		"",			/* 0x07 */	0,0,		"INVD",			/* 0x08 */	0,0,		"WBINVD",		/* 0x09 */	0,0,		"",			/* 0x0a */	0,0,		"",			/* 0x0b */	0,0,		"",			/* 0x0c */	0,0,		"",			/* 0x0d */	0,0,		"",			/* 0x0e */	0,0,		"",			/* 0x0f */	0,0,		"",			/* 0x10 */	0,0,		"",			/* 0x11 */	0,0,		"",			/* 0x12 */	0,0,		"",			/* 0x13 */	0,0,		"",			/* 0x14 */	0,0,		"",			/* 0x15 */	0,0,		"",			/* 0x16 */	0,0,		"",			/* 0x17 */	0,0,		"",			/* 0x18 */	0,0,		"",			/* 0x19 */	0,0,		"",			/* 0x1a */	0,0,		"",			/* 0x1b */	0,0,		"",			/* 0x1c */	0,0,		"",			/* 0x1d */	0,0,		"",			/* 0x1e */	0,0,		"",			/* 0x1f */	RMR,0,		"MOVL	%C,%e",		/* 0x20 */	RMR,0,		"MOVL	%D,%e",		/* 0x21 */	RMR,0,		"MOVL	%e,%C",		/* 0x22 */	RMR,0,		"MOVL	%e,%D",		/* 0x23 */	RMR,0,		"MOVL	%T,%e",		/* 0x24 */	0,0,		"",			/* 0x25 */	RMR,0,		"MOVL	%e,%T",		/* 0x26 */	0,0,		"",			/* 0x27 */	0,0,		"",			/* 0x28 */	0,0,		"",			/* 0x29 */	0,0,		"",			/* 0x2a */	0,0,		"",			/* 0x2b */	0,0,		"",			/* 0x2c */	0,0,		"",			/* 0x2d */	0,0,		"",			/* 0x2e */	0,0,		"",			/* 0x2f */	0,0,		"WRMSR",		/* 0x30 */	0,0,		"RDTSC",		/* 0x31 */	0,0,		"RDMSR",		/* 0x32 */	0,0,		"",			/* 0x33 */	0,0,		"",			/* 0x34 */	0,0,		"",			/* 0x35 */	0,0,		"",			/* 0x36 */	0,0,		"",			/* 0x37 */	0,0,		"",			/* 0x38 */	0,0,		"",			/* 0x39 */	0,0,		"",			/* 0x3a */	0,0,		"",			/* 0x3b */	0,0,		"",			/* 0x3c */	0,0,		"",			/* 0x3d */	0,0,		"",			/* 0x3e */	0,0,		"",			/* 0x3f */	0,0,		"",			/* 0x40 */	0,0,		"",			/* 0x41 */	0,0,		"",			/* 0x42 */	0,0,		"",			/* 0x43 */	0,0,		"",			/* 0x44 */	0,0,		"",			/* 0x45 */	0,0,		"",			/* 0x46 */	0,0,		"",			/* 0x47 */	0,0,		"",			/* 0x48 */	0,0,		"",			/* 0x49 */	0,0,		"",			/* 0x4a */	0,0,		"",			/* 0x4b */	0,0,		"",			/* 0x4c */	0,0,		"",			/* 0x4d */	0,0,		"",			/* 0x4e */	0,0,		"",			/* 0x4f */	0,0,		"",			/* 0x50 */	0,0,		"",			/* 0x51 */	0,0,		"",			/* 0x52 */	0,0,		"",			/* 0x53 */	0,0,		"",			/* 0x54 */	0,0,		"",			/* 0x55 */	0,0,		"",			/* 0x56 */	0,0,		"",			/* 0x57 */	0,0,		"",			/* 0x58 */	0,0,		"",			/* 0x59 */	0,0,		"",			/* 0x5a */	0,0,		"",			/* 0x5b */	0,0,		"",			/* 0x5c */	0,0,		"",			/* 0x5d */	0,0,		"",			/* 0x5e */	0,0,		"",			/* 0x5f */	0,0,		"",			/* 0x60 */	0,0,		"",			/* 0x61 */	0,0,		"",			/* 0x62 */	0,0,		"",			/* 0x63 */	0,0,		"",			/* 0x64 */	0,0,		"",			/* 0x65 */	0,0,		"",			/* 0x66 */	0,0,		"",			/* 0x67 */	0,0,		"",			/* 0x68 */	0,0,		"",			/* 0x69 */	0,0,		"",			/* 0x6a */	0,0,		"",			/* 0x6b */	0,0,		"",			/* 0x6c */	0,0,		"",			/* 0x6d */	0,0,		"",			/* 0x6e */	0,0,		"",			/* 0x6f */	0,0,		"",			/* 0x70 */	0,0,		"",			/* 0x71 */	0,0,		"",			/* 0x72 */	0,0,		"",			/* 0x73 */	0,0,		"",			/* 0x74 */	0,0,		"",			/* 0x75 */	0,0,		"",			/* 0x76 */	0,0,		"",			/* 0x77 */	0,0,		"",			/* 0x78 */	0,0,		"",			/* 0x79 */	0,0,		"",			/* 0x7a */	0,0,		"",			/* 0x7b */	0,0,		"",			/* 0x7c */	0,0,		"",			/* 0x7d */	0,0,		"",			/* 0x7e */	0,0,		"",			/* 0x7f */	Iwds,0,		"JOS	%p",		/* 0x80 */	Iwds,0,		"JOC	%p",		/* 0x81 */	Iwds,0,		"JCS	%p",		/* 0x82 */	Iwds,0,		"JCC	%p",		/* 0x83 */	Iwds,0,		"JEQ	%p",		/* 0x84 */	Iwds,0,		"JNE	%p",		/* 0x85 */	Iwds,0,		"JLS	%p",		/* 0x86 */	Iwds,0,		"JHI	%p",		/* 0x87 */	Iwds,0,		"JMI	%p",		/* 0x88 */	Iwds,0,		"JPL	%p",		/* 0x89 */	Iwds,0,		"JPS	%p",		/* 0x8a */	Iwds,0,		"JPC	%p",		/* 0x8b */	Iwds,0,		"JLT	%p",		/* 0x8c */	Iwds,0,		"JGE	%p",		/* 0x8d */	Iwds,0,		"JLE	%p",		/* 0x8e */	Iwds,0,		"JGT	%p",		/* 0x8f */	RMB,0,		"SETOS	%e",		/* 0x90 */	RMB,0,		"SETOC	%e",		/* 0x91 */	RMB,0,		"SETCS	%e",		/* 0x92 */	RMB,0,		"SETCC	%e",		/* 0x93 */	RMB,0,		"SETEQ	%e",		/* 0x94 */	RMB,0,		"SETNE	%e",		/* 0x95 */	RMB,0,		"SETLS	%e",		/* 0x96 */	RMB,0,		"SETHI	%e",		/* 0x97 */	RMB,0,		"SETMI	%e",		/* 0x98 */	RMB,0,		"SETPL	%e",		/* 0x99 */	RMB,0,		"SETPS	%e",		/* 0x9a */	RMB,0,		"SETPC	%e",		/* 0x9b */	RMB,0,		"SETLT	%e",		/* 0x9c */	RMB,0,		"SETGE	%e",		/* 0x9d */	RMB,0,		"SETLE	%e",		/* 0x9e */	RMB,0,		"SETGT	%e",		/* 0x9f */	0,0,		"PUSHL	FS",		/* 0xa0 */	0,0,		"POPL	FS",		/* 0xa1 */	0,0,		"CPUID",		/* 0xa2 */	RM,0,		"BT%S	%r,%e",		/* 0xa3 */	RM,Ib,		"SHLD%S	%r,%i,%e",	/* 0xa4 */	RM,0,		"SHLD%S	%r,CL,%e",	/* 0xa5 */	0,0,		"",			/* 0xa6 */	0,0,		"",			/* 0xa7 */	0,0,		"PUSHL	GS",		/* 0xa8 */	0,0,		"POPL	GS",		/* 0xa9 */	0,0,		"",			/* 0xaa */	RM,0,		"BTS%S	%r,%e",		/* 0xab */	RM,Ib,		"SHRD%S	%r,%i,%e",	/* 0xac */	RM,0,		"SHRD%S	%r,CL,%e",	/* 0xad */	0,0,		"",			/* 0xae */	RM,0,		"IMUL%S	%e,%r",		/* 0xaf */	0,0,		"",			/* 0xb0 */	0,0,		"",			/* 0xb1 */	RMM,0,		"LSS	%e,%r",		/* 0xb2 */	RM,0,		"BTR%S	%r,%e",		/* 0xb3 */	RMM,0,		"LFS	%e,%r",		/* 0xb4 */	RMM,0,		"LGS	%e,%r",		/* 0xb5 */	RMB,0,		"MOVBZX	%e,%R",		/* 0xb6 */	RM,0,		"MOVWZX	%e,%R",		/* 0xb7 */	0,0,		"",			/* 0xb8 */	0,0,		"",			/* 0xb9 */	RMOP,0,		optab0FBA,		/* 0xba */	RM,0,		"BTC%S	%e,%r",		/* 0xbb */	RM,0,		"BSF%S	%e,%r",		/* 0xbc */	RM,0,		"BSR%S	%e,%r",		/* 0xbd */	RMB,0,		"MOVBSX	%e,%R",		/* 0xbe */	RM,0,		"MOVWSX	%e,%R",		/* 0xbf */}; static Optable optab80[8]={	Ib,0,		"ADDB	%i,%e",		/* 0x00 */	Ib,0,		"ORB	%i,%e",		/* 0x01 */	Ib,0,		"ADCB	%i,%e",		/* 0x02 */	Ib,0,		"SBBB	%i,%e",		/* 0x03 */	Ib,0,		"ANDB	%i,%e",		/* 0x04 */	Ib,0,		"SUBB	%i,%e",		/* 0x05 */	Ib,0,		"XORB	%i,%e",		/* 0x06 */	Ib,0,		"CMPB	%e,%i",		/* 0x07 */}; 

Lines 1–500 of 1850.