static int do_isearch(address_t addr, address_t len, const struct isearch_query *q) { uint8_t *mbuf; address_t i; mbuf = malloc(len); if (!mbuf) { printc_err("isearch: couldn't allocate memory: %s\n", last_error()); return -1; } if (device_readmem(addr, mbuf, len) < 0) { printc_err("isearch: couldn't read device memory\n"); free(mbuf); return -1; } addr &= ~1; len &= ~1; for (i = 0; i < len; i += 2) { struct msp430_instruction insn; int count = dis_decode(mbuf + i, addr + i, len - i, &insn); if (count >= 0 && isearch_match(&insn, q)) disassemble(addr + i, mbuf + i, count, device_default->power_buf); } free(mbuf); return 0; }
static int read_memory(struct gdb_data *data, char *text) { char *length_text = strchr(text, ','); address_t length, addr; uint8_t buf[GDB_MAX_XFER]; int i; if (!length_text) { printc_err("gdb: malformed memory read request\n"); return gdb_send(data, "E00"); } *(length_text++) = 0; length = strtoul(length_text, NULL, 16); addr = strtoul(text, NULL, 16); if (length > sizeof(buf)) length = sizeof(buf); printc("Reading %4d bytes from 0x%04x\n", length, addr); if (device_readmem(addr, buf, length) < 0) return gdb_send(data, "E00"); gdb_packet_start(data); for (i = 0; i < length; i++) gdb_printf(data, "%02x", buf[i]); gdb_packet_end(data); return gdb_flush_ack(data); }
int prog_flush(struct prog_data *prog) { if (!prog->len) return 0; if (!prog->have_erased && (prog->flags & PROG_WANT_ERASE)) { printc("Erasing...\n"); if (device_erase(DEVICE_ERASE_MAIN, 0) < 0) return -1; printc("Programming...\n"); prog->have_erased = 1; } printc_dbg("%s %4d bytes at %04x", (prog->flags & PROG_VERIFY) ? "Verifying" : "Writing", prog->len, prog->addr); if (prog->section[0]) printc_dbg(" [section: %s]", prog->section); printc_dbg("...\n"); if (prog->flags & PROG_VERIFY) { uint8_t cmp_buf[PROG_BUFSIZE]; int i; if (device_readmem(prog->addr, cmp_buf, prog->len) < 0) return -1; for (i = 0; i < prog->len; i++) if (cmp_buf[i] != prog->buf[i]) { printc("\x1b[1mERROR:\x1b[0m " "mismatch at %04x (read %02x, " "expected %02x)\n", prog->addr + i, cmp_buf[i], prog->buf[i]); return -1; } } else { if (device_writemem(prog->addr, prog->buf, prog->len) < 0) return -1; } prog->total_written += prog->len; prog->addr += prog->len; prog->len = 0; return 0; }
int cmd_dis(char **arg) { char *off_text = get_arg(arg); char *len_text = get_arg(arg); address_t offset = 0; address_t length = 0x40; uint8_t *buf; if (!off_text) { printc_err("dis: offset must be specified\n"); return -1; } if (expr_eval(off_text, &offset) < 0) { printc_err("dis: can't parse offset: %s\n", off_text); return -1; } if (len_text) { if (expr_eval(len_text, &length) < 0) { printc_err("dis: can't parse length: %s\n", len_text); return -1; } } else if (offset < 0x10000 && offset + length > 0x10000) { length = 0x10000 - offset; } buf = malloc(length); if (!buf) { pr_error("dis: couldn't allocate memory"); return -1; } if (device_readmem(offset, buf, length) < 0) { free(buf); return -1; } reader_set_repeat("dis 0x%x 0x%x", offset + length, length); disassemble(offset, buf, length, device_default->power_buf); free(buf); return 0; }
int cmd_md(char **arg) { char *off_text = get_arg(arg); char *len_text = get_arg(arg); address_t offset = 0; address_t length = 0x40; if (!off_text) { printc_err("md: offset must be specified\n"); return -1; } if (expr_eval(off_text, &offset) < 0) { printc_err("md: can't parse offset: %s\n", off_text); return -1; } if (len_text) { if (expr_eval(len_text, &length) < 0) { printc_err("md: can't parse length: %s\n", len_text); return -1; } } else if (offset < 0x10000 && offset + length > 0x10000) { length = 0x10000 - offset; } reader_set_repeat("md 0x%x 0x%x", offset + length, length); while (length) { uint8_t buf[4096]; int blen = length > sizeof(buf) ? sizeof(buf) : length; if (device_readmem(offset, buf, blen) < 0) return -1; hexdump(offset, buf, blen); offset += blen; length -= blen; } return 0; }
int cmd_regs(char **arg) { address_t regs[DEVICE_NUM_REGS]; uint8_t code[16]; int len = sizeof(code); (void)arg; if (device_getregs(regs) < 0) return -1; show_regs(regs); /* Try to disassemble the instruction at PC */ if (len > 0x10000 - regs[0]) len = 0x10000 - regs[0]; if (device_readmem(regs[0], code, len) < 0) return 0; disassemble(regs[0], (uint8_t *)code, len, device_default->power_buf); return 0; }
int cmd_cgraph(char **arg) { char *offset_text, *len_text, *addr_text;; address_t offset, len, addr; uint8_t *memory; struct call_graph graph; /* Figure out what the arguments are */ offset_text = get_arg(arg); len_text = get_arg(arg); addr_text = get_arg(arg); if (!(offset_text && len_text)) { printc_err("cgraph: offset and length must be " "specified\n"); return -1; } if (expr_eval(offset_text, &offset) < 0) { printc_err("cgraph: invalid offset: %s\n", offset_text); return -1; } offset &= ~1; if (expr_eval(len_text, &len) < 0) { printc_err("cgraph: invalid length: %s\n", len_text); return -1; } len &= ~1; if (addr_text && expr_eval(addr_text, &addr) < 0) { printc_err("cgraph: invalid address: %s\n", addr_text); return -1; } /* Grab the memory to be analysed */ memory = malloc(len); if (!memory) { printc_err("cgraph: couldn't allocate memory: %s\n", last_error()); return -1; } if (device_readmem(offset, memory, len) < 0) { printc_err("cgraph: couldn't fetch memory\n"); free(memory); return -1; } /* Produce and display the call graph */ if (cgraph_init(offset, len, memory, &graph) < 0) { printc_err("cgraph: couldn't build call graph\n"); free(memory); return -1; } free(memory); if (addr_text) cgraph_func_info(&graph, addr); else cgraph_summary(&graph); cgraph_destroy(&graph); return 0; }