unwind_interval * process_unconditional_branch(xed_decoded_inst_t *xptr, bool irdebug, interval_arg_t *iarg, mem_alloc m_alloc) { unwind_interval *next = iarg->current; if ((iarg->highwatermark).state == HW_UNINITIALIZED) { (iarg->highwatermark).uwi = iarg->current; (iarg->highwatermark).state = HW_INITIALIZED; } reset_to_canonical_interval(xptr, &next, irdebug, iarg, m_alloc); TMSG(TAIL_CALL,"checking for tail call via unconditional branch @ %p",iarg->ins); void *possible = x86_get_branch_target(iarg->ins, xptr); if (possible == NULL) { TMSG(TAIL_CALL,"indirect unconditional branch ==> possible tail call"); UWI_RECIPE(next)->has_tail_calls = true; } else if ((possible >= iarg->end) || ((uintptr_t)possible < UWI_START_ADDR(iarg->first))) { TMSG(TAIL_CALL,"unconditional branch to address %p outside of current routine (%p to %p)", possible, UWI_START_ADDR(iarg->first), iarg->end); UWI_RECIPE(next)->has_tail_calls = true; } return next; }
unwind_interval * process_conditional_branch(xed_decoded_inst_t *xptr, interval_arg_t *iarg) { highwatermark_t *hw_tmp = &(iarg->highwatermark); if (hw_tmp->state == HW_UNINITIALIZED) { hw_tmp->uwi = iarg->current; hw_tmp->state = HW_INITIALIZED; } TMSG(TAIL_CALL,"checking for tail call via unconditional branch @ %p",iarg->ins); void *possible = x86_get_branch_target(iarg->ins, xptr); if (possible == NULL) { TMSG(TAIL_CALL,"indirect unconditional branch ==> possible tail call"); UWI_RECIPE(iarg->current)->has_tail_calls = true; } else if ((possible > iarg->end) || ((uintptr_t)possible < UWI_START_ADDR(iarg->first))) { TMSG(TAIL_CALL,"unconditional branch to address %p outside of current routine (%p to %p)", possible, UWI_START_ADDR(iarg->first), iarg->end); UWI_RECIPE(iarg->current)->has_tail_calls = true; } return iarg->current; }
void IMG_addrlabels(Image_t *img, int secid) { assert(img != NULL); Section_t *sec; x86_insn_t insn; sec = IMG_getsection(img, secid); if (sec->plan == NULL) { return; } #if 0 sec->data = (uint8_t *)BUF_getptr(sec->buf_data); printf("%d %02X\n", secid, sec->data[0]); printf("%d %02X\n", 1, *((uint8_t *)IMG_getptr(img, uaddr_mk(1, 0)))); return; #endif uaddr_t min_target = uaddr_mk(secid, 0); uaddr_t max_target = uaddr_mk(secid, IMG_getsecsize(img, secid)); IMG_begintransaction(img); //for (int pos = 0; pos < 349; pos++) { int count = 0; for (int pos = 0; pos < sec->size; pos++) { int len = plan_size(sec->plan, pos); if (PLAN_ISCODE(sec->plan, pos)) { x86_disasm((unsigned char *)sec->data, sec->size, uaddr_mk(secid, 0), pos, &insn); x86_op_t *op = x86_get_branch_target(&insn); int rel; int relsize = 0; bool found = false; // ve se essa instrucao tem algum operando if (op != NULL) { // so nos interessam operandos relativos (jumps) if (op->type == op_relative_near) { found = true; rel = (int)op->data.relative_near; relsize = 1; } else if (op->type == op_relative_far) { found = true; rel = op->data.relative_far; relsize = 4; //// FIXME pode ser 2 em 16 bits } } if (found) { int disp = 0; uaddr_t target = insn.addr + insn.size + rel; //printf("%d ADD LABEL L%08X\n", pos, target); //IMG_addlabel(img, target, NULL); // Se necessário, desloca o label até o início de uma instrução if ((target < min_target) || (target >= max_target)) { printf("ERROR: relative jump/call at %08X points to %08X\n", uaddr_mk(secid, pos), target); x86_oplist_free(&insn); IMG_endtransaction(img); return; } #if 1 for (;;) { uint8_t uuu = sec->plan[uaddr_off(target)]; //if (!((uuu & CP_INSIDE) || (uuu == CP_DATA2))) { if (!(uuu & PLAN_INSIDE)) { break; } disp++; target--; } #endif //printf("%d\n", disp); //printf("%08X %08X\n", uaddr_mk(secid, pos), target); //printf("%08X %08X\n", uaddr_mk(secid, pos), target); #if 1 uaddr_t afrom = uaddr_mk(secid, pos) + 1; if (sec->data[pos] == 0x0F) { afrom += 1; } IMG_addreloc(img, afrom, target, relsize, disp, RELOC_REL); // FIXME::: SIZE 0?? #endif count++; } x86_oplist_free(&insn); } pos += len - 1; } IMG_endtransaction(img); //printf("; %d labels added\n", count); }