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