void db_task_trap( int type, int code, boolean_t user_space) { jmp_buf_t db_jmpbuf; jmp_buf_t *prev; boolean_t bkpt; boolean_t watchpt; task_t task; task_t task_space; task = db_current_task(); task_space = db_target_space(current_act(), user_space); bkpt = IS_BREAKPOINT_TRAP(type, code); watchpt = IS_WATCHPOINT_TRAP(type, code); /* * Note: we look up PC values in an address space (task_space), * but print symbols using a (task-specific) symbol table, found * using task. */ db_init_default_act(); db_check_breakpoint_valid(); if (db_stop_at_pc(&bkpt, task, task_space)) { if (db_inst_count) { db_printf("After %d instructions (%d loads, %d stores),\n", db_inst_count, db_load_count, db_store_count); } if (bkpt) db_printf("Breakpoint at "); else if (watchpt) db_printf("Watchpoint at "); else db_printf("Stopped at "); db_dot = PC_REGS(DDB_REGS); prev = db_recover; if (_setjmp(db_recover = &db_jmpbuf) == 0) { #if defined(__alpha) db_print_loc(db_dot, task_space); db_printf("\n\t"); db_print_inst(db_dot, task_space); #else /* !defined(__alpha) */ #if defined(__powerpc__) db_print_loc_and_inst(db_dot, task_space); #else /* __powerpc__ */ db_print_loc_and_inst(db_dot, task); #endif /* __powerpc__ */ #endif /* defined(__alpha) */ } else db_printf("Trouble printing location %#X.\n", db_dot); db_recover = prev; db_command_loop(); } db_restart_at_pc(watchpt, task_space); }
void db_read_bytes( vm_offset_t addr, int size, char *data, task_t task) { char *src; int n; vm_offset_t kern_addr; src = (char *)addr; if ((addr >= VM_MIN_KERNEL_ADDRESS && addr < VM_MAX_KERNEL_ADDRESS) || task == TASK_NULL) { if (task == TASK_NULL) task = db_current_task(); while (--size >= 0) { if (addr < VM_MIN_KERNEL_ADDRESS && task == TASK_NULL) { db_printf("\nbad address %x\n", addr); db_error(0); /* NOTREACHED */ } addr++; *data++ = *src++; } return; } while (size > 0) { if (db_user_to_kernel_address(task, addr, &kern_addr, 1) < 0) return; src = (char *)kern_addr; n = intel_trunc_page(addr+INTEL_PGBYTES) - addr; if (n > size) n = size; size -= n; addr += n; while (--n >= 0) *data++ = *src++; } }
/* * Write bytes to kernel address space for debugger. */ void db_write_bytes( vm_offset_t addr, int size, char *data, task_t task) { char *dst; pt_entry_t *ptep0 = 0; pt_entry_t oldmap0 = 0; vm_offset_t addr1; pt_entry_t *ptep1 = 0; pt_entry_t oldmap1 = 0; extern char etext; if ((addr < VM_MIN_KERNEL_ADDRESS) ^ ((addr + size) <= VM_MIN_KERNEL_ADDRESS)) { db_error("\ncannot write data into mixed space\n"); /* NOTREACHED */ } if (addr < VM_MIN_KERNEL_ADDRESS) { if (task) { db_write_bytes_user_space(addr, size, data, task); return; } else if (db_current_task() == TASK_NULL) { db_printf("\nbad address %x\n", addr); db_error(0); /* NOTREACHED */ } } if (addr >= VM_MIN_KERNEL_ADDRESS && addr <= (vm_offset_t)&etext) { ptep0 = pmap_pte(kernel_pmap, addr); oldmap0 = *ptep0; *ptep0 |= INTEL_PTE_WRITE; addr1 = i386_trunc_page(addr + size - 1); if (i386_trunc_page(addr) != addr1) { /* data crosses a page boundary */ ptep1 = pmap_pte(kernel_pmap, addr1); oldmap1 = *ptep1; *ptep1 |= INTEL_PTE_WRITE; } if (CPU_HAS_FEATURE(CPU_FEATURE_PGE)) set_cr4(get_cr4() & ~CR4_PGE); flush_tlb(); } dst = (char *)addr; while (--size >= 0) *dst++ = *data++; if (ptep0) { *ptep0 = oldmap0; if (ptep1) { *ptep1 = oldmap1; } flush_tlb(); if (CPU_HAS_FEATURE(CPU_FEATURE_PGE)) set_cr4(get_cr4() | CR4_PGE); } }