(watchnum, watchaddr, size, access, d)
| 391 | } |
| 392 | |
| 393 | int |
| 394 | amd64_set_watch(watchnum, watchaddr, size, access, d) |
| 395 | int watchnum; |
| 396 | unsigned long watchaddr; |
| 397 | int size; |
| 398 | int access; |
| 399 | struct dbreg *d; |
| 400 | { |
| 401 | int i, len; |
| 402 | |
| 403 | if (watchnum == -1) { |
| 404 | for (i = 0; i < 4; i++) |
| 405 | if (!DBREG_DR7_ENABLED(d->dr[7], i)) |
| 406 | break; |
| 407 | if (i < 4) |
| 408 | watchnum = i; |
| 409 | else |
| 410 | return (-1); |
| 411 | } |
| 412 | |
| 413 | switch (access) { |
| 414 | case DBREG_DR7_EXEC: |
| 415 | size = 1; /* size must be 1 for an execution breakpoint */ |
| 416 | /* fall through */ |
| 417 | case DBREG_DR7_WRONLY: |
| 418 | case DBREG_DR7_RDWR: |
| 419 | break; |
| 420 | default: |
| 421 | return (-1); |
| 422 | } |
| 423 | |
| 424 | /* |
| 425 | * we can watch a 1, 2, 4, or 8 byte sized location |
| 426 | */ |
| 427 | switch (size) { |
| 428 | case 1: |
| 429 | len = DBREG_DR7_LEN_1; |
| 430 | break; |
| 431 | case 2: |
| 432 | len = DBREG_DR7_LEN_2; |
| 433 | break; |
| 434 | case 4: |
| 435 | len = DBREG_DR7_LEN_4; |
| 436 | break; |
| 437 | case 8: |
| 438 | len = DBREG_DR7_LEN_8; |
| 439 | break; |
| 440 | default: |
| 441 | return (-1); |
| 442 | } |
| 443 | |
| 444 | /* clear the bits we are about to affect */ |
| 445 | d->dr[7] &= ~DBREG_DR7_MASK(watchnum); |
| 446 | |
| 447 | /* set drN register to the address, N=watchnum */ |
| 448 | DBREG_DRX(d, watchnum) = watchaddr; |
| 449 | |
| 450 | /* enable the watchpoint */ |
no outgoing calls
no test coverage detected