/*
 * Debugger break-points handling
 *
 * Copyright 1994 Martin von Loewis
 * Copyright 1995 Alexandre Julliard
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include "windows.h"
#include "debugger.h"

#define INT3          0xcc   /* int 3 opcode */
#define STEP_FLAG     0x100  /* single-step flag */

#define MAX_BREAKPOINTS 25

typedef struct
{
    DBG_ADDR    addr;
    BYTE        addrlen;
    BYTE        opcode;
    BOOL        enabled;
    BOOL        in_use;
} BREAKPOINT;

static BREAKPOINT breakpoints[MAX_BREAKPOINTS];

static int next_bp = 1;  /* breakpoint 0 is reserved for step-over */


/***********************************************************************
 *           DEBUG_ChangeOpcode
 *
 * Change the opcode at segment:addr.
 */
static void DEBUG_SetOpcode( const DBG_ADDR *addr, BYTE op )
{
    if (addr->seg)
    {
        *(BYTE *)PTR_SEG_OFF_TO_LIN( addr->seg, addr->off ) = op;
    }
    else  /* 32-bit code, so we have to change the protection first */
    {
        /* There are a couple of problems with this. On Linux prior to
           1.1.62, this call fails (ENOACCESS) due to a bug in fs/exec.c.
           This code is currently not tested at all on BSD.
           How do I determine the page size in a more symbolic manner?
           And why does mprotect need that start address of the page
           in the first place?
           Not that portability matters, this code is i386 only anyways...
           How do I get the old protection in order to restore it later on?
        */
        if (mprotect((caddr_t)(addr->off & (~4095)), 4096,
                     PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
        {
            perror( "Can't set break point" );
            return;
	}
        *(BYTE *)addr->off = op;
	mprotect((caddr_t)(addr->off & ~4095), 4096,
                  PROT_READ | PROT_EXEC );
    }
}


/***********************************************************************
 *           DEBUG_SetBreakpoints
 *
 * Set or remove all the breakpoints.
 */
void DEBUG_SetBreakpoints( BOOL set )
{
    int i;

    for (i = 0; i < MAX_BREAKPOINTS; i++)
    {
        if (breakpoints[i].in_use && breakpoints[i].enabled)
            DEBUG_SetOpcode( &breakpoints[i].addr,
                             set ? INT3 : breakpoints[i].opcode );
    }
}


/***********************************************************************
 *           DEBUG_FindBreakpoint
 *
 * Find the breakpoint for a given address. Return the breakpoint
 * number or -1 if none.
 */
int DEBUG_FindBreakpoint( const DBG_ADDR *addr )
{
    int i;

    for (i = 0; i < MAX_BREAKPOINTS; i++)
    {
        if (breakpoints[i].in_use && breakpoints[i].enabled &&
            breakpoints[i].addr.seg == addr->seg &&
            breakpoints[i].addr.off == addr->off) return i;
    }
    return -1;
}


/***********************************************************************
 *           DEBUG_AddBreakpoint
 *
 * Add a breakpoint.
 */
void DEBUG_AddBreakpoint( const DBG_ADDR *address )
{
    DBG_ADDR addr = *address;
    int num;
    BYTE *p;

    DBG_FIX_ADDR_SEG( &addr, CS_reg(DEBUG_context) );

    if (next_bp < MAX_BREAKPOINTS)
        num = next_bp++;
    else  /* try to find an empty slot */  
    {
        for (num = 1; num < MAX_BREAKPOINTS; num++)
            if (!breakpoints[num].in_use) break;
        if (num >= MAX_BREAKPOINTS)
        {
            fprintf( stderr, "Too many breakpoints. Please delete some.\n" );
            return;
        }
    }
    p = DBG_ADDR_TO_LIN( &addr );
    breakpoints[num].addr    = addr;
    breakpoints[num].addrlen = !addr.seg ? 32 :
                         (GET_SEL_FLAGS(addr.seg) & LDT_FLAGS_32BIT) ? 32 : 16;
    breakpoints[num].opcode  = *p;
    breakpoints[num].enabled = TRUE;
    breakpoints[num].in_use  = TRUE;
    fprintf( stderr, "Breakpoint %d at ", num );
    DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].addrlen );
    fprintf( stderr, "\n" );
}


