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