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

Reply via email to