/*
 * Debugger stack handling
 *
 * Copyright 1995 Alexandre Julliard
 * Copyright 1996 Eric Youngdale
 */

#include <stdio.h>
#include <stdlib.h>
#include "xmalloc.h"
#include "windows.h"
#include "debugger.h"


/*
 * We keep this info for each frame, so that we can
 * find local variable information correctly.
 */
struct bt_info
{
  unsigned int	     eip;
  unsigned int	     ess;
  unsigned int	     ebp;
  struct symbol_info frame;
};

static int nframe;
static struct bt_info * frames = NULL;
int curr_frame;

typedef struct
{
    WORD bp;
    WORD ip;
    WORD cs;
} FRAME16;

typedef struct
{
    DWORD bp;
    DWORD ip;
    WORD cs;
} FRAME32;



/***********************************************************************
 *           DEBUG_InfoStack
 *
 * Dump the top of the stack
 */
void DEBUG_InfoStack(void)
{
    DBG_ADDR addr;

    fprintf(stderr,"Stack dump:\n");
    if ((SS_reg(&DEBUG_context) == WINE_DATA_SELECTOR) ||
        (GET_SEL_FLAGS(SS_reg(&DEBUG_context)) & LDT_FLAGS_32BIT))
    {  /* 32-bit mode */
        addr.seg = 0;
        addr.off = ESP_reg(&DEBUG_context);
	addr.type = NULL;
        DEBUG_ExamineMemory( &addr, 24, 'x' );
    }
    else  /* 16-bit mode */
    {
        addr.seg = SS_reg(&DEBUG_context);
        addr.off = SP_reg(&DEBUG_context);
	addr.type = NULL;
        DEBUG_ExamineMemory( &addr, 24, 'w' );
    }
    fprintf(stderr,"\n");
}


/***********************************************************************
 *           DEBUG_BackTrace
 *
 * Display a stack back-trace.
 */
void DEBUG_BackTrace(void)
{
    DBG_ADDR addr;
    int frameno = 0;

    fprintf(stderr,"Backtrace:\n");
    if (SS_reg(&DEBUG_context) == WINE_DATA_SELECTOR)  /* 32-bit mode */
    {
        nframe = 1;
        if (frames) free( frames );
	frames = (struct bt_info *) xmalloc( sizeof(struct bt_info) );
        fprintf(stderr,"%s%d ",(curr_frame == 0 ? "=>" : "  "), frameno++);

        addr.seg = 0;
        addr.off = EIP_reg(&DEBUG_context);
	frames[0].eip = addr.off;
        frames[0].frame = DEBUG_PrintAddress( &addr, 32, TRUE );
        fprintf( stderr, "\n" );
	frames[0].ebp = addr.off = EBP_reg(&DEBUG_context);

        while (addr.off)
        {
            FRAME32 *frame = (FRAME32 *)addr.off;
            if (!DBG_CHECK_READ_PTR( &addr, sizeof(FRAME32) )) return;
            if (!frame->ip) break;
            nframe++;
            frames = (struct bt_info *)xrealloc(frames,
                                                nframe*sizeof(struct bt_info));
            fprintf(stderr,"%s%d ", (frameno == curr_frame ? "=>" : "  "),
		    frameno);
            addr.off = frame->ip;
	    frames[frameno].eip = addr.off;
	    frames[frameno].ebp = frame->bp;
            frames[frameno].frame = DEBUG_PrintAddressAndArgs( &addr, 32, 
							frame->bp, TRUE );
	    frameno++;
            fprintf( stderr, "\n" );
            addr.off = frame->bp;
        }
    }
    else  /* 16-bit mode */
    {
      WORD ss = SS_reg(&DEBUG_context), cs = CS_reg(&DEBUG_context);
      if (GET_SEL_FLAGS(ss) & LDT_FLAGS_32BIT)
      {
          fprintf( stderr, "Not implemented: 32-bit backtrace on a different stack segment.\n" );
          return;
      }
      fprintf( stderr,"%d ", frameno++ );
      addr.seg = cs;
      addr.off = IP_reg(&DEBUG_context);
      DEBUG_PrintAddress( &addr, 16, TRUE );
      fprintf( stderr, "\n" );
      addr.seg = ss;
      addr.off = BP_reg(&DEBUG_context) & ~1;
      for (;;)
      {
          FRAME16 *frame = (FRAME16 *)DBG_ADDR_TO_LIN(&addr);
          if (!DBG_CHECK_READ_PTR( &addr, sizeof(FRAME16) )) return;
          if (!frame->bp) break;
          if (frame->bp & 1) cs = frame->cs;
          fprintf( stderr,"%d ", frameno++ );
          addr.seg = cs;
          addr.off = frame->ip;
          DEBUG_PrintAddress( &addr, 16, TRUE );
          fprintf( stderr, "\n" );
          addr.seg = ss;
          addr.off = frame->bp & ~1;
      }
  }
  fprintf( stderr, "\n" );
}

