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

#include <stdio.h>
#include <stdlib.h>
#include "ldt.h"
#include "db_disasm.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, int addrlen)
{
    if (addrlen == 16)
    {
        fprintf( outfile, "%4.4x:%4.4x", addr >> 16, addr & 0xffff );
    }
    else
    {
        extern char * find_nearest_symbol(unsigned int *);

        char * 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 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, dbg_mode);
		fprintf(stderr,":  ");
	};

	switch(format){
	case 's':
		pnt = dbg_mode == 16 ? (char *)PTR_SEG_TO_LIN(addr)
                                     : (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, dbg_mode);
			fprintf(stderr,":  ");
			addr = db_disasm( addr, 0, (dbg_mode == 16) );
			fprintf(stderr,"\n");
		};
		return;
	case 'x':
		dump = dbg_mode == 16 ? (unsigned int *)PTR_SEG_TO_LIN(addr)
                                      : (unsigned int *)addr;
		for(i=0; i<count; i++) 
		{
			fprintf(stderr," %8.8x", *dump++);
                        addr += 4;
			if ((i % 8) == 7) {
				fprintf(stderr,"\n");
				print_address(addr, stderr, dbg_mode);
				fprintf(stderr,":  ");
			};
		}
		fprintf(stderr,"\n");
		return;
	
	case 'd':
		dump = dbg_mode == 16 ? (unsigned int *)PTR_SEG_TO_LIN(addr)
                                      : (unsigned int *)addr;
		for(i=0; i<count; i++) 
		{
			fprintf(stderr," %d", *dump++);
                        addr += 4;
			if ((i % 8) == 7) {
				fprintf(stderr,"\n");
				print_address(addr, stderr, dbg_mode);
				fprintf(stderr,":  ");
			};
		}
		fprintf(stderr,"\n");
		return;
	
	case 'w':
		wdump = dbg_mode == 16 ? (unsigned short *)PTR_SEG_TO_LIN(addr)
                                       : (unsigned short *)addr;
		for(i=0; i<count; i++) 
		{
			fprintf(stderr," %x", *wdump++);
                        addr += 2;
			if ((i % 10) == 7) {
				fprintf(stderr,"\n");
				print_address(addr, stderr, dbg_mode);
				fprintf(stderr,":  ");
			};
		}
		fprintf(stderr,"\n");
		return;
	
	case 'c':
		pnt = dbg_mode == 16 ? (char *)PTR_SEG_TO_LIN(addr)
                                     : (char *)addr;
		for(i=0; i<count; i++) 
		{
			if(*pnt < 0x20) {
				fprintf(stderr,"  ");
				pnt++;
			} else
				fprintf(stderr," %c", *pnt++);
                        addr++;
			if ((i % 32) == 7) {
				fprintf(stderr,"\n");
				print_address(addr, stderr, dbg_mode);
				fprintf(stderr,":  ");
			};
		}
		fprintf(stderr,"\n");
		return;
	
	case 'b':
		pnt = dbg_mode == 16 ? (char *)PTR_SEG_TO_LIN(addr)
                                     : (char *)addr;
		for(i=0; i<count; i++) 
		{
			fprintf(stderr," %02x", (*pnt++) & 0xff);
                        addr++;
			if ((i % 32) == 7) {
				fprintf(stderr,"\n");
				print_address(addr, stderr, dbg_mode);
				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",
"  break *<addr>                        bt",
"  disable bpnum                        enable bpnum",
"  help                                 quit",
"  x <expr>                             cont",
"  mode [16,32]                         print <expr>",
"  set <reg> = <expr>                   set *<expr> = <expr>",
"  info [reg,stack,break,segments]      symbolfile <filename>",
"  define <identifier> <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;
  }

  if (dbg_mode == 16)
      frame = (struct frame *)PTR_SEG_OFF_TO_LIN( SC_SS, SC_BP & ~1 );
  else
      frame = (struct frame *)SC_EBP(dbg_mask);

  fprintf(stderr,"Backtrace:\n");
  cs = SC_CS;
  while((cs & 3) == 3) {
    /* See if in 32 bit mode or not.  Assume GDT means 32 bit. */
    if ((cs & 7) != 7) {
      extern int main();
      fprintf(stderr,"%d ",frameno++);
      print_address(frame->u.win32.saved_ip,stderr,32);
      fprintf( stderr, "\n" );
      if (frame->u.win32.saved_ip >= ((unsigned long)main) &&
          frame->u.win32.saved_ip <= ((unsigned long)main+1000)) break;
      frame = (struct frame *) frame->u.win32.saved_bp;
    } else {
      if (frame->u.win16.saved_bp & 1) cs = frame->u.win16.saved_cs;
      fprintf(stderr,"%d %4.4x:%4.4x\n", frameno++, cs, 
	      frame->u.win16.saved_ip);
      frame = (struct frame *) PTR_SEG_OFF_TO_LIN( SC_SS, frame->u.win16.saved_bp & ~1);
      if ((cs & 7) != 7)  /* switching to 32-bit mode */
      {
          extern int IF1632_Saved32_ebp;
          frame = (struct frame *)IF1632_Saved32_ebp;
      }
    }
  }
  putchar('\n');
}

