/*
 * Wine debugger utility routines
 * Eric Youngdale
 * 9/93
 */

#include <stdio.h>
#include "opcodes/dis-asm.h"
#include "regpos.h"

extern int * regval;
extern unsigned int dbg_mask;
extern unsigned int dbg_mode;

void application_not_running()
{
  fprintf(stderr,"Application not running\n");
}

void print_address(unsigned int addr, FILE * outfile){
	char * name;
	extern char * find_nearest_symbol(unsigned int *);

	name = find_nearest_symbol((unsigned int *) addr);
	if(name)
		fprintf(outfile,"0x%8.8x(%s)", addr, name);
	else
		fprintf(outfile,"0x%8.8x", addr);

}

void print_address_info(bfd_vma addr, disassemble_info * info){
	print_address((unsigned int) addr, info->stream);
}

int print_insn(char *realmemaddr, char *memaddr, FILE *stream, int addrlen){
	static disassemble_info info;
	static int initialized = 0;

	if (!initialized) {
		INIT_DISASSEMBLE_INFO(info, stderr);
		info.print_address_func = print_address_info;
		initialized = 1;
	}
	info.stream = stream;
	info.buffer = memaddr;
	info.buffer_vma = (bfd_vma) realmemaddr;
	info.buffer_length = 1024;
	if (addrlen == 16)
		return print_insn_i286((bfd_vma) realmemaddr, &info);
	if (addrlen == 32)
		return print_insn_i386((bfd_vma) realmemaddr, &info);
	fprintf(stderr, "invalid address length %d.\n", addrlen);
	return 0;
}

void info_reg(){

	  if(!regval) {
	    application_not_running();
	    return;
	  }

	fprintf(stderr,"Register dump:\n");
	/* First get the segment registers out of the way */
	fprintf(stderr," CS:%4.4x SS:%4.4x DS:%4.4x ES:%4.4x GS:%4.4x FS:%4.4x\n", 
		SC_CS, SC_SS, SC_DS, SC_ES, SC_GS, SC_FS);

	/* Now dump the main registers */
	fprintf(stderr," EIP:%8.8x ESP:%8.8x EBP:%8.8x EFLAGS:%8.8x\n", 
		SC_EIP(dbg_mask), SC_ESP(dbg_mask), SC_EBP(dbg_mask), SC_EFLAGS);

	/* And dump the regular registers */

	fprintf(stderr," EAX:%8.8x EBX:%8.8x ECX:%8.8x EDX:%8.8x\n", 
		SC_EAX(dbg_mask), SC_EBX(dbg_mask), SC_ECX(dbg_mask), SC_EDX(dbg_mask));

	/* Finally dump these main registers */
	fprintf(stderr," EDI:%8.8x ESI:%8.8x\n", 
		SC_EDI(dbg_mask), SC_ESI(dbg_mask));

}

void info_stack(){
	unsigned int * dump;
	int i;

	if(!regval) {
	  application_not_running();
	  return;
	}

	fprintf(stderr,"Stack dump:\n");
	dump = (int*) SC_EIP(dbg_mask);
	for(i=0; i<22; i++) 
	{
	    fprintf(stderr," %8.8x", *dump++);
	    if ((i % 8) == 7)
		fprintf(stderr,"\n");
	}
	fprintf(stderr,"\n");
}


