bitkeeper revision 1.879.1.3 (408fbad0T3LWY4pCllkDFuZcXfqMOQ)
authorach61@labyrinth.cl.cam.ac.uk <ach61@labyrinth.cl.cam.ac.uk>
Wed, 28 Apr 2004 14:08:16 +0000 (14:08 +0000)
committerach61@labyrinth.cl.cam.ac.uk <ach61@labyrinth.cl.cam.ac.uk>
Wed, 28 Apr 2004 14:08:16 +0000 (14:08 +0000)
properly modify process memory

xen/arch/i386/pdb-stub.c
xen/common/debug-linux.c

index 049f330cf69c8b62086da7183b1ade70d30ee00d..5b42e9a74612277f6f255ea0279eec1504c8c05d 100644 (file)
@@ -51,6 +51,8 @@ static unsigned char  pdb_xmit_checksum;
 unsigned long pdb_linux_pid_ptbr (unsigned long cr3, int pid);
 void pdb_linux_get_values(char *buffer, int length, unsigned long address,
                          int pid, unsigned long cr3);
+void pdb_linux_set_values(char *buffer, int length, unsigned long address,
+                         int pid, unsigned long cr3);
 
 struct pdb_context
 {
@@ -571,6 +573,12 @@ pdb_process_command (char *ptr, struct pt_regs *regs, unsigned long cr3,
                        {
                            hex2mem (ptr, (char *)addr, length);
                        }
+                       else if (pdb_ctx.process != -1)
+                       {
+                           pdb_linux_set_values(ptr, length, addr,
+                                                pdb_ctx.process, 
+                                                pdb_ctx.ptbr);
+                       }
                        else
                        {
                            pdb_set_values (ptr, length,
index 4fbcdf29180a197fe1415c3e6aeadac614fdace4..ff767b51cd58d70758b35fbb9c64569c4e256ad2 100644 (file)
@@ -171,6 +171,44 @@ void pdb_linux_get_values(char *buffer, int length, unsigned long address,
     }
 }
 
+void pdb_linux_set_value(int pid, unsigned long cr3, unsigned long addr,
+                        u_char *value)
+{
+    unsigned long pgd;
+    unsigned long l2tab, page;
+    /* get the process' pgd */
+    pgd = pdb_linux_pid_ptbr(cr3, pid);
+    /* get the l2 table entry */
+    pdb_get_values((u_char *) &l2tab, sizeof(l2tab),
+                  cr3, pgd + (addr >> PGDIR_SHIFT) * 4);
+    l2tab = (unsigned long)__va(machine_to_phys(cr3, l2tab) & PAGE_MASK);
+    /* get the page table entry */
+    pdb_get_values((u_char *) &page, sizeof(page),
+                  cr3, l2tab + ((addr & L1_PAGE_BITS) >> PAGE_SHIFT) * 4);
+    page = (unsigned long)__va(machine_to_phys(cr3, page) & PAGE_MASK);
+    /* set the byte */
+    pdb_set_values(value, sizeof(u_char), cr3, page + (addr & ~PAGE_MASK));
+}
+void pdb_linux_set_values(char *buffer, int length, unsigned long address,
+                         int pid, unsigned long cr3)
+{
+    int loop;
+    /* it's difficult to imagine a more inefficient algorithm */
+    for (loop = 0; loop < length; loop++)
+    {
+        pdb_linux_set_value(pid, cr3, address + loop, &buffer[loop * 2]);
+    }
+}
+
+/**********************************************************************/
+
 /*
  * return 1 if is the virtual address is in the operating system's
  * address space, else 0