34 uint8_t bp_num, uint8_t bp_type, uint8_t bp_length);
37 uint32_t
addr, uint8_t *buf);
39 uint32_t
addr,
const uint8_t *buf);
58 struct reg **reg_list[],
int *reg_list_size,
65 LOG_DEBUG(
"num_regs=%d, reg_class=%d", (*reg_list_size), reg_class);
66 *reg_list = malloc(
sizeof(
struct reg *) * (*reg_list_size));
72 for (i = 0; i < (*reg_list_size); i++) {
122 *physical = dsb + address;
163 bool pg_disabled =
false;
164 LOG_DEBUG(
"addr=0x%08" PRIx32
", size=%" PRIu32
", count=0x%" PRIx32
", buf=%p",
171 LOG_ERROR(
"%s invalid params count=0x%" PRIx32
", buf=%p, addr=0x%08" PRIx32,
180 LOG_ERROR(
"%s could not disable paging", __func__);
186 for (uint32_t i = 0; i <
count; i++) {
198 LOG_ERROR(
"%s invalid read size", __func__);
208 LOG_ERROR(
"%s could not enable paging", __func__);
224 uint8_t *newbuffer =
NULL;
251 pbiter = pbiter->
next;
267 bool pg_disabled =
false;
269 LOG_DEBUG(
"addr=0x%08" PRIx32
", size=%" PRIu32
", count=0x%" PRIx32
", buf=%p",
274 LOG_ERROR(
"%s invalid params count=0x%" PRIx32
", buf=%p, addr=0x%08" PRIx32,
288 LOG_ERROR(
"%s could not disable paging", __func__);
293 for (uint32_t i = 0; i <
count; i++) {
313 LOG_ERROR(
"%s could not enable paging", __func__);
321 uint32_t
addr, uint8_t *buf)
329 LOG_ERROR(
"%s error write EAX", __func__);
353 LOG_ERROR(
"%s invalid read mem size", __func__);
367 LOG_ERROR(
"%s error read EDX", __func__);
370 for (uint8_t i = 0; i <
size; i++)
371 buf[i] = (regval >> (i*8)) & 0x000000FF;
375 LOG_ERROR(
"%s error on mem read", __func__);
382 uint32_t
addr,
const uint8_t *buf)
385 uint32_t buf4bytes = 0;
389 for (i = 0; i <
size; ++i) {
390 buf4bytes = buf4bytes << 8;
391 buf4bytes += buf[(
size-1)-i];
397 LOG_ERROR(
"%s error write EAX", __func__);
406 LOG_ERROR(
"%s error write EDX", __func__);
429 LOG_ERROR(
"%s invalid write mem size", __func__);
438 LOG_ERROR(
"%s error on mem write", __func__);
446 uint8_t entry_buffer[8];
464 bool is_pae = cr4 & 0x00000020;
468 uint32_t pdpt_base = cr3 & 0xFFFFF000;
469 uint32_t pdpt_index = (
addr & 0xC0000000) >> 30;
470 uint32_t pdpt_addr = pdpt_base + (8 * pdpt_index);
472 LOG_ERROR(
"%s couldn't read page directory pointer table entry at 0x%08" PRIx32,
473 __func__, pdpt_addr);
477 if (!(pdpt_entry & 0x0000000000000001)) {
478 LOG_ERROR(
"%s page directory pointer table entry at 0x%08" PRIx32
" is not present",
479 __func__, pdpt_addr);
483 uint32_t pd_base = pdpt_entry & 0xFFFFF000;
484 uint32_t pd_index = (
addr & 0x3FE00000) >> 21;
485 uint32_t pd_addr = pd_base + (8 * pd_index);
487 LOG_ERROR(
"%s couldn't read page directory entry at 0x%08" PRIx32,
492 if (!(pd_entry & 0x0000000000000001)) {
493 LOG_ERROR(
"%s page directory entry at 0x%08" PRIx32
" is not present",
499 if (pd_entry & 0x0000000000000080) {
501 uint32_t page_base = (uint32_t)(pd_entry & 0x00000000FFE00000);
503 *physaddr = page_base +
offset;
508 uint32_t pt_base = (uint32_t)(pd_entry & 0x00000000FFFFF000);
509 uint32_t pt_index = (
addr & 0x001FF000) >> 12;
510 uint32_t pt_addr = pt_base + (8 * pt_index);
512 LOG_ERROR(
"%s couldn't read page table entry at 0x%08" PRIx32, __func__, pt_addr);
516 if (!(pt_entry & 0x0000000000000001)) {
517 LOG_ERROR(
"%s page table entry at 0x%08" PRIx32
" is not present", __func__, pt_addr);
521 uint32_t page_base = (uint32_t)(pt_entry & 0x00000000FFFFF000);
523 *physaddr = page_base +
offset;
527 uint32_t pd_base = cr3 & 0xFFFFF000;
528 uint32_t pd_index = (
addr & 0xFFC00000) >> 22;
529 uint32_t pd_addr = pd_base + (4 * pd_index);
531 LOG_ERROR(
"%s couldn't read page directory entry at 0x%08" PRIx32, __func__, pd_addr);
535 if (!(pd_entry & 0x00000001)) {
536 LOG_ERROR(
"%s page directory entry at 0x%08" PRIx32
" is not present", __func__, pd_addr);
542 if (pd_entry & 0x00000080) {
544 uint32_t page_base = pd_entry & 0xFFC00000;
545 *physaddr = page_base + (
addr & 0x003FFFFF);
549 uint32_t pt_base = pd_entry & 0xFFFFF000;
550 uint32_t pt_index = (
addr & 0x003FF000) >> 12;
551 uint32_t pt_addr = pt_base + (4 * pt_index);
553 LOG_ERROR(
"%s couldn't read page table entry at 0x%08" PRIx32, __func__, pt_addr);
557 if (!(pt_entry & 0x00000001)) {
558 LOG_ERROR(
"%s page table entry at 0x%08" PRIx32
" is not present", __func__, pt_addr);
561 uint32_t page_base = pt_entry & 0xFFFFF000;
562 *physaddr = page_base + (
addr & 0x00000FFF);
569 uint32_t
size, uint32_t
count, uint8_t *buf)
588 LOG_ERROR(
"%s could not disable paging", __func__);
610 LOG_ERROR(
"%s could not enable paging", __func__);
626 uint32_t
size, uint32_t
count,
const uint8_t *buf)
644 LOG_ERROR(
"%s could not disable paging", __func__);
665 LOG_ERROR(
"%s could not enable paging", __func__);
681 uint32_t
size, uint8_t *buf)
687 bool pg_disabled =
false;
691 LOG_ERROR(
"%s invalid params buf=%p, addr=%08" PRIx32, __func__, buf,
addr);
696 LOG_ERROR(
"%s error EDX write", __func__);
703 LOG_ERROR(
"%s could not disable paging", __func__);
728 LOG_ERROR(
"%s invalid read io size", __func__);
736 LOG_ERROR(
"%s could not enable paging", __func__);
747 LOG_ERROR(
"%s error on read EAX", __func__);
750 for (uint8_t i = 0; i <
size; i++)
751 buf[i] = (regval >> (i*8)) & 0x000000FF;
754 LOG_ERROR(
"%s error on io read", __func__);
761 uint32_t
size,
const uint8_t *buf)
769 bool pg_disabled =
false;
771 LOG_ERROR(
"%s invalid params buf=%p, addr=0x%08" PRIx32, __func__, buf,
addr);
777 LOG_ERROR(
"%s error on EDX write", __func__);
781 for (uint8_t i = 0; i <
size; i++)
782 regval += (buf[i] << (i*8));
785 LOG_ERROR(
"%s error on EAX write", __func__);
792 LOG_ERROR(
"%s could not disable paging", __func__);
817 LOG_ERROR(
"%s invalid write io size", __func__);
825 LOG_ERROR(
"%s could not enable paging", __func__);
835 LOG_ERROR(
"%s error on io write", __func__);
882 uint8_t bp_num, uint8_t bp_type, uint8_t bp_length)
885 LOG_DEBUG(
"addr=0x%08" PRIx32
", bp_num=%" PRIu8
", bp_type=%" PRIu8
", pb_length=%" PRIu8,
886 address, bp_num, bp_type, bp_length);
891 if (bp_length != 1 && bp_length != 2 && bp_length != 4)
897 LOG_ERROR(
"%s dr7 error, already enabled, val=%08" PRIx32, __func__, dr7);
914 LOG_ERROR(
"%s unsupported feature bp_type=%d", __func__, bp_type);
923 LOG_ERROR(
"%s invalid request [only 0-3] bp_type=%d", __func__, bp_type);
952 LOG_ERROR(
"%s dr7 error, not enabled, val=0x%08" PRIx32, __func__, dr7);
977 uint8_t hwbp_num = 0;
979 while (debug_reg_list[hwbp_num].
used && (hwbp_num < x86_32->num_hw_bpoints))
988 debug_reg_list[hwbp_num].
used = 1;
990 LOG_USER(
"%s hardware breakpoint %" PRIu32
" set at 0x%08" PRIx32
" (hwreg=%" PRIu8
")", __func__,
999 int hwbp_num = bp->
number;
1002 LOG_ERROR(
"%s invalid breakpoint number=%d, bpid=%" PRIu32,
1009 debug_reg_list[hwbp_num].
used = 0;
1010 debug_reg_list[hwbp_num].
bp_value = 0;
1043 LOG_ERROR(
"%s readback=0x%02" PRIx8
" orig=0x%02" PRIx8
"",
1052 LOG_ERROR(
"%s out of memory", __func__);
1065 addto = addto->
next;
1066 addto->
next = new_patch;
1078 uint8_t current_instr;
1092 LOG_ERROR(
"%s current=0x%02" PRIx8
" orig=0x%02" PRIx8
"",
1146 LOG_ERROR(
"%s core doesn't support SW breakpoints", __func__);
1186 LOG_ERROR(
"%s watchpoint already set", __func__);
1191 LOG_ERROR(
"%s no support for 'read' watchpoints, use 'access' or 'write'"
1196 while (debug_reg_list[wp_num].
used && (wp_num < x86_32->num_hw_bpoints))
1199 LOG_ERROR(
"%s no debug registers left", __func__);
1204 LOG_ERROR(
"%s only watchpoints of length 1, 2 or 4 are supported", __func__);
1222 LOG_ERROR(
"%s only 'access' or 'write' watchpoints are supported", __func__);
1226 debug_reg_list[wp_num].
used = 1;
1247 LOG_DEBUG(
"Invalid FP Comparator number in watchpoint");
1253 debug_reg_list[wp_num].
used = 0;
1254 debug_reg_list[wp_num].
bp_value = 0;
1292 debug_reg_list[i].
used = 0;
1336 const unsigned int line_bytecnt = 32;
1337 unsigned int line_modulo = line_bytecnt /
size;
1339 char output[line_bytecnt * 4 + 1];
1340 unsigned int output_len = 0;
1342 const char *value_fmt;
1345 value_fmt =
"%8.8x ";
1348 value_fmt =
"%4.4x ";
1351 value_fmt =
"%2.2x ";
1355 LOG_ERROR(
"%s invalid memory read size: %u", __func__,
size);
1359 for (
unsigned int i = 0; i <
count; i++) {
1360 if (i % line_modulo == 0) {
1361 output_len += snprintf(
output + output_len,
1362 sizeof(
output) - output_len,
1363 "0x%8.8" PRIx32
": ",
1364 address + (i *
size));
1368 const uint8_t *value_ptr =
buffer + i *
size;
1379 output_len += snprintf(
output + output_len,
1380 sizeof(
output) - output_len,
1383 if ((i % line_modulo == line_modulo - 1) || (i ==
count - 1)) {
1397 if (address > 0xffff) {
1398 LOG_ERROR(
"%s IA-32 I/O space is 2^16, 0x%08" PRIx32
" exceeds max", __func__, address);
1402 unsigned int size = 0;
1416 unsigned int count = 1;
1428 unsigned int data_size,
1432 LOG_DEBUG(
"address=0x%08" PRIx32
", data_size=%u, b=0x%08" PRIx32,
1433 address, data_size, b);
1434 uint8_t target_buf[data_size];
1435 switch (data_size) {
1443 target_buf[0] = (b & 0x0ff);
1461 unsigned int wordsize;
1482 .handler = handle_iow_command,
1483 .help =
"write I/O port word",
1484 .usage =
"port data[word]",
1489 .handler = handle_iow_command,
1490 .help =
"write I/O port halfword",
1491 .usage =
"port data[halfword]",
1496 .handler = handle_iow_command,
1497 .help =
"write I/O port byte",
1498 .usage =
"port data[byte]",
1503 .handler = handle_iod_command,
1504 .help =
"display I/O port word",
1510 .handler = handle_iod_command,
1511 .help =
"display I/O port halfword",
1517 .handler = handle_iod_command,
1518 .help =
"display I/O port byte",
1529 .help =
"x86_32 target commands",
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
static void buf_set_u32(uint8_t *_buffer, unsigned int first, unsigned int num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
static void watchpoint_set(struct watchpoint *watchpoint, unsigned int number)
static void breakpoint_hw_set(struct breakpoint *breakpoint, unsigned int hw_number)
void command_print(struct command_invocation *cmd, const char *format,...)
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
#define CMD_NAME
Use this macro to access the name of the command being handled, rather than accessing the variable di...
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
#define ERROR_COMMAND_SYNTAX_ERROR
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
#define ERROR_COMMAND_ARGUMENT_INVALID
bool check_not_halted(const struct target *t)
#define LOG_USER(expr ...)
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_DEBUG(expr ...)
target_addr_t addr
Start address to search for the control block.
size_t size
Size of the control block search area.
enum breakpoint_type type
When run_command is called, a new instance will be created on the stack, filled with the proper value...
struct swbp_mem_patch * next
struct breakpoint * breakpoints
struct watchpoint * watchpoints
int(* read_hw_reg_to_cache)(struct target *target, int num)
struct swbp_mem_patch * swbbp_mem_patch_list
bool(* sw_bpts_supported)(struct target *t)
int(* disable_paging)(struct target *t)
struct x86_32_dbg_reg * hw_break_list
int(* write_hw_reg_from_cache)(struct target *target, int num)
int(* read_hw_reg)(struct target *t, int reg, uint32_t *regval, uint8_t cache)
bool(* is_paging_enabled)(struct target *t)
uint8_t(* get_num_user_regs)(struct target *t)
int(* write_hw_reg)(struct target *t, int reg, uint32_t regval, uint8_t cache)
int(* enable_paging)(struct target *t)
int(* submit_instruction)(struct target *t, int num)
struct jtag_tap * curr_tap
struct working_area * fast_data_area
unsigned int common_magic
int(* transaction_status)(struct target *t)
uint64_t target_buffer_get_u64(struct target *target, const uint8_t *buffer)
void target_buffer_set_u16(struct target *target, uint8_t *buffer, uint16_t value)
void target_buffer_set_u32(struct target *target, uint8_t *buffer, uint32_t value)
uint16_t target_buffer_get_u16(struct target *target, const uint8_t *buffer)
struct target * get_current_target(struct command_context *cmd_ctx)
uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer)
#define ERROR_TARGET_NOT_HALTED
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
static int write_mem(struct target *t, uint32_t size, uint32_t addr, const uint8_t *buf)
static int set_swbp(struct target *t, struct breakpoint *bp)
static int unset_hwbp(struct target *t, struct breakpoint *bp)
static int unset_breakpoint(struct target *target, struct breakpoint *breakpoint)
const struct command_registration x86_32_command_handlers[]
int x86_32_common_add_watchpoint(struct target *t, struct watchpoint *wp)
int x86_32_common_read_io(struct target *t, uint32_t addr, uint32_t size, uint8_t *buf)
int x86_32_common_read_memory(struct target *t, target_addr_t addr, uint32_t size, uint32_t count, uint8_t *buf)
static int write_hw_reg_from_cache(struct target *t, int num)
static int unset_watchpoint(struct target *target, struct watchpoint *watchpoint)
int x86_32_common_init_arch_info(struct target *t, struct x86_32_common *x86_32)
static int calcaddr_physfromlin(struct target *t, target_addr_t addr, target_addr_t *physaddr)
int x86_32_common_add_breakpoint(struct target *t, struct breakpoint *bp)
int x86_32_common_virt2phys(struct target *t, target_addr_t address, target_addr_t *physical)
int x86_32_common_write_memory(struct target *t, target_addr_t addr, uint32_t size, uint32_t count, const uint8_t *buf)
int x86_32_get_gdb_reg_list(struct target *t, struct reg **reg_list[], int *reg_list_size, enum target_register_class reg_class)
static int target_fill_io(struct target *target, uint32_t address, unsigned int data_size, uint32_t b)
static int read_hw_reg_to_cache(struct target *t, int num)
static const struct command_registration x86_32_exec_command_handlers[]
static int set_watchpoint(struct target *target, struct watchpoint *watchpoint)
static int unset_swbp(struct target *t, struct breakpoint *bp)
int x86_32_common_read_phys_mem(struct target *t, target_addr_t phys_address, uint32_t size, uint32_t count, uint8_t *buffer)
static int set_hwbp(struct target *t, struct breakpoint *bp)
int x86_32_common_remove_watchpoint(struct target *t, struct watchpoint *wp)
static int set_debug_regs(struct target *t, uint32_t address, uint8_t bp_num, uint8_t bp_type, uint8_t bp_length)
int x86_32_common_mmu(struct target *t, int *enabled)
static int read_phys_mem(struct target *t, uint32_t phys_address, uint32_t size, uint32_t count, uint8_t *buffer)
static int unset_debug_regs(struct target *t, uint8_t bp_num)
static int set_breakpoint(struct target *target, struct breakpoint *breakpoint)
static int read_mem(struct target *t, uint32_t size, uint32_t addr, uint8_t *buf)
void x86_32_common_reset_breakpoints_watchpoints(struct target *t)
int x86_32_common_write_phys_mem(struct target *t, target_addr_t phys_address, uint32_t size, uint32_t count, const uint8_t *buffer)
static int write_phys_mem(struct target *t, uint32_t phys_address, uint32_t size, uint32_t count, const uint8_t *buffer)
COMMAND_HANDLER(handle_iod_command)
static void handle_iod_output(struct command_invocation *cmd, struct target *target, uint32_t address, unsigned int size, unsigned int count, const uint8_t *buffer)
int x86_32_common_write_io(struct target *t, uint32_t addr, uint32_t size, const uint8_t *buf)
int x86_32_common_remove_breakpoint(struct target *t, struct breakpoint *bp)
#define DR7_SET_LENGTH(val, regnum, len)
#define DR7_SET_WRITE(val, regnum)
#define DR7_BP_FREE(val, regnum)
#define DR7_SET_EXE(val, regnum)
static struct x86_32_common * target_to_x86_32(struct target *target)
#define DR7_GLOBAL_ENABLE(val, regnum)
#define DR7_RESET_RWLEN_BITS(val, regnum)
#define DR7_SET_ACCESS(val, regnum)
#define X86_32_COMMON_MAGIC
#define DR7_GLOBAL_DISABLE(val, regnum)