void examine_memory(int addr, int count, char format){
	char * pnt;
	unsigned int * dump;
	unsigned short int * wdump;
	int i;

	if((addr & 0xffff0000) == 0 && dbg_mode == 16)
	        addr |= (format == 'i' ? SC_CS : SC_DS) << 16;


	if(format != 'i' && count > 1) {
		print_address(addr, stderr);
		fprintf(stderr,":  ");
	};


	switch(format){
	case 's':
		pnt = (char *) addr;
		if (count == 1) count = 256;
	        while(*pnt && count) {
			fputc( *pnt++, stderr);
			count--;
		};
		fprintf(stderr,"\n");
		return;

	case 'i':
		for(i=0; i<count; i++) {
			print_address(addr, stderr);
			fprintf(stderr,":  ");
			addr += print_insn((char *) addr, (char *) addr, stderr, dbg_mode);
			fprintf(stderr,"\n");
		};
		return;
	case 'x':
		dump = (unsigned int *) addr;
		for(i=0; i<count; i++) 
		{
			fprintf(stderr," %8.8x", *dump++);
			if ((i % 8) == 7) {
				fprintf(stderr,"\n");
				print_address((unsigned int) dump, stderr);
				fprintf(stderr,":  ");
			};
		}
		fprintf(stderr,"\n");
		return;
	
	case 'd':
		dump = (unsigned int *) addr;
		for(i=0; i<count; i++) 
		{
			fprintf(stderr," %d", *dump++);
			if ((i % 8) == 7) {
				fprintf(stderr,"\n");
				print_address((unsigned int) dump, stderr);
				fprintf(stderr,":  ");
			};
		}
		fprintf(stderr,"\n");
		return;
	
	case 'w':
		wdump = (unsigned short int *) addr;
		for(i=0; i<count; i++) 
		{
			fprintf(stderr," %x", *wdump++);
			if ((i % 10) == 7) {
				fprintf(stderr,"\n");
				print_address((unsigned int) wdump, stderr);
				fprintf(stderr,":  ");
			};
		}
		fprintf(stderr,"\n");
		return;
	
	case 'c':
		pnt = (char *) addr;
		for(i=0; i<count; i++) 
		{
			if(*pnt < 0x20) {
				fprintf(stderr,"  ");
				pnt++;
			} else
				fprintf(stderr," %c", *pnt++);
			if ((i % 32) == 7) {
				fprintf(stderr,"\n");
				print_address((unsigned int) dump, stderr);
				fprintf(stderr,":  ");
			};
		}
		fprintf(stderr,"\n");
		return;
	
	case 'b':
		pnt = (char *) addr;
		for(i=0; i<count; i++) 
		{
			fprintf(stderr," %02.2x", (*pnt++) & 0xff);
			if ((i % 32) == 7) {
				fprintf(stderr,"\n");
				print_address((unsigned int) pnt, stderr);
				fprintf(stderr,":  ");
			};
		}
		fprintf(stderr,"\n");
		return;
	};
	
	/* The rest are fairly straightforward */

	fprintf(stderr,"examine mem: %x %d %c\n", addr, count, format);
}

char * helptext[] = {
"The commands accepted by the Wine debugger are a small subset",
"of the commands that gdb would accept.  The commands currently",
"are:\n",
"  info [reg,stack,break]",
"  break *<addr>",
"  enable bpnum",
"  disable bpnum",
"  help",
"  quit",
"  print <expr>",
"  bt",
"  mode [16,32]",
"  symbolfile <filename>",
"  define <identifier> <expr>",
"  x <expr>",
"  cont",
"  set <reg> = <expr>",
"  set *<expr> = <expr>",
"",
"The 'x' command accepts repeat counts and formats (including 'i') in the",
"same way that gdb does.",
"",
" The following are examples of legal expressions:",
" $eax     $eax+0x3   0x1000   ($eip + 256)  *$eax   *($esp + 3)",
" Also, a nm format symbol table can be read from a file using the",
" symbolfile command.  Symbols can also be defined individually with",
" the define command.",
"",
NULL};

void dbg_help(){
	int i;
	i = 0;
	while(helptext[i]) fprintf(stderr,"%s\n", helptext[i++]);
}


struct frame{
  union{
    struct {
      unsigned short saved_bp;
      unsigned short saved_ip;
      unsigned short saved_cs;
    } win16;
    struct {
      unsigned long saved_bp;
      unsigned long saved_ip;
      unsigned short saved_cs;
    } win32;
  } u;
};


void dbg_bt(){
  struct frame * frame;
  unsigned short cs;
  int frameno = 0;

  if(!regval) {
    application_not_running();
    return;
  }

  fprintf(stderr,"Backtrace:\n");
  fprintf(stderr,"%d %4.4x:%4.4x\n", frameno++, SC_CS, SC_EIP(dbg_mask));
  cs = SC_CS;

  frame = (struct frame *) ((SC_EBP(dbg_mask) & ~1) | (SC_SS << 16));
  while((cs & 3) == 3) {
    /* See if in 32 bit mode or not.  Assume GDT means 32 bit. */
    if ((cs & 7) != 7) {
      cs = frame->u.win32.saved_cs;
      fprintf(stderr,"%d %4.4x:%4.4x\n", frameno++, cs, 
	      frame->u.win32.saved_ip);
      frame = (struct frame *) frame->u.win32.saved_bp;
    } else {
      cs = frame->u.win16.saved_cs;
      fprintf(stderr,"%d %4.4x:%4.4x\n", frameno++, cs, 
	      frame->u.win16.saved_ip);
      frame = (struct frame *) ((frame->u.win16.saved_bp & ~1) |
				(SC_SS << 16));
    }
  }
}

