223 lines
5.8 KiB
C
223 lines
5.8 KiB
C
/*
|
|
** Copyright (c) 1996
|
|
** Michael Smith. All rights reserved.
|
|
**
|
|
** Redistribution and use in source and binary forms, with or without
|
|
** modification, are permitted provided that the following conditions
|
|
** are met:
|
|
** 1. Redistributions of source code must retain the above copyright
|
|
** notice, this list of conditions and the following disclaimer.
|
|
** 2. Redistributions in binary form must reproduce the above copyright
|
|
** notice, this list of conditions and the following disclaimer in the
|
|
** documentation and/or other materials provided with the distribution.
|
|
**
|
|
** THIS SOFTWARE IS PROVIDED BY Michael Smith ``AS IS'' AND
|
|
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
** ARE DISCLAIMED. IN NO EVENT SHALL Michael Smith BE LIABLE
|
|
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
** SUCH DAMAGE.
|
|
**
|
|
** $FreeBSD$
|
|
*/
|
|
|
|
/******************************************************************************
|
|
** Abstractions to hide register access methods across different platforms.
|
|
**
|
|
*/
|
|
|
|
#define NEW_REGISTERS
|
|
|
|
#ifndef _MACHINE_VM86_H_
|
|
|
|
/* standard register representation */
|
|
typedef union
|
|
{
|
|
u_long r_ex;
|
|
struct
|
|
{
|
|
u_short r_x;
|
|
u_short :16;
|
|
} r_w;
|
|
struct
|
|
{
|
|
u_char r_l;
|
|
u_char r_h;
|
|
u_short :16;
|
|
} r_b;
|
|
} reg86_t;
|
|
|
|
#endif
|
|
|
|
#ifdef __FreeBSD__
|
|
|
|
/* layout must match definition of struct sigcontext in <machine/signal.h> */
|
|
|
|
typedef struct
|
|
{
|
|
int pad[2];
|
|
reg86_t esp;
|
|
reg86_t ebp;
|
|
reg86_t isp;
|
|
reg86_t eip;
|
|
reg86_t efl;
|
|
reg86_t es;
|
|
reg86_t ds;
|
|
reg86_t cs;
|
|
reg86_t ss;
|
|
reg86_t edi;
|
|
reg86_t esi;
|
|
reg86_t ebx;
|
|
reg86_t edx;
|
|
reg86_t ecx;
|
|
reg86_t eax;
|
|
reg86_t gs;
|
|
reg86_t fs;
|
|
} registers_t;
|
|
|
|
typedef union
|
|
{
|
|
struct sigcontext sc;
|
|
registers_t r;
|
|
} regcontext_t;
|
|
|
|
/*
|
|
** passed around as a reference to the registers. This must be in
|
|
** scope for the following register macros to work.
|
|
*/
|
|
|
|
/* register shorthands */
|
|
#define R_ESP (REGS->r.esp.r_ex)
|
|
#define R_SP (REGS->r.esp.r_w.r_x)
|
|
#define R_EBP (REGS->r.ebp.r_ex)
|
|
#define R_BP (REGS->r.ebp.r_w.r_x)
|
|
#define R_ISP (REGS->r.isp.r_ex)
|
|
#define R_EIP (REGS->r.eip.r_ex)
|
|
#define R_IP (REGS->r.eip.r_w.r_x)
|
|
#define R_EFLAGS (REGS->r.efl.r_ex)
|
|
#define R_FLAGS (REGS->r.efl.r_w.r_x)
|
|
#define R_EES (REGS->r.es.r_ex)
|
|
#define R_ES (REGS->r.es.r_w.r_x)
|
|
#define R_EDS (REGS->r.ds.r_ex)
|
|
#define R_DS (REGS->r.ds.r_w.r_x)
|
|
#define R_ECS (REGS->r.cs.r_ex)
|
|
#define R_CS (REGS->r.cs.r_w.r_x)
|
|
#define R_ESS (REGS->r.ss.r_ex)
|
|
#define R_SS (REGS->r.ss.r_w.r_x)
|
|
#define R_EDI (REGS->r.edi.r_ex)
|
|
#define R_DI (REGS->r.edi.r_w.r_x)
|
|
#define R_ESI (REGS->r.esi.r_ex)
|
|
#define R_SI (REGS->r.esi.r_w.r_x)
|
|
#define R_EBX (REGS->r.ebx.r_ex)
|
|
#define R_BX (REGS->r.ebx.r_w.r_x)
|
|
#define R_BL (REGS->r.ebx.r_b.r_l)
|
|
#define R_BH (REGS->r.ebx.r_b.r_h)
|
|
#define R_EDX (REGS->r.edx.r_ex)
|
|
#define R_DX (REGS->r.edx.r_w.r_x)
|
|
#define R_DL (REGS->r.edx.r_b.r_l)
|
|
#define R_DH (REGS->r.edx.r_b.r_h)
|
|
#define R_ECX (REGS->r.ecx.r_ex)
|
|
#define R_CX (REGS->r.ecx.r_w.r_x)
|
|
#define R_CL (REGS->r.ecx.r_b.r_l)
|
|
#define R_CH (REGS->r.ecx.r_b.r_h)
|
|
#define R_EAX (REGS->r.eax.r_ex)
|
|
#define R_AX (REGS->r.eax.r_w.r_x)
|
|
#define R_AL (REGS->r.eax.r_b.r_l)
|
|
#define R_AH (REGS->r.eax.r_b.r_h)
|
|
#define R_EGS (REGS->r.gs.r_ex)
|
|
#define R_GS (REGS->r.gs.r_w.r_x)
|
|
#define R_EFS (REGS->r.fs.r_ex)
|
|
#define R_FS (REGS->r.fs.r_w.r_x)
|
|
|
|
#endif
|
|
|
|
#ifdef __bsdi__
|
|
#endif
|
|
|
|
#ifdef __NetBSD__
|
|
#endif
|
|
|
|
/*
|
|
** register manipulation macros
|
|
*/
|
|
|
|
#define N_PUTVEC(s, o, x) ((s) = ((x) >> 16), (o) = (x) & 0xffff)
|
|
#define MAKEVEC(s, o) (((s) << 16) + (o)) /* XXX these two should be combined */
|
|
#define N_GETVEC(s, o) (((s) << 16) + (o))
|
|
|
|
#define N_PUTPTR(s, o, x) (((s) = ((x) & 0xf0000) >> 4), (o) = (x) & 0xffff)
|
|
#define MAKEPTR(s, o) (((s) << 4) + (o)) /* XXX these two should be combined */
|
|
#define N_GETPTR(s, o) (((s) << 4) + (o))
|
|
|
|
#define VECPTR(x) MAKEPTR((x) >> 16, (x) & 0xffff)
|
|
|
|
#if 0
|
|
#define N_REGISTERS regcontext_t *_regcontext
|
|
#define N_REGS _regcontex
|
|
#endif
|
|
|
|
inline static void
|
|
N_PUSH(u_short x, regcontext_t *REGS)
|
|
{
|
|
R_SP -= 2;
|
|
*(u_short *)N_GETPTR(R_SS, R_SP) = (x);
|
|
}
|
|
|
|
inline static u_short
|
|
N_POP(regcontext_t *REGS)
|
|
{
|
|
u_short x;
|
|
|
|
x = *(u_short *)N_GETPTR(R_SS, R_SP);
|
|
R_SP += 2;
|
|
return(x);
|
|
}
|
|
|
|
# ifndef PSL_ALLCC /* Grr, FreeBSD doesn't have this */
|
|
# define PSL_ALLCC (PSL_C|PSL_PF|PSL_AF|PSL_Z|PSL_N)
|
|
# endif
|
|
|
|
/******************************************************************************
|
|
** older stuff below here
|
|
*/
|
|
|
|
#define REGISTERS struct sigcontext *sc
|
|
|
|
#define GET16(x) (x & 0xffff)
|
|
#define GET8L(x) (x & 0xff)
|
|
#define GET8H(x) ((x >> 8) & 0xff)
|
|
#define SET16(x, y) (x = (x & ~0xffff) | (y & 0xffff))
|
|
#define SET8L(x, y) (x = (x & ~0xff) | (y & 0xff))
|
|
#define SET8H(x, y) (x = (x & ~0xff00) | ((y & 0xff) << 8))
|
|
|
|
#define PUTVEC(s, o, x) (SET16(s, x >> 16), SET16(o, x))
|
|
#define GETVEC(s, o) MAKEVEC(GET16(s), GET16(o))
|
|
|
|
#define PUTPTR(s, o, x) (SET16(s, (x & 0xf0000) >> 4), SET16(o, x))
|
|
#define GETPTR(s, o) MAKEPTR(GET16(s), GET16(o))
|
|
|
|
#define VECPTR(x) MAKEPTR((x) >> 16, (x) & 0xffff)
|
|
|
|
inline static void
|
|
PUSH(u_short x, struct sigcontext *sc)
|
|
{
|
|
SET16(sc->sc_esp, GET16(sc->sc_esp) - 2);
|
|
*(u_short *)GETPTR(sc->sc_ss, sc->sc_esp) = x;
|
|
}
|
|
|
|
inline static u_short
|
|
POP(struct sigcontext *sc)
|
|
{
|
|
u_short x;
|
|
|
|
x = *(u_short *)GETPTR(sc->sc_ss, sc->sc_esp);
|
|
SET16(sc->sc_esp, GET16(sc->sc_esp) + 2);
|
|
return (x);
|
|
}
|
|
|