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(®name[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:[EMAIL PROTECTED]
38000 Echirolles
France