PERFORCE change 56562 for review
Marcel Moolenaar
marcel at FreeBSD.org
Mon Jul 5 18:12:31 PDT 2004
http://perforce.freebsd.org/chv.cgi?CH=56562
Change 56562 by marcel at marcel_nfs on 2004/07/06 01:11:30
Implement makectx() on ia64. Tested and working.
This gave some complications: unwinding based on the PCB was
based on the fact that savectx() was called and thus that the
context we cared about was that of the previous function (i.e.
the caller. As such, the PC was taken from the return address
and the frame state was the previous one.
When constructing a PCB from a trapframe, the context we care
about is the one that was interrupted. Worse, we cannot simply
store the IP and CFM as RP and PFS in the context because that
messes up unwinding when those registers actually contain live
values.
So, a yedi trick was called for: there's a spare field in the
pcb_special structure that is explicitly cleared by savectx().
I must have had foresight. When we create the PCB from the
trapframe, we write ~0 in that field. From there on we extract
the values from the PCB based on that value: when 0 - it's a
PCB created by savectx() and we use RP & PFS. Otherwise it's
actually a trapframe in disguise and we use IIP & CFM.
I haven't given the spare field a name, but it isn't actually
spare anymore. This has to sink in first...
Affected files ...
.. //depot/projects/gdb/sys/ia64/ia64/machdep.c#9 edit
.. //depot/projects/gdb/sys/ia64/ia64/unwind.c#6 edit
.. //depot/projects/gdb/sys/ia64/include/db_machdep.h#5 edit
Differences ...
==== //depot/projects/gdb/sys/ia64/ia64/machdep.c#9 (text+ko) ====
@@ -1017,6 +1017,23 @@
}
#endif
+/*
+ * Construct a PCB from a trapframe. This is called from kdb_trap() where
+ * we want to start a backtrace from the function that caused us to enter
+ * the debugger. We have the context in the trapframe, but base the trace
+ * on the PCB. The PCB doesn't have to be perfect, as long as it contains
+ * enough for a backtrace.
+ */
+void
+makectx(struct trapframe *tf, struct pcb *pcb)
+{
+
+ pcb->pcb_special = tf->tf_special;
+ pcb->pcb_special.__spare = ~0UL; /* XXX see unwind.c */
+ save_callee_saved(&pcb->pcb_preserved);
+ save_callee_saved_fp(&pcb->pcb_preserved_fp);
+}
+
int
get_mcontext(struct thread *td, mcontext_t *mc, int flags)
{
==== //depot/projects/gdb/sys/ia64/ia64/unwind.c#6 (text+ko) ====
@@ -310,7 +310,7 @@
int
unw_create_from_frame(struct unw_regstate *rs, struct trapframe *tf)
{
- uint64_t bsp;
+ uint64_t bsp, ip;
int uwxerr;
rs->frame = tf;
@@ -326,9 +326,10 @@
bsp = tf->tf_special.bspstore + tf->tf_special.ndirty;
bsp = ia64_bsp_adjust(bsp, -IA64_CFM_SOF(tf->tf_special.cfm));
+ ip = tf->tf_special.iip + ((tf->tf_special.isr >> 41) & 3);
- uwxerr = uwx_init_context(rs->env, tf->tf_special.iip,
- tf->tf_special.sp, bsp, tf->tf_special.cfm);
+ uwxerr = uwx_init_context(rs->env, ip, tf->tf_special.sp, bsp,
+ tf->tf_special.cfm);
return ((uwxerr) ? EINVAL : 0); /* XXX */
}
@@ -336,7 +337,7 @@
int
unw_create_from_pcb(struct unw_regstate *rs, struct pcb *pcb)
{
- uint64_t bsp, cfm;
+ uint64_t bsp, cfm, ip;
int uwxerr;
rs->frame = NULL;
@@ -351,11 +352,16 @@
return (EINVAL); /* XXX */
bsp = pcb->pcb_special.bspstore;
- cfm = pcb->pcb_special.pfs;
+ if (pcb->pcb_special.__spare == ~0UL) {
+ ip = pcb->pcb_special.iip + ((pcb->pcb_special.isr >> 41) & 3);
+ cfm = pcb->pcb_special.cfm;
+ bsp += pcb->pcb_special.ndirty;
+ } else {
+ ip = pcb->pcb_special.rp;
+ 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, pcb->pcb_special.pfs);
+ uwxerr = uwx_init_context(rs->env, ip, pcb->pcb_special.sp, bsp, cfm);
return ((uwxerr) ? EINVAL : 0); /* XXX */
}
==== //depot/projects/gdb/sys/ia64/include/db_machdep.h#5 (text+ko) ====
@@ -44,7 +44,9 @@
typedef vm_offset_t db_addr_t; /* address - unsigned */
typedef long db_expr_t; /* expression - signed */
-#define PC_REGS() ((db_addr_t)kdb_thrctx->pcb_special.rp)
+#define PC_REGS() ((kdb_thrctx->pcb_special.__spare == 0) ? \
+ kdb_thrctx->pcb_special.rp : \
+ kdb_thrctx->pcb_special.iip + ((kdb_thrctx->pcb_special.psr>>41) & 3))
#define BKPT_WRITE(addr, storage) db_bkpt_write(addr, storage)
#define BKPT_CLEAR(addr, storage) db_bkpt_clear(addr, storage)
@@ -71,6 +73,4 @@
#define branch_taken(ins, pc, regs) pc
-#define next_instr_address(v, b) ((db_addr_t) ((b) ? (v) : ((v) + 4)))
-
#endif /* _MACHINE_DB_MACHDEP_H_ */
More information about the p4-projects
mailing list