Use kdb_jmpbuf and setjmp to handle accessing invalid addresses in the

debugger memory access functions. This allows us to correctly reenter into
the debugger on failure.

Sponsored by:	ABT Systems Ltd
This commit is contained in:
Andrew Turner 2015-08-25 17:02:28 +00:00
parent 84a9a3a344
commit 7a1ac4a701

View File

@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <machine/cpu.h> #include <machine/cpu.h>
#include <machine/pcb.h> #include <machine/pcb.h>
#include <machine/stack.h>
#include <machine/vmparam.h> #include <machine/vmparam.h>
static int static int
@ -107,37 +108,28 @@ db_show_mdpcpu(struct pcpu *pc)
{ {
} }
static int
db_validate_address(vm_offset_t addr)
{
struct proc *p = curproc;
struct pmap *pmap;
if (!p || !p->p_vmspace || !p->p_vmspace->vm_map.pmap ||
addr >= VM_MAXUSER_ADDRESS)
pmap = pmap_kernel();
else
pmap = p->p_vmspace->vm_map.pmap;
return (pmap_extract(pmap, addr) != 0);
}
/* /*
* Read bytes from kernel address space for debugger. * Read bytes from kernel address space for debugger.
*/ */
int int
db_read_bytes(vm_offset_t addr, size_t size, char *data) db_read_bytes(vm_offset_t addr, size_t size, char *data)
{ {
const char *src = (const char *)addr; jmp_buf jb;
void *prev_jb;
const char *src;
int ret;
while (size-- > 0) { prev_jb = kdb_jmpbuf(jb);
if (db_validate_address((vm_offset_t)src)) { ret = setjmp(jb);
db_printf("address %p is invalid\n", src);
return (-1); if (ret == 0) {
} src = (const char *)addr;
while (size-- > 0)
*data++ = *src++; *data++ = *src++;
} }
return (0); (void)kdb_jmpbuf(prev_jb);
return (ret);
} }
/* /*
@ -146,21 +138,25 @@ db_read_bytes(vm_offset_t addr, size_t size, char *data)
int int
db_write_bytes(vm_offset_t addr, size_t size, char *data) db_write_bytes(vm_offset_t addr, size_t size, char *data)
{ {
jmp_buf jb;
void *prev_jb;
char *dst; char *dst;
int ret;
prev_jb = kdb_jmpbuf(jb);
ret = setjmp(jb);
if (ret == 0) {
dst = (char *)addr; dst = (char *)addr;
while (size-- > 0) { while (size-- > 0)
if (db_validate_address((vm_offset_t)dst)) {
db_printf("address %p is invalid\n", dst);
return (-1);
}
*dst++ = *data++; *dst++ = *data++;
}
dsb(ish); dsb(ish);
/* Clean D-cache and invalidate I-cache */ /* Clean D-cache and invalidate I-cache */
cpu_dcache_wb_range(addr, (vm_size_t)size); cpu_dcache_wb_range(addr, (vm_size_t)size);
cpu_icache_sync_range(addr, (vm_size_t)size); cpu_icache_sync_range(addr, (vm_size_t)size);
}
return (0); (void)kdb_jmpbuf(prev_jb);
return (ret);
} }