/*
 * 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 char * find_nearest_symbol( unsigned int seg, unsigned int addr );

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 segment, unsigned int addr, int addrlen )
{
    char *name = find_nearest_symbol( segment, addr );

    if (segment) fprintf( stderr, "0x%04x:", segment );
    if (addrlen == 16) fprintf( stderr, "0x%04x", addr );
    else fprintf( stderr, "0x%08x", addr );
    if (name) fprintf( stderr, " (%s)", name );
}


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_ESP(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( unsigned int segment, unsigned int addr,
                     int count, char format )
{
    char * pnt;
    unsigned int * dump;
    unsigned short int * wdump;
    int i;

    if (segment == 0xffffffff)
        segment = (dbg_mode == 32) ? 0 : (format == 'i' ? SC_CS : SC_DS);
    
    if (format != 'i' && count > 1)
    {
        print_address( segment, addr, dbg_mode );
        fprintf(stderr,":  ");
    }

    pnt = segment ? (char *)PTR_SEG_OFF_TO_LIN(segment,addr) : (char *)addr;

    switch(format)
    {
	case 's':
		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( segment, addr, dbg_mode );
			fprintf(stderr,":  ");
			addr = db_disasm( segment, addr, (dbg_mode == 16) );
			fprintf(stderr,"\n");
		};
		return;
	case 'x':
		dump = (unsigned int *)pnt;
		for(i=0; i<count; i++) 
		{
			fprintf(stderr," %8.8x", *dump++);
                        addr += 4;
			if ((i % 8) == 7) {
				fprintf(stderr,"\n");
				print_address( segment, addr, dbg_mode );
				fprintf(stderr,":  ");
			};
		}
		fprintf(stderr,"\n");
		return;
	
	case 'd':
		dump = (unsigned int *)pnt;
		for(i=0; i<count; i++) 
		{
			fprintf(stderr," %d", *dump++);
                        addr += 4;
			if ((i % 8) == 7) {
				fprintf(stderr,"\n");
				print_address( segment, addr, dbg_mode );
				fprintf(stderr,":  ");
			};
		}
		fprintf(stderr,"\n");
		return;
	
	case 'w':
		wdump = (unsigned short *)pnt;
		for(i=0; i<count; i++) 
		{
			fprintf(stderr," %x", *wdump++);
                        addr += 2;
			if ((i % 10) == 7) {
				fprintf(stderr,"\n");
				print_address( segment, addr, dbg_mode );
				fprintf(stderr,":  ");
			};
		}
		fprintf(stderr,"\n");
		return;
	
	case 'c':
		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( segment, addr, dbg_mode );
				fprintf(stderr,":  ");
			};
		}
		fprintf(stderr,"\n");
		return;
	
	case 'b':
		for(i=0; i<count; i++) 
		{
			fprintf(stderr," %02x", (*pnt++) & 0xff);
                        addr++;
			if ((i % 32) == 7) {
				fprintf(stderr,"\n");
				print_address( segment, addr, 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) {
      fprintf(stderr,"%d ",frameno++);
      print_address( 0, frame->u.win32.saved_ip, 32 );
      fprintf( stderr, "\n" );
      if (!frame->u.win32.saved_ip) 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);
      if (!frame->u.win16.saved_bp) break;
      frame = (struct frame *) PTR_SEG_OFF_TO_LIN( SC_SS, frame->u.win16.saved_bp & ~1);
    }
  }
  putchar('\n');
}

