示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
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);
}