[ia64] stacked registers

Sebastien Lelarge sebastien.lelarge at bull.net
Wed Jul 17 02:09:55 PDT 2002


Hello Keith,

I've been looking for a solution while waiting for an answer of the
list. I've written a little patch for kdbasupport.c to make stacked registers
modifications. It creates a routine called change_cur_stack_frame
where it modifies the appropriate register. It also modifies the
kdba_setregcontents routine. Until now, it seems to work. I have
checked for bad modifications and you can't modify an inexistent
stacked register.

Here's the patch :

--- linux-ref/arch/ia64/kdb/kdbasupport.c	Wed Jul 17 07:55:00 2002
+++ linux-stacked/arch/ia64/kdb/kdbasupport.c	Wed Jul 17 07:51:24 2002
@@ -20,6 +20,8 @@
  *              RSE support for ia64
  *	Scott Lurndal			1999/12/12
  *		v1.0 restructuring.
+ *      Sebastien Lelarge               2002/07/17
+ *              Stacked registers modification support.
  */
 
 #include <linux/config.h>
@@ -199,6 +201,44 @@
 		kdb_printf(" kr%d: %016lx  kr%d: %016lx\n", 2*i, kr[2*i], 2*i+1, kr[2*i+1]);
 	kdb_printf("\n");
 }
+static int
+change_cur_stack_frame(struct pt_regs *regs, int regno, unsigned long *contents)
+{
+	unsigned long sof, i, cfm, sp, *bsp;
+	struct unw_frame_info info;
+	mm_segment_t old_fs;
+
+	unw_init_frame_info(&info, current, kdb_sw[smp_processor_id()]);
+	do {
+		if (unw_unwind(&info) < 0) {
+			kdb_printf("Failed to unwind\n");
+			return 0;
+		}
+		unw_get_sp(&info, &sp);
+	} while (sp <= (unsigned long) regs);
+	unw_get_bsp(&info, (unsigned long *) &bsp);
+	unw_get_cfm(&info, &cfm);
+	
+	if (!bsp) {
+		kdb_printf("Unable to get Current Stack Frame\n");
+		return 0;
+	}
+	
+	sof = (cfm & 0x7f);
+	
+	if(((unsigned long)regno - 32) >= (sof - 2)) return 1;
+	
+	old_fs = set_fs(KERNEL_DS);
+	{
+		for (i = 0; i < (regno - 32); ++i) {
+			bsp = ia64_rse_skip_regs(bsp, 1);
+		}
+		put_user(*contents, bsp);
+	}
+	set_fs(old_fs);
+	
+	return 0 ;
+}
 
 static int
 show_cur_stack_frame(struct pt_regs *regs, int regno, unsigned long *contents)
@@ -428,29 +468,44 @@
 		  struct pt_regs *regs,
 		  unsigned long contents)
 {
-	int i;
-
+	int i, ret = 0, fixed = 0;
+	char *endp;
+	unsigned long regno;
+	
 	if (regname[0] == '%') {
 		regname++;
 		regs = (struct pt_regs *)
 			(current->thread.ksp - sizeof(struct pt_regs));
 	}
-
+	/* fixed registers */
 	for (i=0; i<nkdbreglist; i++) {
 		if (strnicmp(kdbreglist[i].reg_name,
 			     regname,
-			     strlen(regname)) == 0)
+			     strlen(regname)) == 0) {
+			fixed = 1;
 			break;
+		}
 	}
-
+	
+	/* stacked registers */
+	if (!fixed) {
+		regno = (simple_strtoul(&regname[1], &endp, 10));
+		if ((regname[0] == 'r') && regno > (unsigned long)31) {
+			ret = change_cur_stack_frame(regs, regno, &contents);
+			if(!ret) return 0;
+		}
+	}
+	
 	if ((i == nkdbreglist)
-	 || (strlen(kdbreglist[i].reg_name) != strlen(regname))) {
+	    || (strlen(kdbreglist[i].reg_name) != strlen(regname))
+	    || ret) {
 		return KDB_BADREG;
 	}
 
+	/* just in case of "standart" register */ 
 	*(unsigned long *)((unsigned long)regs + kdbreglist[i].reg_offset) =
 		contents;
-
+	
 	return 0;
 }


-- 
LELARGE Sebastien		
BULL S.A - Linux IA64 Team    mailto:sebastien.lelarge at bull.net
38000 Echirolles
France



More information about the kdb mailing list