/***********************************************************************
 *           DEBUG_SilentBackTrace
 *
 * Display a stack back-trace.
 */
void DEBUG_SilentBackTrace(void)
{
    DBG_ADDR addr;
    int frameno = 0;

    nframe = 1;
    if (frames) free( frames );
    frames = (struct bt_info *) xmalloc( sizeof(struct bt_info) );

    if (SS_reg(&DEBUG_context) == WINE_DATA_SELECTOR)  /* 32-bit mode */
    {
        addr.seg = 0;
        addr.off = EIP_reg(&DEBUG_context);
	frames[0].eip = addr.off;
	DEBUG_FindNearestSymbol( &addr, TRUE, &frames[0].frame.sym, 0, 
						&frames[0].frame.list);
	frames[0].ebp = addr.off = EBP_reg(&DEBUG_context);
	frameno++;

        while (addr.off)
        {
            FRAME32 *frame = (FRAME32 *)addr.off;
            if (!DBG_CHECK_READ_PTR( &addr, sizeof(FRAME32) )) return;
            if (!frame->ip) break;
            nframe++;
            frames = (struct bt_info *)xrealloc(frames,
                                                nframe*sizeof(struct bt_info));
            addr.off = frame->ip;
	    frames[frameno].eip = addr.off;
	    frames[frameno].ebp = frame->bp;
	    DEBUG_FindNearestSymbol( &addr, TRUE, 
				     &frames[frameno].frame.sym, frame->bp, 
				     &frames[frameno].frame.list);
	    frameno++;
            addr.off = frame->bp;
        }
    }
    else  /* 16-bit mode */
    {
      /*
       * Not implemented here.  I am not entirely sure how best to handle
       * this stuff.
       */
    }
}

int
DEBUG_SetFrame(int newframe)
{
  int		rtn = FALSE;

  curr_frame = newframe;

  if( curr_frame >= nframe )
    {
      curr_frame = nframe - 1;
    }

  if( curr_frame < 0 )
    {
      curr_frame = 0;
    }

   if( frames[curr_frame].frame.list.sourcefile != NULL )
    {
      DEBUG_List(&frames[curr_frame].frame.list, NULL, 0);
    }

  rtn = TRUE;
  return (rtn);
}

int
DEBUG_GetCurrentFrame(struct name_hash ** name, unsigned int * eip,
		      unsigned int * ebp)
{
  /*
   * If we don't have a valid backtrace, then just return.
   */
  if( frames == NULL )
    {
      return FALSE;
    }

  /*
   * If we don't know what the current function is, then we also have
   * nothing to report here.
   */
  if( frames[curr_frame].frame.sym == NULL )
    {
      return FALSE;
    }

  *name = frames[curr_frame].frame.sym;
  *eip = frames[curr_frame].eip;
  *ebp = frames[curr_frame].ebp;

  return TRUE;
}

