Upgrade Unwind Express (libuwx) to BETA 5. This upgrade includes
all the fixes locally applied and submitted to the author. Not included in BETA 5, but part of this import are: o FreeBSD specific ifdefs to make this compile within a kernel. These are limited to include directives and defines. o Removal of unused variables, proper casts and initializations to allow building with -Werror. This happens in code so has a higher chance of causing future import conflicts but not enough to worry about it. I'm especially thankful that the author accepted the change to replace DISABLE_TRACE with UWX_TRACE_ENABLE so that we can use it in kernel config files without nasty mappings or indirections as that would make the integration less perfect. Thanks Cary!
This commit is contained in:
parent
3289b51a91
commit
2f9c5f7f57
@ -8,11 +8,11 @@
|
||||
AR = ar
|
||||
RANLIB = :
|
||||
|
||||
OTHERCFLAGS =
|
||||
# OTHERCFLAGS = -DUWX_TRACE_ENABLE # Enables trace output
|
||||
# OTHERCFLAGS = +DD64 # Builds 64-bit library
|
||||
OTHERCFLAGS =
|
||||
|
||||
CFLAGS = +W944 -O $(OTHERCFLAGS)
|
||||
CFLAGS = -O $(OTHERCFLAGS)
|
||||
|
||||
OBJS = uwx_bstream.o uwx_context.o uwx_env.o uwx_scoreboard.o \
|
||||
uwx_step.o uwx_str.o uwx_swap.o uwx_trace.o uwx_uinfo.o \
|
||||
@ -36,7 +36,7 @@ libuwx.sl: $(OBJS) $(SELFOBJS)
|
||||
|
||||
uwx_bstream.o: uwx.h uwx_env.h uwx_bstream.h
|
||||
|
||||
uwx_context.o: uwx.h uwx_env.h uwx_scoreboard.h uwx_trace.h
|
||||
uwx_context.o: uwx.h uwx_env.h uwx_scoreboard.h uwx_step.h uwx_trace.h
|
||||
|
||||
uwx_env.o: uwx.h uwx_env.h uwx_scoreboard.h uwx_str.h uwx_trace.h
|
||||
|
||||
|
@ -208,18 +208,26 @@ extern int uwx_get_abi_context_code(struct uwx_env *env);
|
||||
#define UWX_REG_CFM 3 /* cfm (no spill info) */
|
||||
#define UWX_REG_RP 4 /* rp (pseudo-register) */
|
||||
#define UWX_REG_PSP 5 /* psp (pseudo-register) */
|
||||
#define UWX_REG_PFS 6 /* ar.pfs */
|
||||
#define UWX_REG_PFS 6 /* pfs (pseudo-register) */
|
||||
#define UWX_REG_PREDS 7 /* p0 - p63 */
|
||||
#define UWX_REG_PRIUNAT 8 /* primary unat (pseudo-register) */
|
||||
#define UWX_REG_BSPSTORE 9 /* ar.bspstore */
|
||||
#define UWX_REG_RNAT 10 /* ar.rnat */
|
||||
#define UWX_REG_UNAT 11 /* ar.unat */
|
||||
#define UWX_REG_FPSR 12 /* ar.fpsr */
|
||||
#define UWX_REG_LC 13 /* ar.lc */
|
||||
#define UWX_REG_AR_PFS 9 /* ar.pfs */
|
||||
#define UWX_REG_AR_BSPSTORE 10 /* ar.bspstore */
|
||||
#define UWX_REG_AR_RNAT 11 /* ar.rnat */
|
||||
#define UWX_REG_AR_UNAT 12 /* ar.unat */
|
||||
#define UWX_REG_AR_FPSR 13 /* ar.fpsr */
|
||||
#define UWX_REG_AR_LC 14 /* ar.lc */
|
||||
#define UWX_REG_GR(gr) (0x100 | (gr))
|
||||
#define UWX_REG_FR(fr) (0x200 | (fr))
|
||||
#define UWX_REG_BR(br) (0x300 | (br))
|
||||
|
||||
/* for backwards compatibility with previous releases... */
|
||||
#define UWX_REG_BSPSTORE UWX_REG_AR_BSPSTORE
|
||||
#define UWX_REG_RNAT UWX_REG_AR_RNAT
|
||||
#define UWX_REG_UNAT UWX_REG_AR_UNAT
|
||||
#define UWX_REG_FPSR UWX_REG_AR_FPSR
|
||||
#define UWX_REG_LC UWX_REG_AR_LC
|
||||
|
||||
/* Values corresponding to UWX_KEY_SPILL keys indicate the disposition */
|
||||
/* of the spilled register -- either in the memory stack or in another */
|
||||
/* register. The PSP register may also have a disposition of "SPPLUS", */
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "uwx_env.h"
|
||||
#include "uwx_context.h"
|
||||
#include "uwx_scoreboard.h"
|
||||
#include "uwx_step.h"
|
||||
#include "uwx_trace.h"
|
||||
|
||||
int uwx_init_context(
|
||||
@ -46,6 +47,7 @@ int uwx_init_context(
|
||||
for (i = 0; i < NPRESERVEDGR; i++)
|
||||
env->context.gr[i] = 0;
|
||||
env->context.valid_regs = VALID_BASIC4;
|
||||
env->context.valid_frs = 0;
|
||||
env->rstate = 0;
|
||||
(void)uwx_init_history(env);
|
||||
return UWX_OK;
|
||||
@ -64,8 +66,17 @@ int uwx_get_reg(struct uwx_env *env, int regid, uint64_t *valp)
|
||||
|
||||
status = UWX_OK;
|
||||
|
||||
if (regid == UWX_REG_GR(12))
|
||||
regid = UWX_REG_SP;
|
||||
if (regid < NSPECIALREG && (env->context.valid_regs & (1 << regid)))
|
||||
*valp = env->context.special[regid];
|
||||
else if (regid == UWX_REG_PSP || regid == UWX_REG_RP ||
|
||||
regid == UWX_REG_PFS) {
|
||||
status = uwx_restore_markers(env);
|
||||
if (status != UWX_OK)
|
||||
return status;
|
||||
*valp = env->context.special[regid];
|
||||
}
|
||||
else if (regid >= UWX_REG_GR(4) && regid <= UWX_REG_GR(7) &&
|
||||
(env->context.valid_regs &
|
||||
(1 << (regid - UWX_REG_GR(4) + VALID_GR_SHIFT))) )
|
||||
@ -94,13 +105,13 @@ int uwx_get_reg(struct uwx_env *env, int regid, uint64_t *valp)
|
||||
(env->context.valid_regs &
|
||||
(1 << (regid - UWX_REG_BR(1) + VALID_BR_SHIFT))) )
|
||||
*valp = env->context.br[regid - UWX_REG_BR(1)];
|
||||
else if (regid >= UWX_REG_FR(2) && regid <= UWX_REG_BR(5) &&
|
||||
(env->context.valid_frs & (1 << (regid - UWX_REG_FR(2)))) ) {
|
||||
else if (regid >= UWX_REG_FR(2) && regid <= UWX_REG_FR(5) &&
|
||||
(env->context.valid_frs & (1 << (regid - UWX_REG_FR(2)))) ) {
|
||||
valp[0] = env->context.fr[regid - UWX_REG_FR(2)].part0;
|
||||
valp[1] = env->context.fr[regid - UWX_REG_FR(2)].part1;
|
||||
}
|
||||
else if (regid >= UWX_REG_FR(16) && regid <= UWX_REG_BR(31) &&
|
||||
(env->context.valid_frs & (1 << (regid - UWX_REG_FR(2)))) ) {
|
||||
else if (regid >= UWX_REG_FR(16) && regid <= UWX_REG_FR(31) &&
|
||||
(env->context.valid_frs & (1 << (regid - UWX_REG_FR(16) + 4))) ) {
|
||||
valp[0] = env->context.fr[regid - UWX_REG_FR(16) + 4].part0;
|
||||
valp[1] = env->context.fr[regid - UWX_REG_FR(16) + 4].part1;
|
||||
}
|
||||
@ -114,7 +125,7 @@ int uwx_get_reg(struct uwx_env *env, int regid, uint64_t *valp)
|
||||
if (n != DWORDSZ)
|
||||
status = UWX_ERR_COPYIN_REG;
|
||||
}
|
||||
else if (regid >= UWX_REG_FR(2) && regid <= UWX_REG_BR(127)) {
|
||||
else if (regid >= UWX_REG_FR(2) && regid <= UWX_REG_FR(127)) {
|
||||
if (env->copyin == 0)
|
||||
return UWX_ERR_NOCALLBACKS;
|
||||
n = (*env->copyin)(UWX_COPYIN_REG, (char *)valp,
|
||||
@ -170,7 +181,7 @@ int uwx_get_nat(struct uwx_env *env, int regid, int *natp)
|
||||
natcollp = bsp | 0x01f8;
|
||||
if (natcollp >= bsp)
|
||||
n = (*env->copyin)(UWX_COPYIN_REG, (char *)&natcoll,
|
||||
(uint64_t)UWX_REG_RNAT, DWORDSZ, env->cb_token);
|
||||
(uint64_t)UWX_REG_AR_RNAT, DWORDSZ, env->cb_token);
|
||||
else
|
||||
n = (*env->copyin)(UWX_COPYIN_RSTACK, (char *)&natcoll,
|
||||
bsp, DWORDSZ, env->cb_token);
|
||||
@ -197,6 +208,8 @@ int uwx_get_spill_loc(struct uwx_env *env, int regid, uint64_t *dispp)
|
||||
|
||||
status = UWX_OK;
|
||||
|
||||
if (regid == UWX_REG_GR(12))
|
||||
regid = UWX_REG_SP;
|
||||
if (regid < NSPECIALREG)
|
||||
*dispp = env->history.special[regid];
|
||||
else if (regid >= UWX_REG_GR(4) && regid <= UWX_REG_GR(7))
|
||||
@ -233,6 +246,8 @@ int uwx_set_reg(struct uwx_env *env, int regid, uint64_t val)
|
||||
if (env == 0)
|
||||
return UWX_ERR_NOENV;
|
||||
|
||||
if (regid == UWX_REG_GR(12))
|
||||
regid = UWX_REG_SP;
|
||||
if (regid < NSPECIALREG) {
|
||||
env->context.special[regid] = val;
|
||||
env->context.valid_regs |= 1 << regid;
|
||||
|
@ -39,7 +39,7 @@ struct uwx_scoreboard;
|
||||
|
||||
#define NSCOREBOARDS 8 /* Initial allocation of scoreboards */
|
||||
|
||||
#define NSPECIALREG 14
|
||||
#define NSPECIALREG 16 /* Must be even, so FRs are aligned */
|
||||
#define NPRESERVEDGR 4
|
||||
#define NPRESERVEDBR 5
|
||||
#define NPRESERVEDFR 20
|
||||
@ -61,7 +61,8 @@ struct uwx_context {
|
||||
#define VALID_GR_SHIFT NSPECIALREG
|
||||
#define VALID_BR_SHIFT (NSPECIALREG + NPRESERVEDGR)
|
||||
|
||||
#define VALID_BASIC4 0x0f /* IP, SP, BSP, PFS */
|
||||
#define VALID_BASIC4 0x0f /* IP, SP, BSP, CFM */
|
||||
#define VALID_MARKERS 0x70 /* RP, PSP, PFS */
|
||||
|
||||
struct uwx_history {
|
||||
uint64_t special[NSPECIALREG];
|
||||
|
@ -63,8 +63,8 @@ struct uwx_scoreboard *uwx_alloc_scoreboard(struct uwx_env *env)
|
||||
sb->rstate[i] = UWX_DISP_NONE;
|
||||
sb->rstate[SBREG_RP] = UWX_DISP_REG(UWX_REG_BR(0));
|
||||
sb->rstate[SBREG_PSP] = UWX_DISP_SPPLUS(0);
|
||||
sb->rstate[SBREG_PFS] = UWX_DISP_REG(UWX_REG_PFS);
|
||||
sb->rstate[SBREG_PRIUNAT] = UWX_DISP_REG(UWX_REG_UNAT);
|
||||
sb->rstate[SBREG_PFS] = UWX_DISP_REG(UWX_REG_AR_PFS);
|
||||
sb->rstate[SBREG_PRIUNAT] = UWX_DISP_REG(UWX_REG_AR_UNAT);
|
||||
sb->label = 0;
|
||||
return sb;
|
||||
}
|
||||
|
@ -91,18 +91,33 @@ int uwx_self_init_from_sigcontext(
|
||||
uint64_t cfm;
|
||||
unsigned int nat;
|
||||
uint64_t ec;
|
||||
int adj;
|
||||
|
||||
info->ucontext = ucontext;
|
||||
status = __uc_get_reason(ucontext, &reason);
|
||||
status = __uc_get_ip(ucontext, &ip);
|
||||
status = __uc_get_grs(ucontext, 12, 1, &sp, &nat);
|
||||
status = __uc_get_cfm(ucontext, &cfm);
|
||||
#ifdef NEW_UC_GET_AR
|
||||
status = __uc_get_ar_bsp(ucontext, &bsp);
|
||||
status = __uc_get_ar_bspstore(ucontext, &info->bspstore);
|
||||
status = __uc_get_ar_ec(ucontext, &ec);
|
||||
#else
|
||||
status = __uc_get_ar(ucontext, 17, &bsp);
|
||||
status = __uc_get_ar(ucontext, 18, &info->bspstore);
|
||||
status = __uc_get_ar(ucontext, 66, &ec);
|
||||
status = __uc_get_cfm(ucontext, &cfm);
|
||||
cfm |= ec << 52;
|
||||
#endif
|
||||
/* The returned bsp needs to be adjusted. */
|
||||
/* For interrupt frames, where bsp was advanced by a cover */
|
||||
/* instruction, subtract sof (size of frame). For non-interrupt */
|
||||
/* frames, where bsp was advanced by br.call, subtract sol */
|
||||
/* (size of locals). */
|
||||
if (reason != 0)
|
||||
bsp = uwx_add_to_bsp(bsp, -((unsigned int)cfm & 0x7f));
|
||||
adj = (unsigned int)cfm & 0x7f; /* interrupt frame */
|
||||
else
|
||||
adj = ((unsigned int)cfm >> 7) & 0x7f; /* non-interrupt frame */
|
||||
bsp = uwx_add_to_bsp(bsp, -adj);
|
||||
cfm |= ec << 52;
|
||||
uwx_init_context(env, ip, sp, bsp, cfm);
|
||||
return UWX_OK;
|
||||
}
|
||||
@ -171,22 +186,22 @@ int uwx_self_copyin(
|
||||
regid = (int)rem;
|
||||
if (rem < UWX_REG_GR(0)) {
|
||||
switch (regid) {
|
||||
case UWX_REG_PFS:
|
||||
status = __uc_get_ar(info->ucontext, 64, dp);
|
||||
break;
|
||||
case UWX_REG_PREDS:
|
||||
status = __uc_get_prs(info->ucontext, dp);
|
||||
break;
|
||||
case UWX_REG_RNAT:
|
||||
case UWX_REG_AR_PFS:
|
||||
status = __uc_get_ar(info->ucontext, 64, dp);
|
||||
break;
|
||||
case UWX_REG_AR_RNAT:
|
||||
status = __uc_get_ar(info->ucontext, 19, dp);
|
||||
break;
|
||||
case UWX_REG_UNAT:
|
||||
case UWX_REG_AR_UNAT:
|
||||
status = __uc_get_ar(info->ucontext, 36, dp);
|
||||
break;
|
||||
case UWX_REG_FPSR:
|
||||
case UWX_REG_AR_FPSR:
|
||||
status = __uc_get_ar(info->ucontext, 40, dp);
|
||||
break;
|
||||
case UWX_REG_LC:
|
||||
case UWX_REG_AR_LC:
|
||||
status = __uc_get_ar(info->ucontext, 65, dp);
|
||||
break;
|
||||
default:
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "uwx_uinfo.h"
|
||||
#include "uwx_scoreboard.h"
|
||||
#include "uwx_str.h"
|
||||
#include "uwx_step.h"
|
||||
#include "uwx_trace.h"
|
||||
|
||||
/*
|
||||
@ -44,6 +45,8 @@
|
||||
int uwx_decode_uvec(struct uwx_env *env, uint64_t *uvec, uint64_t **rstate);
|
||||
int uwx_restore_reg(struct uwx_env *env, uint64_t rstate,
|
||||
uint64_t *valp, uint64_t *histp);
|
||||
int uwx_restore_freg(struct uwx_env *env, uint64_t rstate,
|
||||
uint64_t *valp, uint64_t *histp);
|
||||
int uwx_restore_nat(struct uwx_env *env, uint64_t rstate, int unat);
|
||||
|
||||
|
||||
@ -59,12 +62,8 @@ int uwx_get_frame_info(struct uwx_env *env)
|
||||
struct uwx_utable_entry uentry;
|
||||
uint64_t uvecout[4];
|
||||
|
||||
if (env == 0)
|
||||
return UWX_ERR_NOENV;
|
||||
if (env->copyin == 0 || env->lookupip == 0)
|
||||
return UWX_ERR_NOCALLBACKS;
|
||||
if ((env->context.valid_regs & VALID_BASIC4) != VALID_BASIC4)
|
||||
return UWX_ERR_NOCONTEXT;
|
||||
|
||||
env->function_offset = -1LL;
|
||||
env->function_name = 0;
|
||||
@ -131,7 +130,63 @@ int uwx_get_frame_info(struct uwx_env *env)
|
||||
}
|
||||
|
||||
|
||||
/* uwx_restore_markers: Restores the stack markers -- PSP, RP, PFS */
|
||||
|
||||
int uwx_restore_markers(struct uwx_env *env)
|
||||
{
|
||||
int status;
|
||||
uint64_t val;
|
||||
uint64_t hist;
|
||||
|
||||
if ((env->context.valid_regs & VALID_BASIC4) != VALID_BASIC4)
|
||||
return UWX_ERR_NOCONTEXT;
|
||||
|
||||
/* If we haven't already obtained the frame info for the */
|
||||
/* current frame, get it now. */
|
||||
|
||||
if (env->rstate == 0) {
|
||||
status = uwx_get_frame_info(env);
|
||||
if (status != UWX_OK)
|
||||
return status;
|
||||
}
|
||||
|
||||
TRACE_S_STEP(env->rstate)
|
||||
|
||||
if (env->rstate[SBREG_PSP] != UWX_DISP_NONE) {
|
||||
status = uwx_restore_reg(env, env->rstate[SBREG_PSP], &val, &hist);
|
||||
if (status != UWX_OK)
|
||||
return status;
|
||||
env->context.special[UWX_REG_PSP] = val;
|
||||
env->history.special[UWX_REG_PSP] = hist;
|
||||
env->context.valid_regs |= 1 << UWX_REG_PSP;
|
||||
TRACE_S_RESTORE_REG("PSP", env->rstate[SBREG_PSP], val)
|
||||
}
|
||||
|
||||
if (env->rstate[SBREG_RP] != UWX_DISP_NONE) {
|
||||
status = uwx_restore_reg(env, env->rstate[SBREG_RP], &val, &hist);
|
||||
if (status != UWX_OK)
|
||||
return status;
|
||||
env->context.special[UWX_REG_RP] = val;
|
||||
env->history.special[UWX_REG_RP] = hist;
|
||||
env->context.valid_regs |= 1 << UWX_REG_RP;
|
||||
TRACE_S_RESTORE_REG("RP", env->rstate[SBREG_RP], val)
|
||||
}
|
||||
|
||||
if (env->rstate[SBREG_PFS] != UWX_DISP_NONE) {
|
||||
status = uwx_restore_reg(env, env->rstate[SBREG_PFS], &val, &hist);
|
||||
if (status != UWX_OK)
|
||||
return status;
|
||||
env->context.special[UWX_REG_PFS] = val;
|
||||
env->history.special[UWX_REG_PFS] = hist;
|
||||
env->context.valid_regs |= 1 << UWX_REG_PFS;
|
||||
TRACE_S_RESTORE_REG("PFS", env->rstate[SBREG_PFS], val)
|
||||
}
|
||||
|
||||
return UWX_OK;
|
||||
}
|
||||
|
||||
/* uwx_get_sym_info: Gets symbolic info from current frame */
|
||||
|
||||
int uwx_get_sym_info(
|
||||
struct uwx_env *env,
|
||||
char **modp,
|
||||
@ -147,10 +202,6 @@ int uwx_get_sym_info(
|
||||
|
||||
if (env == 0)
|
||||
return UWX_ERR_NOENV;
|
||||
if (env->copyin == 0 || env->lookupip == 0)
|
||||
return UWX_ERR_NOCALLBACKS;
|
||||
if ((env->context.valid_regs & VALID_BASIC4) != VALID_BASIC4)
|
||||
return UWX_ERR_NOCONTEXT;
|
||||
|
||||
/* If we haven't already obtained the frame info for the */
|
||||
/* current frame, get it now. */
|
||||
@ -221,48 +272,15 @@ int uwx_step(struct uwx_env *env)
|
||||
|
||||
if (env == 0)
|
||||
return UWX_ERR_NOENV;
|
||||
if (env->copyin == 0 || env->lookupip == 0)
|
||||
return UWX_ERR_NOCALLBACKS;
|
||||
if ((env->context.valid_regs & VALID_BASIC4) != VALID_BASIC4)
|
||||
return UWX_ERR_NOCONTEXT;
|
||||
|
||||
/* If we haven't already obtained the frame info for the */
|
||||
/* current frame, get it now. */
|
||||
|
||||
if (env->rstate == 0) {
|
||||
status = uwx_get_frame_info(env);
|
||||
if (status != UWX_OK)
|
||||
return status;
|
||||
}
|
||||
|
||||
TRACE_S_STEP(env->rstate)
|
||||
|
||||
/* Complete the current context by restoring the current values */
|
||||
/* of psp, rp, and pfs. */
|
||||
|
||||
if (env->rstate[SBREG_PSP] != UWX_DISP_NONE) {
|
||||
status = uwx_restore_reg(env, env->rstate[SBREG_PSP], &val, &hist);
|
||||
if (env->rstate == 0 ||
|
||||
(env->context.valid_regs & VALID_MARKERS) != VALID_MARKERS) {
|
||||
status = uwx_restore_markers(env);
|
||||
if (status != UWX_OK)
|
||||
return status;
|
||||
env->context.special[UWX_REG_PSP] = val;
|
||||
env->history.special[UWX_REG_PSP] = hist;
|
||||
TRACE_S_RESTORE_REG("PSP", env->rstate[SBREG_PSP], val)
|
||||
}
|
||||
if (env->rstate[SBREG_RP] != UWX_DISP_NONE) {
|
||||
status = uwx_restore_reg(env, env->rstate[SBREG_RP], &val, &hist);
|
||||
if (status != UWX_OK)
|
||||
return status;
|
||||
env->context.special[UWX_REG_RP] = val;
|
||||
env->history.special[UWX_REG_RP] = hist;
|
||||
TRACE_S_RESTORE_REG("RP", env->rstate[SBREG_RP], val)
|
||||
}
|
||||
if (env->rstate[SBREG_PFS] != UWX_DISP_NONE) {
|
||||
status = uwx_restore_reg(env, env->rstate[SBREG_PFS], &val, &hist);
|
||||
if (status != UWX_OK)
|
||||
return status;
|
||||
env->context.special[UWX_REG_PFS] = val;
|
||||
env->history.special[UWX_REG_PFS] = hist;
|
||||
TRACE_S_RESTORE_REG("PFS", env->rstate[SBREG_PFS], val)
|
||||
}
|
||||
|
||||
/* Check for bottom of stack (rp == 0). */
|
||||
@ -336,7 +354,7 @@ int uwx_step(struct uwx_env *env)
|
||||
if (env->nsbreg == NSBREG) {
|
||||
for (i = 0; i < NSB_FR; i++) {
|
||||
if (env->rstate[SBREG_FR + i] != UWX_DISP_NONE) {
|
||||
status = uwx_restore_reg(env,
|
||||
status = uwx_restore_freg(env,
|
||||
env->rstate[SBREG_FR + i], fval, &hist);
|
||||
if (status != UWX_OK)
|
||||
return status;
|
||||
@ -364,36 +382,36 @@ int uwx_step(struct uwx_env *env)
|
||||
status = uwx_restore_reg(env, env->rstate[SBREG_RNAT], &val, &hist);
|
||||
if (status != UWX_OK)
|
||||
return status;
|
||||
env->context.special[UWX_REG_RNAT] = val;
|
||||
env->history.special[UWX_REG_RNAT] = hist;
|
||||
env->context.valid_regs |= 1 << UWX_REG_RNAT;
|
||||
env->context.special[UWX_REG_AR_RNAT] = val;
|
||||
env->history.special[UWX_REG_AR_RNAT] = hist;
|
||||
env->context.valid_regs |= 1 << UWX_REG_AR_RNAT;
|
||||
TRACE_S_RESTORE_REG("RNAT", env->rstate[SBREG_RNAT], val)
|
||||
}
|
||||
if (env->rstate[SBREG_UNAT] != UWX_DISP_NONE) {
|
||||
status = uwx_restore_reg(env, env->rstate[SBREG_UNAT], &val, &hist);
|
||||
if (status != UWX_OK)
|
||||
return status;
|
||||
env->context.special[UWX_REG_UNAT] = val;
|
||||
env->history.special[UWX_REG_UNAT] = hist;
|
||||
env->context.valid_regs |= 1 << UWX_REG_UNAT;
|
||||
env->context.special[UWX_REG_AR_UNAT] = val;
|
||||
env->history.special[UWX_REG_AR_UNAT] = hist;
|
||||
env->context.valid_regs |= 1 << UWX_REG_AR_UNAT;
|
||||
TRACE_S_RESTORE_REG("UNAT", env->rstate[SBREG_UNAT], val)
|
||||
}
|
||||
if (env->rstate[SBREG_FPSR] != UWX_DISP_NONE) {
|
||||
status = uwx_restore_reg(env, env->rstate[SBREG_FPSR], &val, &hist);
|
||||
if (status != UWX_OK)
|
||||
return status;
|
||||
env->context.special[UWX_REG_FPSR] = val;
|
||||
env->history.special[UWX_REG_FPSR] = hist;
|
||||
env->context.valid_regs |= 1 << UWX_REG_FPSR;
|
||||
env->context.special[UWX_REG_AR_FPSR] = val;
|
||||
env->history.special[UWX_REG_AR_FPSR] = hist;
|
||||
env->context.valid_regs |= 1 << UWX_REG_AR_FPSR;
|
||||
TRACE_S_RESTORE_REG("FPSR", env->rstate[SBREG_FPSR], val)
|
||||
}
|
||||
if (env->rstate[SBREG_LC] != UWX_DISP_NONE) {
|
||||
status = uwx_restore_reg(env, env->rstate[SBREG_LC], &val, &hist);
|
||||
if (status != UWX_OK)
|
||||
return status;
|
||||
env->context.special[UWX_REG_LC] = val;
|
||||
env->history.special[UWX_REG_LC] = hist;
|
||||
env->context.valid_regs |= 1 << UWX_REG_LC;
|
||||
env->context.special[UWX_REG_AR_LC] = val;
|
||||
env->history.special[UWX_REG_AR_LC] = hist;
|
||||
env->context.valid_regs |= 1 << UWX_REG_AR_LC;
|
||||
TRACE_S_RESTORE_REG("LC", env->rstate[SBREG_LC], val)
|
||||
}
|
||||
|
||||
@ -426,6 +444,7 @@ int uwx_step(struct uwx_env *env)
|
||||
/* The frame info for the new frame isn't yet available. */
|
||||
|
||||
env->rstate = 0;
|
||||
env->context.valid_regs &= ~VALID_MARKERS;
|
||||
|
||||
return UWX_OK;
|
||||
}
|
||||
@ -497,6 +516,50 @@ int uwx_restore_reg(struct uwx_env *env, uint64_t rstate,
|
||||
return status;
|
||||
}
|
||||
|
||||
#define COPYIN_MSTACK_16(dest, src) \
|
||||
(env->remote? \
|
||||
(*env->copyin)(UWX_COPYIN_MSTACK, (dest), (src), \
|
||||
2*DWORDSZ, env->cb_token) : \
|
||||
(*(uint64_t *)(dest) = *(uint64_t *)(src), \
|
||||
*(uint64_t *)((dest)+8) = *(uint64_t *)((src)+8), \
|
||||
2*DWORDSZ) )
|
||||
|
||||
int uwx_restore_freg(struct uwx_env *env, uint64_t rstate,
|
||||
uint64_t *valp, uint64_t *histp)
|
||||
{
|
||||
int status;
|
||||
uint64_t p;
|
||||
int n;
|
||||
int regid;
|
||||
|
||||
status = UWX_OK;
|
||||
|
||||
switch (UWX_GET_DISP_CODE(rstate)) {
|
||||
case UWX_DISP_SPREL(0):
|
||||
p = env->context.special[UWX_REG_SP] +
|
||||
UWX_GET_DISP_OFFSET(rstate);
|
||||
n = COPYIN_MSTACK_16((char *)valp, p);
|
||||
if (n != 2*DWORDSZ)
|
||||
status = UWX_ERR_COPYIN_MSTK;
|
||||
*histp = UWX_DISP_MSTK(p);
|
||||
break;
|
||||
case UWX_DISP_PSPREL(0):
|
||||
p = env->context.special[UWX_REG_PSP] + 16 -
|
||||
UWX_GET_DISP_OFFSET(rstate);
|
||||
n = COPYIN_MSTACK_16((char *)valp, p);
|
||||
if (n != 2*DWORDSZ)
|
||||
status = UWX_ERR_COPYIN_MSTK;
|
||||
*histp = UWX_DISP_MSTK(p);
|
||||
break;
|
||||
case UWX_DISP_REG(0):
|
||||
regid = UWX_GET_DISP_REGID(rstate);
|
||||
status = uwx_get_reg(env, regid, valp);
|
||||
(void) uwx_get_spill_loc(env, regid, histp);
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/* uwx_restore_nat: Returns the saved NaT bit for a preserved GR */
|
||||
|
||||
int uwx_restore_nat(struct uwx_env *env, uint64_t rstate, int unat)
|
||||
|
1
sys/contrib/ia64/libuwx/src/uwx_step.h
Normal file
1
sys/contrib/ia64/libuwx/src/uwx_step.h
Normal file
@ -0,0 +1 @@
|
||||
extern int uwx_restore_markers(struct uwx_env *env);
|
@ -98,9 +98,9 @@ void uwx_dump_rstate(int regid, uint64_t rstate)
|
||||
break;
|
||||
case UWX_DISP_REG(0):
|
||||
reg = UWX_GET_DISP_REGID(rstate);
|
||||
if (reg == UWX_REG_PFS)
|
||||
if (reg == UWX_REG_AR_PFS)
|
||||
printf(" [AR.PFS]\n");
|
||||
else if (reg == UWX_REG_UNAT)
|
||||
else if (reg == UWX_REG_AR_UNAT)
|
||||
printf(" [AR.UNAT]\n");
|
||||
else if (reg >= UWX_REG_GR(0) && reg < UWX_REG_GR(128))
|
||||
printf(" [GR%d]\n", reg - UWX_REG_GR(0));
|
||||
|
@ -29,54 +29,7 @@
|
||||
#define UWX_TRACE_COPYIN 64 /* UWX_TRACE=C: copyin callback */
|
||||
#define UWX_TRACE_LOOKUPIP 128 /* UWX_TRACE=L: lookupip callback */
|
||||
|
||||
#ifndef UWX_TRACE_ENABLE
|
||||
|
||||
#define TRACE_INIT
|
||||
#define TRACE_B_REUSE(id)
|
||||
#define TRACE_B_ALLOC(id)
|
||||
#define TRACE_B_POP(id)
|
||||
#define TRACE_B_LABEL(label)
|
||||
#define TRACE_B_LABEL_COPY(id)
|
||||
#define TRACE_B_LABEL_REVERSE(back, new)
|
||||
#define TRACE_B_COPY(label, id)
|
||||
#define TRACE_B_COPY_FREE(id)
|
||||
#define TRACE_B_COPY_FOUND(id)
|
||||
#define TRACE_B_COPY_COPY(id)
|
||||
#define TRACE_B_COPY_REVERSE(back, new)
|
||||
#define TRACE_B_FREE(id)
|
||||
#define TRACE_I_DECODE_RHDR_1(name, b0)
|
||||
#define TRACE_I_DECODE_RHDR_1L(name, b0, val)
|
||||
#define TRACE_I_DECODE_RHDR_2L(name, b0, b1, val)
|
||||
#define TRACE_I_DECODE_PROLOGUE_1(name, b0)
|
||||
#define TRACE_I_DECODE_PROLOGUE_1L(name, b0, val)
|
||||
#define TRACE_I_DECODE_PROLOGUE_1LL(name, b0, val1, val2)
|
||||
#define TRACE_I_DECODE_PROLOGUE_2(name, b0, b1)
|
||||
#define TRACE_I_DECODE_PROLOGUE_2L(name, b0, b1, parm1)
|
||||
#define TRACE_I_DECODE_PROLOGUE_3(name, b0, b1, b2)
|
||||
#define TRACE_I_DECODE_PROLOGUE_4(name, b0, b1, b2, b3)
|
||||
#define TRACE_I_DECODE_PROLOGUE_SPILL_BASE(spill_base)
|
||||
#define TRACE_I_DECODE_PROLOGUE_MASKS(gr_mem_mask, gr_gr_mask)
|
||||
#define TRACE_I_DECODE_PROLOGUE_NSPILL(ngr)
|
||||
#define TRACE_I_DECODE_BODY_1(name, b0)
|
||||
#define TRACE_I_DECODE_BODY_1L(name, b0, parm1)
|
||||
#define TRACE_I_DECODE_BODY_1LL(name, b0, parm1, parm2)
|
||||
#define TRACE_R_UIB(uentry, ulen)
|
||||
#define TRACE_R_DUMP_SB(scoreboard, rhdr, cur_slot, ip_slot)
|
||||
#define TRACE_S_STEP(rstate)
|
||||
#define TRACE_S_RESTORE_REG(regname, rstate, val)
|
||||
#define TRACE_S_RESTORE_GR(regid, rstate, val)
|
||||
#define TRACE_S_RESTORE_BR(regid, rstate, val)
|
||||
#define TRACE_S_RESTORE_FR(regid, rstate, val)
|
||||
#define TRACE_T_SEARCH32(ip)
|
||||
#define TRACE_T_BINSEARCH32(lb, ub, mid, code_start, code_end)
|
||||
#define TRACE_C_GET_REG(regid, bsp)
|
||||
#define TRACE_C_ROTATE_GR(regid, sor, rrb_gr, newregid)
|
||||
#define TRACE_SELF_COPYIN4(rem, len, wp)
|
||||
#define TRACE_SELF_COPYIN8(rem, len, dp)
|
||||
#define TRACE_SELF_LOOKUP(ip)
|
||||
#define TRACE_SELF_LOOKUP_DESC(text_base, unwind_base)
|
||||
|
||||
#else /* !UWX_TRACE_ENABLE */
|
||||
#ifdef UWX_TRACE_ENABLE
|
||||
|
||||
extern void uwx_trace_init(struct uwx_env *env);
|
||||
|
||||
@ -235,7 +188,7 @@ extern void uwx_dump_scoreboard(
|
||||
|
||||
#define TRACE_S_STEP(rstate) \
|
||||
if (env->trace & UWX_TRACE_STEP) { \
|
||||
printf("uwx_step:\n"); \
|
||||
printf("uwx_restore_markers:\n"); \
|
||||
uwx_dump_rstate(SBREG_RP, (rstate)[SBREG_RP]); \
|
||||
uwx_dump_rstate(SBREG_PSP, (rstate)[SBREG_PSP]); \
|
||||
uwx_dump_rstate(SBREG_PFS, (rstate)[SBREG_PFS]); \
|
||||
@ -344,5 +297,52 @@ extern void uwx_dump_scoreboard(
|
||||
(unsigned int) ((text_base)+(unwind_base)[2])); \
|
||||
}
|
||||
|
||||
#endif /* !UWX_TRACE_ENABLE */
|
||||
#else /* !UWX_TRACE_ENABLE */
|
||||
|
||||
#define TRACE_INIT
|
||||
#define TRACE_B_REUSE(id)
|
||||
#define TRACE_B_ALLOC(id)
|
||||
#define TRACE_B_POP(id)
|
||||
#define TRACE_B_LABEL(label)
|
||||
#define TRACE_B_LABEL_COPY(id)
|
||||
#define TRACE_B_LABEL_REVERSE(back, new)
|
||||
#define TRACE_B_COPY(label, id)
|
||||
#define TRACE_B_COPY_FREE(id)
|
||||
#define TRACE_B_COPY_FOUND(id)
|
||||
#define TRACE_B_COPY_COPY(id)
|
||||
#define TRACE_B_COPY_REVERSE(back, new)
|
||||
#define TRACE_B_FREE(id)
|
||||
#define TRACE_I_DECODE_RHDR_1(name, b0)
|
||||
#define TRACE_I_DECODE_RHDR_1L(name, b0, val)
|
||||
#define TRACE_I_DECODE_RHDR_2L(name, b0, b1, val)
|
||||
#define TRACE_I_DECODE_PROLOGUE_1(name, b0)
|
||||
#define TRACE_I_DECODE_PROLOGUE_1L(name, b0, val)
|
||||
#define TRACE_I_DECODE_PROLOGUE_1LL(name, b0, val1, val2)
|
||||
#define TRACE_I_DECODE_PROLOGUE_2(name, b0, b1)
|
||||
#define TRACE_I_DECODE_PROLOGUE_2L(name, b0, b1, parm1)
|
||||
#define TRACE_I_DECODE_PROLOGUE_3(name, b0, b1, b2)
|
||||
#define TRACE_I_DECODE_PROLOGUE_4(name, b0, b1, b2, b3)
|
||||
#define TRACE_I_DECODE_PROLOGUE_SPILL_BASE(spill_base)
|
||||
#define TRACE_I_DECODE_PROLOGUE_MASKS(gr_mem_mask, gr_gr_mask)
|
||||
#define TRACE_I_DECODE_PROLOGUE_NSPILL(ngr)
|
||||
#define TRACE_I_DECODE_BODY_1(name, b0)
|
||||
#define TRACE_I_DECODE_BODY_1L(name, b0, parm1)
|
||||
#define TRACE_I_DECODE_BODY_1LL(name, b0, parm1, parm2)
|
||||
#define TRACE_R_UIB(uentry, ulen)
|
||||
#define TRACE_R_DUMP_SB(scoreboard, rhdr, cur_slot, ip_slot)
|
||||
#define TRACE_S_STEP(rstate)
|
||||
#define TRACE_S_RESTORE_REG(regname, rstate, val)
|
||||
#define TRACE_S_RESTORE_GR(regid, rstate, val)
|
||||
#define TRACE_S_RESTORE_BR(regid, rstate, val)
|
||||
#define TRACE_S_RESTORE_FR(regid, rstate, val)
|
||||
#define TRACE_T_SEARCH32(ip)
|
||||
#define TRACE_T_BINSEARCH32(lb, ub, mid, code_start, code_end)
|
||||
#define TRACE_C_GET_REG(regid, bsp)
|
||||
#define TRACE_C_ROTATE_GR(regid, sor, rrb_gr, newregid)
|
||||
#define TRACE_SELF_COPYIN4(rem, len, wp)
|
||||
#define TRACE_SELF_COPYIN8(rem, len, dp)
|
||||
#define TRACE_SELF_LOOKUP(ip)
|
||||
#define TRACE_SELF_LOOKUP_DESC(text_base, unwind_base)
|
||||
|
||||
#endif /* UWX_TRACE_ENABLE */
|
||||
|
||||
|
@ -249,22 +249,22 @@ int uwx_ttrace_copyin(
|
||||
if (info->have_ucontext) {
|
||||
if (regid < UWX_REG_GR(0)) {
|
||||
switch (regid) {
|
||||
case UWX_REG_PFS:
|
||||
status = __uc_get_ar(&info->ucontext, 64, dp);
|
||||
break;
|
||||
case UWX_REG_PREDS:
|
||||
status = __uc_get_prs(&info->ucontext, dp);
|
||||
break;
|
||||
case UWX_REG_RNAT:
|
||||
case UWX_REG_AR_PFS:
|
||||
status = __uc_get_ar(&info->ucontext, 64, dp);
|
||||
break;
|
||||
case UWX_REG_AR_RNAT:
|
||||
status = __uc_get_ar(&info->ucontext, 19, dp);
|
||||
break;
|
||||
case UWX_REG_UNAT:
|
||||
case UWX_REG_AR_UNAT:
|
||||
status = __uc_get_ar(&info->ucontext, 36, dp);
|
||||
break;
|
||||
case UWX_REG_FPSR:
|
||||
case UWX_REG_AR_FPSR:
|
||||
status = __uc_get_ar(&info->ucontext, 40, dp);
|
||||
break;
|
||||
case UWX_REG_LC:
|
||||
case UWX_REG_AR_LC:
|
||||
status = __uc_get_ar(&info->ucontext, 65, dp);
|
||||
break;
|
||||
default:
|
||||
@ -283,22 +283,22 @@ int uwx_ttrace_copyin(
|
||||
else {
|
||||
if (regid < UWX_REG_GR(0)) {
|
||||
switch (regid) {
|
||||
case UWX_REG_PFS:
|
||||
ttreg = __ar_pfs;
|
||||
break;
|
||||
case UWX_REG_PREDS:
|
||||
ttreg = __pr;
|
||||
break;
|
||||
case UWX_REG_RNAT:
|
||||
case UWX_REG_AR_PFS:
|
||||
ttreg = __ar_pfs;
|
||||
break;
|
||||
case UWX_REG_AR_RNAT:
|
||||
ttreg = __ar_rnat;
|
||||
break;
|
||||
case UWX_REG_UNAT:
|
||||
case UWX_REG_AR_UNAT:
|
||||
ttreg = __ar_unat;
|
||||
break;
|
||||
case UWX_REG_FPSR:
|
||||
case UWX_REG_AR_FPSR:
|
||||
ttreg = __ar_fpsr;
|
||||
break;
|
||||
case UWX_REG_LC:
|
||||
case UWX_REG_AR_LC:
|
||||
ttreg = __ar_lc;
|
||||
break;
|
||||
default:
|
||||
|
@ -232,7 +232,8 @@ int uwx_decode_rhdr(
|
||||
if ((b0 & 0x20) == 0) {
|
||||
TRACE_I_DECODE_RHDR_1("(R1) prologue", b0)
|
||||
rhdr->is_prologue = 1;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
TRACE_I_DECODE_RHDR_1("(R1) body", b0)
|
||||
}
|
||||
rhdr->rlen = b0 & 0x1f;
|
||||
@ -263,7 +264,8 @@ int uwx_decode_rhdr(
|
||||
if ((b0 & 0x03) == 0) {
|
||||
TRACE_I_DECODE_RHDR_1L("(R3) prologue", b0, val)
|
||||
rhdr->is_prologue = 1;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
TRACE_I_DECODE_RHDR_1L("(R3) body", b0, val)
|
||||
}
|
||||
rhdr->rlen = (unsigned int) val;
|
||||
@ -863,7 +865,7 @@ int uwx_decode_prologue(
|
||||
if (fr_mem_mask & 1) {
|
||||
newrstate[SBREG_FR + i] = UWX_DISP_PSPREL(fr_base);
|
||||
tspill[SBREG_FR + i] = 0;
|
||||
fr_base -= 8;
|
||||
fr_base -= 16;
|
||||
nfr--;
|
||||
}
|
||||
fr_mem_mask = fr_mem_mask >> 1;
|
||||
|
Loading…
Reference in New Issue
Block a user