/***********************************************************************
 *           DEBUG_DelBreakpoint
 *
 * Delete a breakpoint.
 */
void DEBUG_DelBreakpoint( int num )
{
    if ((num <= 0) || (num >= next_bp) || !breakpoints[num].in_use)
    {
        fprintf( stderr, "Invalid breakpoint number %d\n", num );
        return;
    }
    breakpoints[num].enabled = FALSE;
    breakpoints[num].in_use  = FALSE;
}


/***********************************************************************
 *           DEBUG_EnableBreakpoint
 *
 * Enable or disable a break point.
 */
void DEBUG_EnableBreakpoint( int num, BOOL enable )
{
    if ((num <= 0) || (num >= next_bp) || !breakpoints[num].in_use)
    {
        fprintf( stderr, "Invalid breakpoint number %d\n", num );
        return;
    }
    breakpoints[num].enabled = enable;
}


/***********************************************************************
 *           DEBUG_InfoBreakpoints
 *
 * Display break points information.
 */
void DEBUG_InfoBreakpoints(void)
{
    int i;

    fprintf( stderr, "Breakpoints:\n" );
    for (i = 1; i < next_bp; i++)
    {
        if (breakpoints[i].in_use)
        {
            fprintf( stderr, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
            DEBUG_PrintAddress( &breakpoints[i].addr, breakpoints[i].addrlen );
            fprintf( stderr, "\n" );
        }
    }
}


/***********************************************************************
 *           DEBUG_ShouldContinue
 *
 * Determine if we should continue execution after a SIGTRAP signal when
 * executing in the given mode.
 */
BOOL DEBUG_ShouldContinue( struct sigcontext_struct *context,
                           enum exec_mode mode )
{
    DBG_ADDR addr;
    int bpnum;

      /* If not single-stepping, back up over the int3 instruction */
    if (!(EFL_reg(DEBUG_context) & STEP_FLAG)) EIP_reg(DEBUG_context)--;

    addr.seg = (CS_reg(DEBUG_context) == WINE_CODE_SELECTOR) ? 
                0 : CS_reg(DEBUG_context);
    addr.off = EIP_reg(DEBUG_context);
        
    bpnum  = DEBUG_FindBreakpoint( &addr );
    breakpoints[0].enabled = 0;  /* disable the step-over breakpoint */

    if ((bpnum != 0) && (bpnum != -1))
    {
        fprintf( stderr, "Stopped on breakpoint %d at ", bpnum );
        DEBUG_PrintAddress( &breakpoints[bpnum].addr,
                            breakpoints[bpnum].addrlen );
        fprintf( stderr, "\n" );
        return FALSE;
    }
      /* no breakpoint, continue if in continuous mode */
    return (mode == EXEC_CONT);
}


/***********************************************************************
 *           DEBUG_RestartExecution
 *
 * Set the breakpoints to the correct state to restart execution
 * in the given mode.
 */
void DEBUG_RestartExecution( struct sigcontext_struct *context,
                             enum exec_mode mode, int instr_len )
{
    DBG_ADDR addr;

    addr.seg = (CS_reg(DEBUG_context) == WINE_CODE_SELECTOR) ?
                0 : CS_reg(DEBUG_context);
    addr.off = EIP_reg(DEBUG_context);

    if (DEBUG_FindBreakpoint( &addr ) != -1)
        mode = EXEC_STEP_INSTR;  /* If there's a breakpoint, skip it */

    switch(mode)
    {
    case EXEC_CONT: /* Continuous execution */
        EFL_reg(DEBUG_context) &= ~STEP_FLAG;
        DEBUG_SetBreakpoints( TRUE );
        break;

    case EXEC_STEP_OVER:  /* Stepping over a call */
        EFL_reg(DEBUG_context) &= ~STEP_FLAG;
        addr.off += instr_len;
        breakpoints[0].addr    = addr;
        breakpoints[0].enabled = TRUE;
        breakpoints[0].in_use  = TRUE;
        breakpoints[0].opcode  = *(BYTE *)DBG_ADDR_TO_LIN( &addr );
        DEBUG_SetBreakpoints( TRUE );
        break;

    case EXEC_STEP_INSTR: /* Single-stepping an instruction */
        EFL_reg(DEBUG_context) |= STEP_FLAG;
        break;
    }
}
