Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 14 Jun 2004 04:21:20 GMT
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 54897 for review
Message-ID:  <200406140421.i5E4LKm5063464@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=54897

Change 54897 by marcel@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 */
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200406140421.i5E4LKm5063464>