aboutsummaryrefslogtreecommitdiffstats
path: root/tools/debugger/pdb/linux-2.6-module
diff options
context:
space:
mode:
Diffstat (limited to 'tools/debugger/pdb/linux-2.6-module')
-rw-r--r--tools/debugger/pdb/linux-2.6-module/Makefile21
-rw-r--r--tools/debugger/pdb/linux-2.6-module/debug.c851
-rw-r--r--tools/debugger/pdb/linux-2.6-module/module.c337
-rw-r--r--tools/debugger/pdb/linux-2.6-module/pdb_debug.h47
-rw-r--r--tools/debugger/pdb/linux-2.6-module/pdb_module.h142
5 files changed, 0 insertions, 1398 deletions
diff --git a/tools/debugger/pdb/linux-2.6-module/Makefile b/tools/debugger/pdb/linux-2.6-module/Makefile
deleted file mode 100644
index 9025cd85c1..0000000000
--- a/tools/debugger/pdb/linux-2.6-module/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-XEN_ROOT = ../../../..
-LINUX_DIR = linux-2.6.12-xenU
-KDIR = $(XEN_ROOT)/$(LINUX_DIR)
-
-obj-m += pdb.o
-pdb-objs += module.o
-pdb-objs += debug.o
-
-CFLAGS += -g
-CFLAGS += -Wall
-CFLAGS += -Werror
-
-.PHONY: module
-module :
-# make KBUILD_VERBOSE=1 ARCH=xen -C $(KDIR) M=$(PWD) modules
- make ARCH=xen -C $(KDIR) M=$(PWD) modules
-
-.PHONY: clean
-clean :
- make -C $(KDIR) M=$(PWD) clean
-
diff --git a/tools/debugger/pdb/linux-2.6-module/debug.c b/tools/debugger/pdb/linux-2.6-module/debug.c
deleted file mode 100644
index e53dfbc1b1..0000000000
--- a/tools/debugger/pdb/linux-2.6-module/debug.c
+++ /dev/null
@@ -1,851 +0,0 @@
-/*
- * debug.c
- * pdb debug functionality for processes.
- */
-
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <asm-i386/kdebug.h>
-#include <asm-i386/mach-xen/asm/processor.h>
-#include <asm-i386/mach-xen/asm/ptrace.h>
-#include <asm-i386/mach-xen/asm/tlbflush.h>
-#include <xen/interface/xen.h>
-#include "pdb_module.h"
-#include "pdb_debug.h"
-
-
-static int pdb_debug_fn (struct pt_regs *regs, long error_code,
- unsigned int condition);
-static int pdb_int3_fn (struct pt_regs *regs, long error_code);
-static int pdb_page_fault_fn (struct pt_regs *regs, long error_code,
- unsigned int condition);
-
-/***********************************************************************/
-
-typedef struct bwcpoint /* break/watch/catch point */
-{
- struct list_head list;
- unsigned long address;
- int length;
-
- uint8_t type; /* BWC_??? */
- uint8_t mode; /* for BWC_PAGE, the current protection mode */
- uint32_t process;
- uint8_t error; /* error occured when enabling: don't disable. */
-
- /* original values */
- uint8_t orig_bkpt; /* single byte breakpoint */
- pte_t orig_pte;
-
- struct list_head watchpt_read_list; /* read watchpoints on this page */
- struct list_head watchpt_write_list; /* write */
- struct list_head watchpt_access_list; /* access */
- struct list_head watchpt_disabled_list; /* disabled */
-
- struct bwcpoint *parent; /* watchpoint: bwc_watch (the page) */
- struct bwcpoint *watchpoint; /* bwc_watch_step: original watchpoint */
-} bwcpoint_t, *bwcpoint_p;
-
-static struct list_head bwcpoint_list = LIST_HEAD_INIT(bwcpoint_list);
-
-#define _pdb_bwcpoint_alloc(_var) \
-{ \
- if ( (_var = kmalloc(sizeof(bwcpoint_t), GFP_KERNEL)) == NULL ) \
- printk("error: unable to allocate memory %d\n", __LINE__); \
- else { \
- memset(_var, 0, sizeof(bwcpoint_t)); \
- INIT_LIST_HEAD(&_var->watchpt_read_list); \
- INIT_LIST_HEAD(&_var->watchpt_write_list); \
- INIT_LIST_HEAD(&_var->watchpt_access_list); \
- INIT_LIST_HEAD(&_var->watchpt_disabled_list); \
- } \
-}
-
-/***********************************************************************/
-
-static void _pdb_bwc_print_list (struct list_head *, char *, int);
-
-static void
-_pdb_bwc_print (bwcpoint_p bwc, char *label, int level)
-{
- printk("%s%03d 0x%08lx:0x%02x %c\n", label, bwc->type,
- bwc->address, bwc->length, bwc->error ? 'e' : '-');
-
- if ( !list_empty(&bwc->watchpt_read_list) )
- _pdb_bwc_print_list(&bwc->watchpt_read_list, "r", level);
- if ( !list_empty(&bwc->watchpt_write_list) )
- _pdb_bwc_print_list(&bwc->watchpt_write_list, "w", level);
- if ( !list_empty(&bwc->watchpt_access_list) )
- _pdb_bwc_print_list(&bwc->watchpt_access_list, "a", level);
- if ( !list_empty(&bwc->watchpt_disabled_list) )
- _pdb_bwc_print_list(&bwc->watchpt_disabled_list, "d", level);
-}
-
-static void
-_pdb_bwc_print_list (struct list_head *bwc_list, char *label, int level)
-{
- struct list_head *ptr;
- int counter = 0;
-
- list_for_each(ptr, bwc_list)
- {
- bwcpoint_p bwc = list_entry(ptr, bwcpoint_t, list);
- printk(" %s[%02d]%s ", level > 0 ? " " : "", counter++,
- level > 0 ? "" : " ");
- _pdb_bwc_print(bwc, label, level+1);
- }
-
- if (counter == 0)
- {
- printk(" empty list\n");
- }
-}
-
-void
-pdb_bwc_print_list (void)
-{
- _pdb_bwc_print_list(&bwcpoint_list, " ", 0);
-}
-
-bwcpoint_p
-pdb_search_watchpoint (uint32_t process, unsigned long address)
-{
- bwcpoint_p bwc_watch = (bwcpoint_p) 0;
- bwcpoint_p bwc_entry = (bwcpoint_p) 0;
- struct list_head *ptr;
-
- list_for_each(ptr, &bwcpoint_list) /* find bwc page entry */
- {
- bwc_watch = list_entry(ptr, bwcpoint_t, list);
- if (bwc_watch->address == (address & PAGE_MASK)) break;
- }
-
- if ( !bwc_watch )
- {
- return (bwcpoint_p) 0;
- }
-
-#define __pdb_search_watchpoint_list(__list) \
- list_for_each(ptr, (__list)) \
- { \
- bwc_entry = list_entry(ptr, bwcpoint_t, list); \
- if ( bwc_entry->process == process && \
- bwc_entry->address <= address && \
- bwc_entry->address + bwc_entry->length > address ) \
- return bwc_entry; \
- }
-
- __pdb_search_watchpoint_list(&bwc_watch->watchpt_read_list);
- __pdb_search_watchpoint_list(&bwc_watch->watchpt_write_list);
- __pdb_search_watchpoint_list(&bwc_watch->watchpt_access_list);
-
-#undef __pdb_search_watchpoint_list
-
- return (bwcpoint_p) 0;
-}
-
-/*************************************************************/
-
-int
-pdb_suspend (struct task_struct *target)
-{
- uint32_t rc = 0;
-
- force_sig(SIGSTOP, target); /* force_sig_specific ??? */
-
- return rc;
-}
-
-int
-pdb_resume (struct task_struct *target)
-{
- int rc = 0;
-
- wake_up_process(target);
-
- return rc;
-}
-
-/*
- * from linux-2.6.11/arch/i386/kernel/ptrace.c::getreg()
- */
-static unsigned long
-_pdb_get_register (struct task_struct *target, int reg)
-{
- unsigned long result = ~0UL;
- unsigned long offset;
- unsigned char *stack = 0L;
-
- switch (reg)
- {
- case LINUX_FS:
- result = target->thread.fs;
- break;
- case LINUX_GS:
- result = target->thread.gs;
- break;
- case LINUX_DS:
- case LINUX_ES:
- case LINUX_SS:
- case LINUX_CS:
- result = 0xffff;
- /* fall through */
- default:
- if (reg > LINUX_GS)
- reg -= 2;
-
- offset = reg * sizeof(long);
- offset -= sizeof(struct pt_regs);
- stack = (unsigned char *)target->thread.esp0;
- stack += offset;
- result &= *((int *)stack);
- }
-
- return result;
-}
-
-/*
- * from linux-2.6.11/arch/i386/kernel/ptrace.c::putreg()
- */
-static void
-_pdb_set_register (struct task_struct *target, int reg, unsigned long val)
-{
- unsigned long offset;
- unsigned char *stack;
- unsigned long value = val;
-
- switch (reg)
- {
- case LINUX_FS:
- target->thread.fs = value;
- return;
- case LINUX_GS:
- target->thread.gs = value;
- return;
- case LINUX_DS:
- case LINUX_ES:
- value &= 0xffff;
- break;
- case LINUX_SS:
- case LINUX_CS:
- value &= 0xffff;
- break;
- case LINUX_EFL:
- break;
- }
-
- if (reg > LINUX_GS)
- reg -= 2;
- offset = reg * sizeof(long);
- offset -= sizeof(struct pt_regs);
- stack = (unsigned char *)target->thread.esp0;
- stack += offset;
- *(unsigned long *) stack = value;
-
- return;
-}
-
-int
-pdb_read_register (struct task_struct *target, pdb_op_rd_reg_p op)
-{
- int rc = 0;
-
- switch (op->reg)
- {
- case 0: op->value = _pdb_get_register(target, LINUX_EAX); break;
- case 1: op->value = _pdb_get_register(target, LINUX_ECX); break;
- case 2: op->value = _pdb_get_register(target, LINUX_EDX); break;
- case 3: op->value = _pdb_get_register(target, LINUX_EBX); break;
- case 4: op->value = _pdb_get_register(target, LINUX_ESP); break;
- case 5: op->value = _pdb_get_register(target, LINUX_EBP); break;
- case 6: op->value = _pdb_get_register(target, LINUX_ESI); break;
- case 7: op->value = _pdb_get_register(target, LINUX_EDI); break;
- case 8: op->value = _pdb_get_register(target, LINUX_EIP); break;
- case 9: op->value = _pdb_get_register(target, LINUX_EFL); break;
-
- case 10: op->value = _pdb_get_register(target, LINUX_CS); break;
- case 11: op->value = _pdb_get_register(target, LINUX_SS); break;
- case 12: op->value = _pdb_get_register(target, LINUX_DS); break;
- case 13: op->value = _pdb_get_register(target, LINUX_ES); break;
- case 14: op->value = _pdb_get_register(target, LINUX_FS); break;
- case 15: op->value = _pdb_get_register(target, LINUX_GS); break;
- }
-
- return rc;
-}
-
-int
-pdb_read_registers (struct task_struct *target, pdb_op_rd_regs_p op)
-{
- int rc = 0;
-
- op->reg[ 0] = _pdb_get_register(target, LINUX_EAX);
- op->reg[ 1] = _pdb_get_register(target, LINUX_ECX);
- op->reg[ 2] = _pdb_get_register(target, LINUX_EDX);
- op->reg[ 3] = _pdb_get_register(target, LINUX_EBX);
- op->reg[ 4] = _pdb_get_register(target, LINUX_ESP);
- op->reg[ 5] = _pdb_get_register(target, LINUX_EBP);
- op->reg[ 6] = _pdb_get_register(target, LINUX_ESI);
- op->reg[ 7] = _pdb_get_register(target, LINUX_EDI);
- op->reg[ 8] = _pdb_get_register(target, LINUX_EIP);
- op->reg[ 9] = _pdb_get_register(target, LINUX_EFL);
-
- op->reg[10] = _pdb_get_register(target, LINUX_CS);
- op->reg[11] = _pdb_get_register(target, LINUX_SS);
- op->reg[12] = _pdb_get_register(target, LINUX_DS);
- op->reg[13] = _pdb_get_register(target, LINUX_ES);
- op->reg[14] = _pdb_get_register(target, LINUX_FS);
- op->reg[15] = _pdb_get_register(target, LINUX_GS);
-
- return rc;
-}
-
-int
-pdb_write_register (struct task_struct *target, pdb_op_wr_reg_p op)
-{
- int rc = 0;
-
- _pdb_set_register(target, op->reg, op->value);
-
- return rc;
-}
-
-int
-pdb_access_memory (struct task_struct *target, unsigned long address,
- void *buffer, int length, int write)
-{
- int rc = 0;
-
- access_process_vm(target, address, buffer, length, write);
-
- return rc;
-}
-
-int
-pdb_continue (struct task_struct *target)
-{
- int rc = 0;
- unsigned long eflags;
-
- eflags = _pdb_get_register(target, LINUX_EFL);
- eflags &= ~X86_EFLAGS_TF;
- _pdb_set_register(target, LINUX_EFL, eflags);
-
- wake_up_process(target);
-
- return rc;
-}
-
-int
-pdb_step (struct task_struct *target)
-{
- int rc = 0;
- unsigned long eflags;
- bwcpoint_p bkpt;
-
- eflags = _pdb_get_register(target, LINUX_EFL);
- eflags |= X86_EFLAGS_TF;
- _pdb_set_register(target, LINUX_EFL, eflags);
-
- _pdb_bwcpoint_alloc(bkpt);
- if ( bkpt == NULL ) return -1;
-
- bkpt->process = target->pid;
- bkpt->address = 0;
- bkpt->type = BWC_DEBUG;
-
- list_add_tail(&bkpt->list, &bwcpoint_list);
-
- wake_up_process(target);
-
- return rc;
-}
-
-int
-pdb_insert_memory_breakpoint (struct task_struct *target,
- unsigned long address, uint32_t length)
-{
- int rc = 0;
- bwcpoint_p bkpt;
- uint8_t breakpoint_opcode = 0xcc;
-
- printk("insert breakpoint %d:%lx len: %d\n", target->pid, address, length);
-
- if ( length != 1 )
- {
- printk("error: breakpoint length should be 1\n");
- return -1;
- }
-
- _pdb_bwcpoint_alloc(bkpt);
- if ( bkpt == NULL ) return -1;
-
- bkpt->process = target->pid;
- bkpt->address = address;
- bkpt->type = BWC_INT3;
-
- pdb_access_memory(target, address, &bkpt->orig_bkpt, 1, PDB_MEM_READ);
- pdb_access_memory(target, address, &breakpoint_opcode, 1, PDB_MEM_WRITE);
-
- list_add_tail(&bkpt->list, &bwcpoint_list);
-
- printk("breakpoint_set %d:%lx OLD: 0x%x\n",
- target->pid, address, bkpt->orig_bkpt);
- pdb_bwc_print_list();
-
- return rc;
-}
-
-int
-pdb_remove_memory_breakpoint (struct task_struct *target,
- unsigned long address, uint32_t length)
-{
- int rc = 0;
- bwcpoint_p bkpt = NULL;
-
- printk ("remove breakpoint %d:%lx\n", target->pid, address);
-
- struct list_head *entry;
- list_for_each(entry, &bwcpoint_list)
- {
- bkpt = list_entry(entry, bwcpoint_t, list);
- if ( target->pid == bkpt->process &&
- address == bkpt->address &&
- bkpt->type == BWC_INT3 )
- break;
- }
-
- if (entry == &bwcpoint_list)
- {
- printk ("error: no breakpoint found\n");
- return -1;
- }
-
- pdb_access_memory(target, address, &bkpt->orig_bkpt, 1, PDB_MEM_WRITE);
-
- list_del(&bkpt->list);
- kfree(bkpt);
-
- pdb_bwc_print_list();
-
- return rc;
-}
-
-#define PDB_PTE_UPDATE 1
-#define PDB_PTE_RESTORE 2
-
-int
-pdb_change_pte (struct task_struct *target, bwcpoint_p bwc, int mode)
-{
- int rc = 0;
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *ptep;
-
- pgd = pgd_offset(target->mm, bwc->address);
- if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) return -1;
-
- pud = pud_offset(pgd, bwc->address);
- if (pud_none(*pud) || unlikely(pud_bad(*pud))) return -2;
-
- pmd = pmd_offset(pud, bwc->address);
- if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) return -3;
-
- ptep = pte_offset_map(pmd, bwc->address);
- if (!ptep) return -4;
-
- switch ( mode )
- {
- case PDB_PTE_UPDATE: /* added or removed a watchpoint. update pte. */
- {
- pte_t new_pte;
-
- if ( pte_val(bwc->parent->orig_pte) == 0 ) /* new watchpoint page */
- {
- bwc->parent->orig_pte = *ptep;
- }
-
- new_pte = bwc->parent->orig_pte;
-
- if ( !list_empty(&bwc->parent->watchpt_read_list) ||
- !list_empty(&bwc->parent->watchpt_access_list) )
- {
- new_pte = pte_rdprotect(new_pte);
- }
-
- if ( !list_empty(&bwc->parent->watchpt_write_list) ||
- !list_empty(&bwc->parent->watchpt_access_list) )
- {
- new_pte = pte_wrprotect(new_pte);
- }
-
- if ( pte_val(new_pte) != pte_val(*ptep) )
- {
- *ptep = new_pte;
- flush_tlb_mm(target->mm);
- }
- break;
- }
- case PDB_PTE_RESTORE : /* suspend watchpoint by restoring original pte */
- {
- *ptep = bwc->parent->orig_pte;
- flush_tlb_mm(target->mm);
- break;
- }
- default :
- {
- printk("(linux) unknown mode %d %d\n", mode, __LINE__);
- break;
- }
- }
-
- pte_unmap(ptep); /* can i flush the tlb before pte_unmap? */
-
- return rc;
-}
-
-int
-pdb_insert_watchpoint (struct task_struct *target, pdb_op_watchpt_p watchpt)
-{
- int rc = 0;
-
- bwcpoint_p bwc_watch;
- bwcpoint_p bwc_entry;
- struct list_head *ptr;
- unsigned long page = watchpt->address & PAGE_MASK;
- struct list_head *watchpoint_list;
-
- printk("insert watchpoint: %d %x %x\n",
- watchpt->type, watchpt->address, watchpt->length);
-
- list_for_each(ptr, &bwcpoint_list) /* find existing bwc page entry */
- {
- bwc_watch = list_entry(ptr, bwcpoint_t, list);
-
- if (bwc_watch->address == page) goto got_bwc_watch;
- }
-
- _pdb_bwcpoint_alloc(bwc_watch); /* create new bwc:watch */
- if ( bwc_watch == NULL ) return -1;
-
- bwc_watch->type = BWC_WATCH;
- bwc_watch->process = target->pid;
- bwc_watch->address = page;
-
- list_add_tail(&bwc_watch->list, &bwcpoint_list);
-
- got_bwc_watch:
-
- switch (watchpt->type)
- {
- case BWC_WATCH_READ:
- watchpoint_list = &bwc_watch->watchpt_read_list; break;
- case BWC_WATCH_WRITE:
- watchpoint_list = &bwc_watch->watchpt_write_list; break;
- case BWC_WATCH_ACCESS:
- watchpoint_list = &bwc_watch->watchpt_access_list; break;
- default:
- printk("unknown type %d\n", watchpt->type); return -2;
- }
-
- _pdb_bwcpoint_alloc(bwc_entry); /* create new bwc:entry */
- if ( bwc_entry == NULL ) return -1;
-
- bwc_entry->process = target->pid;
- bwc_entry->address = watchpt->address;
- bwc_entry->length = watchpt->length;
- bwc_entry->type = watchpt->type;
- bwc_entry->parent = bwc_watch;
-
- list_add_tail(&bwc_entry->list, watchpoint_list);
- pdb_change_pte(target, bwc_entry, PDB_PTE_UPDATE);
-
- pdb_bwc_print_list();
-
- return rc;
-}
-
-int
-pdb_remove_watchpoint (struct task_struct *target, pdb_op_watchpt_p watchpt)
-{
- int rc = 0;
- bwcpoint_p bwc_watch = (bwcpoint_p) NULL;
- bwcpoint_p bwc_entry = (bwcpoint_p) NULL;
- unsigned long page = watchpt->address & PAGE_MASK;
- struct list_head *ptr;
- struct list_head *watchpoint_list;
-
- printk("remove watchpoint: %d %x %x\n",
- watchpt->type, watchpt->address, watchpt->length);
-
- list_for_each(ptr, &bwcpoint_list) /* find bwc page entry */
- {
- bwc_watch = list_entry(ptr, bwcpoint_t, list);
- if (bwc_watch->address == page) break;
- }
-
- if ( !bwc_watch )
- {
- printk("(linux) delete watchpoint: can't find bwc page 0x%08x\n",
- watchpt->address);
- return -1;
- }
-
- switch (watchpt->type)
- {
- case BWC_WATCH_READ:
- watchpoint_list = &bwc_watch->watchpt_read_list; break;
- case BWC_WATCH_WRITE:
- watchpoint_list = &bwc_watch->watchpt_write_list; break;
- case BWC_WATCH_ACCESS:
- watchpoint_list = &bwc_watch->watchpt_access_list; break;
- default:
- printk("unknown type %d\n", watchpt->type); return -2;
- }
-
- list_for_each(ptr, watchpoint_list) /* find watchpoint */
- {
- bwc_entry = list_entry(ptr, bwcpoint_t, list);
- if ( bwc_entry->address == watchpt->address &&
- bwc_entry->length == watchpt->length ) break;
- }
-
- if ( !bwc_entry ) /* or ptr == watchpoint_list */
- {
- printk("(linux) delete watchpoint: can't find watchpoint 0x%08x\n",
- watchpt->address);
- return -1;
- }
-
- list_del(&bwc_entry->list);
- pdb_change_pte(target, bwc_entry, PDB_PTE_UPDATE);
- kfree(bwc_entry);
-
-
- if ( list_empty(&bwc_watch->watchpt_read_list) &&
- list_empty(&bwc_watch->watchpt_write_list) &&
- list_empty(&bwc_watch->watchpt_access_list) )
- {
- list_del(&bwc_watch->list);
- kfree(bwc_watch);
- }
-
- pdb_bwc_print_list();
-
- return rc;
-}
-
-
-/***************************************************************/
-
-int
-pdb_exceptions_notify (struct notifier_block *self, unsigned long val,
- void *data)
-{
- struct die_args *args = (struct die_args *)data;
-
- switch (val)
- {
- case DIE_DEBUG:
- if ( pdb_debug_fn(args->regs, args->trapnr, args->err) )
- return NOTIFY_STOP;
- break;
- case DIE_TRAP:
- if ( args->trapnr == 3 && pdb_int3_fn(args->regs, args->err) )
- return NOTIFY_STOP;
- break;
- case DIE_INT3: /* without kprobes, we should never see DIE_INT3 */
- if ( pdb_int3_fn(args->regs, args->err) )
- return NOTIFY_STOP;
- break;
- case DIE_PAGE_FAULT:
- if ( pdb_page_fault_fn(args->regs, args->trapnr, args->err) )
- return NOTIFY_STOP;
- break;
- case DIE_GPF:
- printk("---------------GPF\n");
- break;
- default:
- break;
- }
-
- return NOTIFY_DONE;
-}
-
-
-static int
-pdb_debug_fn (struct pt_regs *regs, long error_code,
- unsigned int condition)
-{
- pdb_response_t resp;
- bwcpoint_p bkpt = NULL;
- struct list_head *entry;
-
- printk("pdb_debug_fn\n");
-
- list_for_each(entry, &bwcpoint_list)
- {
- bkpt = list_entry(entry, bwcpoint_t, list);
- if ( current->pid == bkpt->process &&
- (bkpt->type == BWC_DEBUG || /* single step */
- bkpt->type == BWC_WATCH_STEP)) /* single step over watchpoint */
- break;
- }
-
- if (entry == &bwcpoint_list)
- {
- printk("not my debug 0x%x 0x%lx\n", current->pid, regs->eip);
- return 0;
- }
-
- pdb_suspend(current);
-
- printk("(pdb) %s pid: %d, eip: 0x%08lx\n",
- bkpt->type == BWC_DEBUG ? "debug" : "watch-step",
- current->pid, regs->eip);
-
- regs->eflags &= ~X86_EFLAGS_TF;
- set_tsk_thread_flag(current, TIF_SINGLESTEP);
-
- switch (bkpt->type)
- {
- case BWC_DEBUG:
- resp.operation = PDB_OPCODE_STEP;
- break;
- case BWC_WATCH_STEP:
- {
- struct list_head *watchpoint_list;
- bwcpoint_p watch_page = bkpt->watchpoint->parent;
-
- switch (bkpt->watchpoint->type)
- {
- case BWC_WATCH_READ:
- watchpoint_list = &watch_page->watchpt_read_list; break;
- case BWC_WATCH_WRITE:
- watchpoint_list = &watch_page->watchpt_write_list; break;
- case BWC_WATCH_ACCESS:
- watchpoint_list = &watch_page->watchpt_access_list; break;
- default:
- printk("unknown type %d\n", bkpt->watchpoint->type); return 0;
- }
-
- resp.operation = PDB_OPCODE_WATCHPOINT;
- list_del_init(&bkpt->watchpoint->list);
- list_add_tail(&bkpt->watchpoint->list, watchpoint_list);
- pdb_change_pte(current, bkpt->watchpoint, PDB_PTE_UPDATE);
- pdb_bwc_print_list();
- break;
- }
- default:
- printk("unknown breakpoint type %d %d\n", __LINE__, bkpt->type);
- return 0;
- }
-
- resp.process = current->pid;
- resp.status = PDB_RESPONSE_OKAY;
-
- pdb_send_response(&resp);
-
- list_del(&bkpt->list);
- kfree(bkpt);
-
- return 1;
-}
-
-
-static int
-pdb_int3_fn (struct pt_regs *regs, long error_code)
-{
- pdb_response_t resp;
- bwcpoint_p bkpt = NULL;
- unsigned long address = regs->eip - 1;
-
- struct list_head *entry;
- list_for_each(entry, &bwcpoint_list)
- {
- bkpt = list_entry(entry, bwcpoint_t, list);
- if ( current->pid == bkpt->process &&
- address == bkpt->address &&
- bkpt->type == BWC_INT3 )
- break;
- }
-
- if (entry == &bwcpoint_list)
- {
- printk("not my int3 bkpt 0x%x 0x%lx\n", current->pid, address);
- return 0;
- }
-
- printk("(pdb) int3 pid: %d, eip: 0x%08lx\n", current->pid, address);
-
- pdb_suspend(current);
-
- resp.operation = PDB_OPCODE_CONTINUE;
- resp.process = current->pid;
- resp.status = PDB_RESPONSE_OKAY;
-
- pdb_send_response(&resp);
-
- return 1;
-}
-
-static int
-pdb_page_fault_fn (struct pt_regs *regs, long error_code,
- unsigned int condition)
-{
- unsigned long cr2;
- unsigned long cr3;
- bwcpoint_p bwc;
- bwcpoint_p watchpt;
- bwcpoint_p bkpt;
-
- __asm__ __volatile__ ("movl %%cr3,%0" : "=r" (cr3) : );
- __asm__ __volatile__ ("movl %%cr2,%0" : "=r" (cr2) : );
-
- bwc = pdb_search_watchpoint(current->pid, cr2);
- if ( !bwc )
- {
- return 0; /* not mine */
- }
-
- printk("page_fault cr2:%08lx err:%lx eip:%08lx\n",
- cr2, error_code, regs->eip);
-
- /* disable the watchpoint */
- watchpt = bwc->watchpoint;
- list_del_init(&bwc->list);
- list_add_tail(&bwc->list, &bwc->parent->watchpt_disabled_list);
- pdb_change_pte(current, bwc, PDB_PTE_RESTORE);
-
- /* single step the faulting instruction */
- regs->eflags |= X86_EFLAGS_TF;
-
- /* create a bwcpoint entry so we know what to do once we regain control */
- _pdb_bwcpoint_alloc(bkpt);
- if ( bkpt == NULL ) return -1;
-
- bkpt->process = current->pid;
- bkpt->address = 0;
- bkpt->type = BWC_WATCH_STEP;
- bkpt->watchpoint = bwc;
-
- /* add to head so we see it first the next time we break */
- list_add(&bkpt->list, &bwcpoint_list);
-
- pdb_bwc_print_list();
- return 1;
-}
-
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
-
diff --git a/tools/debugger/pdb/linux-2.6-module/module.c b/tools/debugger/pdb/linux-2.6-module/module.c
deleted file mode 100644
index 5ca0e025ca..0000000000
--- a/tools/debugger/pdb/linux-2.6-module/module.c
+++ /dev/null
@@ -1,337 +0,0 @@
-
-/*
- * module.c
- *
- * Handles initial registration with pdb when the pdb module starts up
- * and cleanup when the module goes away (sortof :)
- * Also receives each request from pdb in domain 0 and dispatches to the
- * appropriate debugger function.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include <asm-i386/kdebug.h>
-
-#include <xen/evtchn.h>
-#include <xen/ctrl_if.h>
-#include <xen/hypervisor.h>
-#include <xen/interface/io/domain_controller.h>
-#include <xen/interface/xen.h>
-
-#include <xen/interface/io/ring.h>
-
-#include "pdb_module.h"
-#include "pdb_debug.h"
-
-#define PDB_RING_SIZE __RING_SIZE((pdb_sring_t *)0, PAGE_SIZE)
-
-static pdb_back_ring_t pdb_ring;
-static unsigned int pdb_evtchn;
-static unsigned int pdb_irq;
-static unsigned int pdb_domain;
-
-/* work queue */
-static void pdb_work_handler(void *unused);
-static DECLARE_WORK(pdb_deferred_work, pdb_work_handler, NULL);
-
-/*
- * send response to a pdb request
- */
-void
-pdb_send_response (pdb_response_t *response)
-{
- pdb_response_t *resp;
-
- resp = RING_GET_RESPONSE(&pdb_ring, pdb_ring.rsp_prod_pvt);
-
- memcpy(resp, response, sizeof(pdb_response_t));
- resp->domain = pdb_domain;
-
- wmb(); /* Ensure other side can see the response fields. */
- pdb_ring.rsp_prod_pvt++;
- RING_PUSH_RESPONSES(&pdb_ring);
- notify_via_evtchn(pdb_evtchn);
- return;
-}
-
-/*
- * handle a debug command from the front end
- */
-static void
-pdb_process_request (pdb_request_t *request)
-{
- pdb_response_t resp;
- struct task_struct *target;
-
- read_lock(&tasklist_lock);
- target = find_task_by_pid(request->process);
- if (target)
- get_task_struct(target);
- read_unlock(&tasklist_lock);
-
- resp.operation = request->operation;
- resp.process = request->process;
-
- if (!target)
- {
- printk ("(linux) target not found 0x%x\n", request->process);
- resp.status = PDB_RESPONSE_ERROR;
- goto response;
- }
-
- switch (request->operation)
- {
- case PDB_OPCODE_PAUSE :
- pdb_suspend(target);
- resp.status = PDB_RESPONSE_OKAY;
- break;
- case PDB_OPCODE_ATTACH :
- pdb_suspend(target);
- pdb_domain = request->u.attach.domain;
- printk("(linux) attach dom:0x%x pid:0x%x\n",
- pdb_domain, request->process);
- resp.status = PDB_RESPONSE_OKAY;
- break;
- case PDB_OPCODE_DETACH :
- pdb_resume(target);
- printk("(linux) detach 0x%x\n", request->process);
- resp.status = PDB_RESPONSE_OKAY;
- break;
- case PDB_OPCODE_RD_REG :
- resp.u.rd_reg.reg = request->u.rd_reg.reg;
- pdb_read_register(target, &resp.u.rd_reg);
- resp.status = PDB_RESPONSE_OKAY;
- break;
- case PDB_OPCODE_RD_REGS :
- pdb_read_registers(target, &resp.u.rd_regs);
- resp.status = PDB_RESPONSE_OKAY;
- break;
- case PDB_OPCODE_WR_REG :
- pdb_write_register(target, &request->u.wr_reg);
- resp.status = PDB_RESPONSE_OKAY;
- break;
- case PDB_OPCODE_RD_MEM :
- pdb_access_memory(target, request->u.rd_mem.address,
- &resp.u.rd_mem.data, request->u.rd_mem.length,
- PDB_MEM_READ);
- resp.u.rd_mem.address = request->u.rd_mem.address;
- resp.u.rd_mem.length = request->u.rd_mem.length;
- resp.status = PDB_RESPONSE_OKAY;
- break;
- case PDB_OPCODE_WR_MEM :
- pdb_access_memory(target, request->u.wr_mem.address,
- &request->u.wr_mem.data, request->u.wr_mem.length,
- PDB_MEM_WRITE);
- resp.status = PDB_RESPONSE_OKAY;
- break;
- case PDB_OPCODE_CONTINUE :
- pdb_continue(target);
- goto no_response;
- break;
- case PDB_OPCODE_STEP :
- pdb_step(target);
- resp.status = PDB_RESPONSE_OKAY;
- goto no_response;
- break;
- case PDB_OPCODE_SET_BKPT :
- pdb_insert_memory_breakpoint(target, request->u.bkpt.address,
- request->u.bkpt.length);
- resp.status = PDB_RESPONSE_OKAY;
- break;
- case PDB_OPCODE_CLR_BKPT :
- pdb_remove_memory_breakpoint(target, request->u.bkpt.address,
- request->u.bkpt.length);
- resp.status = PDB_RESPONSE_OKAY;
- break;
- case PDB_OPCODE_SET_WATCHPT :
- pdb_insert_watchpoint(target, &request->u.watchpt);
- resp.status = PDB_RESPONSE_OKAY;
- break;
- case PDB_OPCODE_CLR_WATCHPT :
- pdb_remove_watchpoint(target, &request->u.watchpt);
- resp.status = PDB_RESPONSE_OKAY;
- break;
- default:
- printk("(pdb) unknown request operation %d\n", request->operation);
- resp.status = PDB_RESPONSE_ERROR;
- }
-
- response:
- pdb_send_response (&resp);
-
- no_response:
- return;
-}
-
-/*
- * work queue
- */
-static void
-pdb_work_handler (void *unused)
-{
- pdb_request_t *req;
- RING_IDX i, rp;
-
- rp = pdb_ring.sring->req_prod;
- rmb();
-
- for ( i = pdb_ring.req_cons;
- (i != rp) && !RING_REQUEST_CONS_OVERFLOW(&pdb_ring, i);
- i++ )
- {
- req = RING_GET_REQUEST(&pdb_ring, i);
- pdb_process_request(req);
-
- }
- pdb_ring.req_cons = i;
-}
-
-/*
- * receive a pdb request
- */
-static irqreturn_t
-pdb_interrupt (int irq, void *dev_id, struct pt_regs *ptregs)
-{
- schedule_work(&pdb_deferred_work);
-
- return IRQ_HANDLED;
-}
-
-static void
-pdb_send_connection_status(int status, unsigned long ring)
-{
- ctrl_msg_t cmsg =
- {
- .type = CMSG_DEBUG,
- .subtype = CMSG_DEBUG_CONNECTION_STATUS,
- .length = sizeof(pdb_connection_t),
- };
- pdb_connection_t *conn = (pdb_connection_t *)cmsg.msg;
-
- conn->status = status;
- conn->ring = ring;
- conn->evtchn = 0;
-
- ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
-}
-
-
-/*
- * this is called each time a message is received on the control channel
- */
-static void
-pdb_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
-{
- switch (msg->subtype)
- {
- case CMSG_DEBUG_CONNECTION_STATUS:
- /* initialize event channel created by the pdb server */
-
- pdb_evtchn = ((pdb_connection_p) msg->msg)->evtchn;
- pdb_irq = bind_evtchn_to_irq(pdb_evtchn);
-
- if ( request_irq(pdb_irq, pdb_interrupt,
- SA_SAMPLE_RANDOM, "pdb", NULL) )
- {
- printk("(pdb) request irq failed: %d %d\n", pdb_evtchn, pdb_irq);
- }
- break;
-
- default:
- printk ("(pdb) unknown xcs control message: %d\n", msg->subtype);
- break;
- }
-
- return;
-}
-
-
-/********************************************************************/
-
-static struct notifier_block pdb_exceptions_nb =
-{
- .notifier_call = pdb_exceptions_notify,
- .priority = 0x1 /* low priority */
-};
-
-
-static int __init
-pdb_initialize (void)
-{
- int err;
- pdb_sring_t *sring;
-
- printk("----\npdb initialize %s %s\n", __DATE__, __TIME__);
-
- /*
- if ( xen_start_info.flags & SIF_INITDOMAIN )
- return 1;
- */
-
- pdb_evtchn = 0;
- pdb_irq = 0;
- pdb_domain = 0;
-
- (void)ctrl_if_register_receiver(CMSG_DEBUG, pdb_ctrlif_rx,
- CALLBACK_IN_BLOCKING_CONTEXT);
-
- /* rings */
- sring = (pdb_sring_t *)__get_free_page(GFP_KERNEL);
- SHARED_RING_INIT(sring);
- BACK_RING_INIT(&pdb_ring, sring, PAGE_SIZE);
-
- /* notify pdb in dom 0 */
- pdb_send_connection_status(PDB_CONNECTION_STATUS_UP,
- virt_to_machine(pdb_ring.sring) >> PAGE_SHIFT);
-
- /* handler for int1 & int3 */
- err = register_die_notifier(&pdb_exceptions_nb);
-
- return err;
-}
-
-static void __exit
-pdb_terminate(void)
-{
- int err = 0;
-
- printk("pdb cleanup\n");
-
- (void)ctrl_if_unregister_receiver(CMSG_DEBUG, pdb_ctrlif_rx);
-
- if (pdb_irq)
- {
- free_irq(pdb_irq, NULL);
- pdb_irq = 0;
- }
-
- if (pdb_evtchn)
- {
- unbind_evtchn_from_irq(pdb_evtchn);
- pdb_evtchn = 0;
- }
-
- pdb_send_connection_status(PDB_CONNECTION_STATUS_DOWN, 0);
-
- /* handler for int1 & int3 */
- err = unregister_die_notifier(&pdb_exceptions_nb);
-
- return;
-}
-
-
-module_init(pdb_initialize);
-module_exit(pdb_terminate);
-
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
-
diff --git a/tools/debugger/pdb/linux-2.6-module/pdb_debug.h b/tools/debugger/pdb/linux-2.6-module/pdb_debug.h
deleted file mode 100644
index 89adbc0b0d..0000000000
--- a/tools/debugger/pdb/linux-2.6-module/pdb_debug.h
+++ /dev/null
@@ -1,47 +0,0 @@
-
-#ifndef __PDB_DEBUG_H_
-#define __PDB_DEBUG_H_
-
-/* debugger.c */
-void pdb_initialize_bwcpoint (void);
-int pdb_suspend (struct task_struct *target);
-int pdb_resume (struct task_struct *target);
-int pdb_read_register (struct task_struct *target, pdb_op_rd_reg_p op);
-int pdb_read_registers (struct task_struct *target, pdb_op_rd_regs_p op);
-int pdb_write_register (struct task_struct *target, pdb_op_wr_reg_p op);
-int pdb_read_memory (struct task_struct *target, pdb_op_rd_mem_req_p req,
- pdb_op_rd_mem_resp_p resp);
-int pdb_write_memory (struct task_struct *target, pdb_op_wr_mem_p op);
-int pdb_access_memory (struct task_struct *target, unsigned long address,
- void *buffer, int length, int write);
-int pdb_continue (struct task_struct *target);
-int pdb_step (struct task_struct *target);
-
-int pdb_insert_memory_breakpoint (struct task_struct *target,
- unsigned long address, uint32_t length);
-int pdb_remove_memory_breakpoint (struct task_struct *target,
- unsigned long address, uint32_t length);
-int pdb_insert_watchpoint (struct task_struct *target,
- pdb_op_watchpt_p watchpt);
-int pdb_remove_watchpoint (struct task_struct *target,
- pdb_op_watchpt_p watchpt);
-
-int pdb_exceptions_notify (struct notifier_block *self, unsigned long val,
- void *data);
-
-/* module.c */
-void pdb_send_response (pdb_response_t *response);
-
-#endif
-
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
-
diff --git a/tools/debugger/pdb/linux-2.6-module/pdb_module.h b/tools/debugger/pdb/linux-2.6-module/pdb_module.h
deleted file mode 100644
index 472403d69e..0000000000
--- a/tools/debugger/pdb/linux-2.6-module/pdb_module.h
+++ /dev/null
@@ -1,142 +0,0 @@
-
-#ifndef __PDB_MODULE_H_
-#define __PDB_MODULE_H_
-
-#include "../pdb_caml_xen.h"
-
-#define PDB_OPCODE_PAUSE 1
-
-#define PDB_OPCODE_ATTACH 2
-typedef struct pdb_op_attach
-{
- uint32_t domain;
-} pdb_op_attach_t, *pdb_op_attach_p;
-
-#define PDB_OPCODE_DETACH 3
-
-#define PDB_OPCODE_RD_REG 4
-typedef struct pdb_op_rd_reg
-{
- uint32_t reg;
- uint32_t value;
-} pdb_op_rd_reg_t, *pdb_op_rd_reg_p;
-
-#define PDB_OPCODE_RD_REGS 5
-typedef struct pdb_op_rd_regs
-{
- uint32_t reg[GDB_REGISTER_FRAME_SIZE];
-} pdb_op_rd_regs_t, *pdb_op_rd_regs_p;
-
-#define PDB_OPCODE_WR_REG 6
-typedef struct pdb_op_wr_reg
-{
- uint32_t reg;
- uint32_t value;
-} pdb_op_wr_reg_t, *pdb_op_wr_reg_p;
-
-#define PDB_OPCODE_RD_MEM 7
-typedef struct pdb_op_rd_mem_req
-{
- uint32_t address;
- uint32_t length;
-} pdb_op_rd_mem_req_t, *pdb_op_rd_mem_req_p;
-
-typedef struct pdb_op_rd_mem_resp
-{
- uint32_t address;
- uint32_t length;
- uint8_t data[1024];
-} pdb_op_rd_mem_resp_t, *pdb_op_rd_mem_resp_p;
-
-#define PDB_OPCODE_WR_MEM 8
-typedef struct pdb_op_wr_mem
-{
- uint32_t address;
- uint32_t length;
- uint8_t data[1024]; /* arbitrary */
-} pdb_op_wr_mem_t, *pdb_op_wr_mem_p;
-
-#define PDB_OPCODE_CONTINUE 9
-#define PDB_OPCODE_STEP 10
-
-#define PDB_OPCODE_SET_BKPT 11
-#define PDB_OPCODE_CLR_BKPT 12
-typedef struct pdb_op_bkpt
-{
- uint32_t address;
- uint32_t length;
-} pdb_op_bkpt_t, *pdb_op_bkpt_p;
-
-#define PDB_OPCODE_SET_WATCHPT 13
-#define PDB_OPCODE_CLR_WATCHPT 14
-#define PDB_OPCODE_WATCHPOINT 15
-typedef struct pdb_op_watchpt
-{
-#define BWC_DEBUG 1
-#define BWC_INT3 3
-#define BWC_WATCH 100 /* pdb: watchpoint page */
-#define BWC_WATCH_STEP 101 /* pdb: watchpoint single step */
-#define BWC_WATCH_WRITE 102
-#define BWC_WATCH_READ 103
-#define BWC_WATCH_ACCESS 104
- uint32_t type;
- uint32_t address;
- uint32_t length;
-} pdb_op_watchpt_t, *pdb_op_watchpt_p;
-
-
-typedef struct
-{
- uint8_t operation; /* PDB_OPCODE_??? */
- uint32_t process;
- union
- {
- pdb_op_attach_t attach;
- pdb_op_rd_reg_t rd_reg;
- pdb_op_wr_reg_t wr_reg;
- pdb_op_rd_mem_req_t rd_mem;
- pdb_op_wr_mem_t wr_mem;
- pdb_op_bkpt_t bkpt;
- pdb_op_watchpt_t watchpt;
- } u;
-} pdb_request_t, *pdb_request_p;
-
-
-
-#define PDB_RESPONSE_OKAY 0
-#define PDB_RESPONSE_ERROR -1
-
-typedef struct {
- uint8_t operation; /* copied from request */
- uint32_t domain;
- uint32_t process;
- int16_t status; /* PDB_RESPONSE_??? */
- union
- {
- pdb_op_rd_reg_t rd_reg;
- pdb_op_rd_regs_t rd_regs;
- pdb_op_rd_mem_resp_t rd_mem;
- } u;
-} pdb_response_t, *pdb_response_p;
-
-
-DEFINE_RING_TYPES(pdb, pdb_request_t, pdb_response_t);
-
-
-/* from access_process_vm */
-#define PDB_MEM_READ 0
-#define PDB_MEM_WRITE 1
-
-#endif
-
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
-