Add support for 8 byte hardware watches in long mode. Kernel hardware
watches support 8 byte watches. For userland, we disallow 8 byte watches for 32-bit tasks.
This commit is contained in:
parent
4fca587ae7
commit
81efc3d94c
@ -562,7 +562,7 @@ amd64_set_watch(watchnum, watchaddr, size, access, d)
|
||||
}
|
||||
|
||||
/*
|
||||
* we can watch a 1, 2, or 4 byte sized location
|
||||
* we can watch a 1, 2, 4, or 8 byte sized location
|
||||
*/
|
||||
switch (size) {
|
||||
case 1:
|
||||
@ -574,6 +574,9 @@ amd64_set_watch(watchnum, watchaddr, size, access, d)
|
||||
case 4:
|
||||
len = DBREG_DR7_LEN_4;
|
||||
break;
|
||||
case 8:
|
||||
len = DBREG_DR7_LEN_8;
|
||||
break;
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
@ -624,12 +627,14 @@ db_md_set_watchpoint(addr, size)
|
||||
avail++;
|
||||
}
|
||||
|
||||
if (avail * 4 < size)
|
||||
if (avail * 8 < size)
|
||||
return (-1);
|
||||
|
||||
for (i = 0; i < 4 && (size > 0); i++) {
|
||||
if (!DBREG_DR7_ENABLED(d.dr[7], i)) {
|
||||
if (size > 2)
|
||||
if (size >= 8 || (avail == 1 && size > 4))
|
||||
wsize = 8;
|
||||
else if (size > 2)
|
||||
wsize = 4;
|
||||
else
|
||||
wsize = size;
|
||||
@ -637,6 +642,7 @@ db_md_set_watchpoint(addr, size)
|
||||
DBREG_DR7_WRONLY, &d);
|
||||
addr += wsize;
|
||||
size -= wsize;
|
||||
avail--;
|
||||
}
|
||||
}
|
||||
|
||||
@ -699,8 +705,12 @@ db_md_list_watchpoints()
|
||||
if (DBREG_DR7_ENABLED(d.dr[7], i)) {
|
||||
type = DBREG_DR7_ACCESS(d.dr[7], i);
|
||||
len = DBREG_DR7_LEN(d.dr[7], i);
|
||||
if (len == DBREG_DR7_LEN_8)
|
||||
len = 8;
|
||||
else
|
||||
len++;
|
||||
db_printf(" %-5d %-8s %10s %3d ",
|
||||
i, "enabled", watchtype_str(type), len + 1);
|
||||
i, "enabled", watchtype_str(type), len);
|
||||
db_printsym((db_addr_t)DBREG_DRX((&d), i), DB_STGY_ANY);
|
||||
db_printf("\n");
|
||||
} else {
|
||||
|
@ -1711,7 +1711,8 @@ set_dbregs(struct thread *td, struct dbreg *dbregs)
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (DBREG_DR7_ACCESS(dbregs->dr[7], i) == 0x02)
|
||||
return (EINVAL);
|
||||
if (DBREG_DR7_LEN(dbregs->dr[7], i) == 0x02)
|
||||
if (td->td_frame->tf_cs == _ucode32sel &&
|
||||
DBREG_DR7_LEN(dbregs->dr[7], i) == DBREG_DR7_LEN_8)
|
||||
return (EINVAL);
|
||||
}
|
||||
if ((dbregs->dr[6] & 0xffffffff00000000ul) != 0 ||
|
||||
|
@ -97,6 +97,7 @@ struct dbreg {
|
||||
#define DBREG_DR7_LEN_1 0x00 /* 1 byte length */
|
||||
#define DBREG_DR7_LEN_2 0x01
|
||||
#define DBREG_DR7_LEN_4 0x03
|
||||
#define DBREG_DR7_LEN_8 0x02
|
||||
#define DBREG_DR7_EXEC 0x00 /* break on execute */
|
||||
#define DBREG_DR7_WRONLY 0x01 /* break on write */
|
||||
#define DBREG_DR7_RDWR 0x03 /* break on read or write */
|
||||
|
Loading…
Reference in New Issue
Block a user