static int find_possible_edges(int offset, int len, uint8_t *memory, struct call_graph *graph) { int i; for (i = 0; i < len; i += 2) { struct msp430_instruction insn; if (dis_decode(memory + i, offset + i, len - i, &insn) < 0) continue; if (insn.dst_mode == MSP430_AMODE_IMMEDIATE && (insn.op == MSP430_OP_CALL || insn.op == MSP430_OP_BR) && !(insn.dst_addr & 1)) { struct cg_edge br; br.src = offset + i; br.dst = insn.dst_addr; br.is_tail_call = insn.op != MSP430_OP_CALL; if (vector_push(&graph->edge_from, &br, 1) < 0) return -1; } } return 0; }
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; }
void disassemble(address_t offset, const uint8_t *data, int length) { int first_line = 1; while (length) { struct msp430_instruction insn = {0}; int retval; int count; int i; address_t oboff; char obname[64]; if (!stab_nearest(offset, obname, sizeof(obname), &oboff) && !oboff) { printc("\x1b[m%s\x1b[0m:\n", obname); } else if (first_line) { print_address(offset, obname, sizeof(obname)); printc("\x1b[m%s\x1b[0m:\n", obname); } first_line = 0; retval = dis_decode(data, offset, length, &insn); count = retval > 0 ? retval : 2; if (count > length) count = length; printc(" \x1b[36m%05x\x1b[0m:", offset); for (i = 0; i < count; i++) printc(" %02x", data[i]); while (i < 9) { printc(" "); i++; } if (retval >= 0) dis_format(&insn); printc("\n"); offset += count; length -= count; data += count; } }
void disassemble(address_t offset, const uint8_t *data, int length, powerbuf_t power) { int first_line = 1; unsigned long long ua_total = 0; int samples_total = 0; while (length) { struct msp430_instruction insn = {0}; int retval; int count; int i; address_t oboff; char obname[MAX_SYMBOL_LENGTH]; if (first_line || (!stab_nearest(offset, obname, sizeof(obname), &oboff) && !oboff)) { char buffer[MAX_SYMBOL_LENGTH]; print_address(offset, buffer, sizeof(buffer), 0); printc("\x1b[m%s\x1b[0m:\n", buffer); } first_line = 0; retval = dis_decode(data, offset, length, &insn); count = retval > 0 ? retval : 2; if (count > length) count = length; printc(" \x1b[36m%05x\x1b[0m:", offset); for (i = 0; i < count; i++) printc(" %02x", data[i]); while (i < 9) { printc(" "); i++; } if (retval >= 0) i = dis_format(&insn); if (power) { unsigned long long ua; int samples; while (i < 40) { printc(" "); i++; } samples = powerbuf_get_by_mab(power, offset, &ua); if (samples) { printc(" ;; %.01f uA", (double)ua / (double)samples); ua_total += ua; samples_total += samples; } } printc("\n"); offset += count; length -= count; data += count; } if (power && samples_total) printc(";; Total over this block: " "%.01f uAs in %.01f ms (%.01f uA avg)\n", (double)(ua_total * power->interval_us) / 1000000.0, (double)(samples_total * power->interval_us) / 1000.0, (double)ua_total / (double)samples_total); }