PERFORCE change 54897 for review
Marcel Moolenaar
marcel at FreeBSD.org
Mon Jun 14 04:21:29 GMT 2004
http://perforce.freebsd.org/chv.cgi?CH=54897
Change 54897 by marcel at marcel_nfs on 2004/06/14 04:20:41
Now that the unwind context can be created from the PCB as
well as the trapframe, we cannot dereference the frame
pointer for the registers the unwinder wants us to copyin.
We need to fetch them from the PCB if appropriate. While
here, replace some backstore pointer magic with the new
convenience macros/functions.
Affected files ...
.. //depot/projects/gdb/sys/ia64/ia64/unwind.c#5 edit
Differences ...
==== //depot/projects/gdb/sys/ia64/ia64/unwind.c#5 (text+ko) ====
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003 Marcel Moolenaar
+ * Copyright (c) 2003, 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,6 +35,7 @@
#include <sys/queue.h>
#include <machine/frame.h>
+#include <machine/md_var.h>
#include <machine/pcb.h>
#include <machine/unwind.h>
@@ -156,11 +157,101 @@
return (NULL);
}
+static uint64_t
+unw_copyin_from_frame(struct trapframe *tf, uint64_t from)
+{
+ uint64_t val;
+ int reg;
+
+ if (from == UWX_REG_AR_PFS)
+ val = tf->tf_special.pfs;
+ else if (from == UWX_REG_PREDS)
+ val = tf->tf_special.pr;
+ else if (from == UWX_REG_AR_RNAT)
+ val = tf->tf_special.rnat;
+ else if (from == UWX_REG_AR_UNAT)
+ val = tf->tf_special.unat;
+ else if (from >= UWX_REG_GR(0) && from <= UWX_REG_GR(127)) {
+ reg = from - UWX_REG_GR(0);
+ if (reg == 1)
+ val = tf->tf_special.gp;
+ else if (reg == 12)
+ val = tf->tf_special.sp;
+ else if (reg == 13)
+ val = tf->tf_special.tp;
+ else if (reg >= 2 && reg <= 3)
+ val = (&tf->tf_scratch.gr2)[reg - 2];
+ else if (reg >= 8 && reg <= 11)
+ val = (&tf->tf_scratch.gr8)[reg - 8];
+ else if (reg >= 14 && reg <= 31)
+ val = (&tf->tf_scratch.gr14)[reg - 14];
+ else
+ goto oops;
+ } else if (from >= UWX_REG_BR(0) && from <= UWX_REG_BR(7)) {
+ reg = from - UWX_REG_BR(0);
+ if (reg == 0)
+ val = tf->tf_special.rp;
+ else if (reg >= 6 && reg <= 7)
+ val = (&tf->tf_scratch.br6)[reg - 6];
+ else
+ goto oops;
+ } else
+ goto oops;
+ return (val);
+
+ oops:
+ printf("UNW: %s(%p, %lx)\n", __func__, tf, from);
+ return (0UL);
+}
+
+static uint64_t
+unw_copyin_from_pcb(struct pcb *pcb, uint64_t from)
+{
+ uint64_t val;
+ int reg;
+
+ if (from == UWX_REG_AR_PFS)
+ val = pcb->pcb_special.pfs;
+ else if (from == UWX_REG_PREDS)
+ val = pcb->pcb_special.pr;
+ else if (from == UWX_REG_AR_RNAT)
+ val = pcb->pcb_special.rnat;
+ else if (from == UWX_REG_AR_UNAT)
+ val = pcb->pcb_special.unat;
+ else if (from >= UWX_REG_GR(0) && from <= UWX_REG_GR(127)) {
+ reg = from - UWX_REG_GR(0);
+ if (reg == 1)
+ val = pcb->pcb_special.gp;
+ else if (reg == 12)
+ val = pcb->pcb_special.sp;
+ else if (reg == 13)
+ val = pcb->pcb_special.tp;
+ else if (reg >= 4 && reg <= 7)
+ val = (&pcb->pcb_preserved.gr4)[reg - 4];
+ else
+ goto oops;
+ } else if (from >= UWX_REG_BR(0) && from <= UWX_REG_BR(7)) {
+ reg = from - UWX_REG_BR(0);
+ if (reg == 0)
+ val = pcb->pcb_special.rp;
+ else if (reg >= 1 && reg <= 5)
+ val = (&pcb->pcb_preserved.br1)[reg - 1];
+ else
+ goto oops;
+ } else
+ goto oops;
+ return (val);
+
+ oops:
+ printf("UNW: %s(%p, %lx)\n", __func__, pcb, from);
+ return (0UL);
+}
+
static int
unw_cb_copyin(int req, char *to, uint64_t from, int len, intptr_t tok)
{
struct unw_regstate *rs = (void*)tok;
- int reg;
+ uint64_t val;
switch (req) {
case UWX_COPYIN_UINFO:
@@ -172,49 +263,19 @@
*((uint64_t*)to) = *((uint64_t*)from);
return (8);
case UWX_COPYIN_REG:
- if (from == UWX_REG_AR_PFS)
- from = rs->frame->tf_special.pfs;
- else if (from == UWX_REG_PREDS)
- from = rs->frame->tf_special.pr;
- else if (from == UWX_REG_AR_RNAT)
- from = rs->frame->tf_special.rnat;
- else if (from == UWX_REG_AR_UNAT)
- from = rs->frame->tf_special.unat;
- else if (from >= UWX_REG_GR(0) && from <= UWX_REG_GR(127)) {
- reg = from - UWX_REG_GR(0);
- if (reg == 1)
- from = rs->frame->tf_special.gp;
- else if (reg == 12)
- from = rs->frame->tf_special.sp;
- else if (reg == 13)
- from = rs->frame->tf_special.tp;
- else if (reg >= 2 && reg <= 3)
- from = (&rs->frame->tf_scratch.gr2)[reg - 2];
- else if (reg >= 8 && reg <= 11)
- from = (&rs->frame->tf_scratch.gr8)[reg - 8];
- else if (reg >= 14 && reg <= 31)
- from = (&rs->frame->tf_scratch.gr14)[reg - 14];
- else
- goto oops;
- } else if (from >= UWX_REG_BR(0) && from <= UWX_REG_BR(7)) {
- reg = from - UWX_REG_BR(0);
- if (reg == 0)
- from = rs->frame->tf_special.rp;
- else if (reg >= 6 && reg <= 7)
- from = (&rs->frame->tf_scratch.br6)[reg - 6];
- else
- goto oops;
- } else
+ if (rs->frame != NULL)
+ val = unw_copyin_from_frame(rs->frame, from);
+ else if (rs->pcb != NULL)
+ val = unw_copyin_from_pcb(rs->pcb, from);
+ else
goto oops;
-
- *((uint64_t*)to) = from;
+ *((uint64_t*)to) = val;
return (len);
}
oops:
printf("UNW: %s(%d, %p, %lx, %d, %lx)\n", __func__, req, to, from,
len, tok);
-
return (0);
}
@@ -250,7 +311,7 @@
unw_create_from_frame(struct unw_regstate *rs, struct trapframe *tf)
{
uint64_t bsp;
- int nats, sof, uwxerr;
+ int uwxerr;
rs->frame = tf;
rs->pcb = NULL;
@@ -264,10 +325,10 @@
return (EINVAL); /* XXX */
bsp = tf->tf_special.bspstore + tf->tf_special.ndirty;
- sof = (int)(tf->tf_special.cfm & 0x7f);
- nats = (sof + 63 - ((int)(bsp >> 3) & 0x3f)) / 63;
+ bsp = ia64_bsp_adjust(bsp, -IA64_CFM_SOF(tf->tf_special.cfm));
+
uwxerr = uwx_init_context(rs->env, tf->tf_special.iip,
- tf->tf_special.sp, bsp - ((sof + nats) << 3), tf->tf_special.cfm);
+ tf->tf_special.sp, bsp, tf->tf_special.cfm);
return ((uwxerr) ? EINVAL : 0); /* XXX */
}
@@ -275,8 +336,8 @@
int
unw_create_from_pcb(struct unw_regstate *rs, struct pcb *pcb)
{
- uint64_t bsp;
- int nats, sof, uwxerr;
+ uint64_t bsp, cfm;
+ int uwxerr;
rs->frame = NULL;
rs->pcb = pcb;
@@ -290,12 +351,11 @@
return (EINVAL); /* XXX */
bsp = pcb->pcb_special.bspstore;
- sof = (int)(pcb->pcb_special.pfs & 0x7f);
- nats = (sof + 63 - ((int)(bsp >> 3) & 0x3f)) / 63;
+ cfm = pcb->pcb_special.pfs;
+ bsp = ia64_bsp_adjust(bsp, -IA64_CFM_SOL(cfm));
uwxerr = uwx_init_context(rs->env, pcb->pcb_special.rp,
- pcb->pcb_special.sp, bsp - ((sof + nats) << 3),
- pcb->pcb_special.pfs);
+ pcb->pcb_special.sp, bsp, pcb->pcb_special.pfs);
return ((uwxerr) ? EINVAL : 0); /* XXX */
}
More information about the p4-projects
mailing list