aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorach61@labyrinth.cl.cam.ac.uk <ach61@labyrinth.cl.cam.ac.uk>2004-04-28 14:08:16 +0000
committerach61@labyrinth.cl.cam.ac.uk <ach61@labyrinth.cl.cam.ac.uk>2004-04-28 14:08:16 +0000
commita93317142fe7f3eeb624ec322a2dcf8e18c24b0e (patch)
tree7ed49b2f7c6177f13e36218e1a945daea7c98a76
parent3f83f4a5ab1694cfdd1426193d0bf3fcc73c4c95 (diff)
downloadxen-a93317142fe7f3eeb624ec322a2dcf8e18c24b0e.tar.gz
xen-a93317142fe7f3eeb624ec322a2dcf8e18c24b0e.tar.bz2
xen-a93317142fe7f3eeb624ec322a2dcf8e18c24b0e.zip
bitkeeper revision 1.879.1.3 (408fbad0T3LWY4pCllkDFuZcXfqMOQ)
properly modify process memory
-rw-r--r--xen/arch/i386/pdb-stub.c8
-rw-r--r--xen/common/debug-linux.c38
2 files changed, 46 insertions, 0 deletions
diff --git a/xen/arch/i386/pdb-stub.c b/xen/arch/i386/pdb-stub.c
index 049f330cf6..5b42e9a746 100644
--- a/xen/arch/i386/pdb-stub.c
+++ b/xen/arch/i386/pdb-stub.c
@@ -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,
diff --git a/xen/common/debug-linux.c b/xen/common/debug-linux.c
index 4fbcdf2918..ff767b51cd 100644
--- a/xen/common/debug-linux.c
+++ b/xen/common/debug-linux.c
@@ -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