?? x86bc.c
字號(hào):
return (yasm_effaddr *)x86_ea;}/*@=compmempass@*/yasm_effaddr *yasm_x86__bc_insn_get_ea(yasm_bytecode *bc){ if (!bc) return NULL; if (bc->callback != &x86_bc_callback_insn) yasm_internal_error(N_("Trying to get EA of non-instruction")); return (yasm_effaddr *)(((x86_insn *)bc)->ea);}voidyasm_x86__bc_insn_opersize_override(yasm_bytecode *bc, unsigned int opersize){ if (!bc) return; if (bc->callback == &x86_bc_callback_insn) { x86_insn *insn = (x86_insn *)bc; insn->opersize = (unsigned char)opersize; } else if (bc->callback == &x86_bc_callback_jmp) { x86_jmp *jmp = (x86_jmp *)bc; jmp->opersize = (unsigned char)opersize; } else yasm_internal_error(N_("OperSize override applied to non-instruction"));}voidyasm_x86__bc_insn_addrsize_override(yasm_bytecode *bc, unsigned int addrsize){ if (!bc) return; if (bc->callback == &x86_bc_callback_insn) { x86_insn *insn = (x86_insn *)bc; insn->addrsize = (unsigned char)addrsize; } else if (bc->callback == &x86_bc_callback_jmp) { x86_jmp *jmp = (x86_jmp *)bc; jmp->addrsize = (unsigned char)addrsize; } else yasm_internal_error(N_("AddrSize override applied to non-instruction"));}voidyasm_x86__bc_insn_set_lockrep_prefix(yasm_bytecode *bc, unsigned int prefix, unsigned long line){ unsigned char *lockrep_pre = (unsigned char *)NULL; if (!bc) return; if (bc->callback == &x86_bc_callback_insn) { x86_insn *insn = (x86_insn *)bc; lockrep_pre = &insn->lockrep_pre; } else if (bc->callback == &x86_bc_callback_jmp) { x86_jmp *jmp = (x86_jmp *)bc; lockrep_pre = &jmp->lockrep_pre; } else yasm_internal_error(N_("LockRep prefix applied to non-instruction")); if (*lockrep_pre != 0) yasm__warning(YASM_WARN_GENERAL, line, N_("multiple LOCK or REP prefixes, using leftmost")); *lockrep_pre = (unsigned char)prefix;}static voidx86_bc_insn_destroy(yasm_bytecode *bc){ x86_insn *insn = (x86_insn *)bc; if (insn->ea) yasm_ea_destroy((yasm_effaddr *)insn->ea); if (insn->imm) { yasm_expr_destroy(insn->imm->val); yasm_xfree(insn->imm); }}static voidx86_bc_jmp_destroy(yasm_bytecode *bc){ x86_jmp *jmp = (x86_jmp *)bc; yasm_expr_destroy(jmp->target);}static voidx86_ea_destroy(yasm_effaddr *ea){}static voidx86_ea_print(const yasm_effaddr *ea, FILE *f, int indent_level){ const x86_effaddr *x86_ea = (const x86_effaddr *)ea; fprintf(f, "%*sSegmentOv=%02x PCRel=%u\n", indent_level, "", (unsigned int)x86_ea->segment, (unsigned int)x86_ea->pcrel); fprintf(f, "%*sModRM=%03o ValidRM=%u NeedRM=%u\n", indent_level, "", (unsigned int)x86_ea->modrm, (unsigned int)x86_ea->valid_modrm, (unsigned int)x86_ea->need_modrm); fprintf(f, "%*sSIB=%03o ValidSIB=%u NeedSIB=%u\n", indent_level, "", (unsigned int)x86_ea->sib, (unsigned int)x86_ea->valid_sib, (unsigned int)x86_ea->need_sib);}static voidx86_bc_insn_print(const yasm_bytecode *bc, FILE *f, int indent_level){ const x86_insn *insn = (const x86_insn *)bc; fprintf(f, "%*s_Instruction_\n", indent_level, ""); fprintf(f, "%*sEffective Address:", indent_level, ""); if (insn->ea) { fprintf(f, "\n"); yasm_ea_print((yasm_effaddr *)insn->ea, f, indent_level+1); } else fprintf(f, " (nil)\n"); fprintf(f, "%*sImmediate Value:", indent_level, ""); if (!insn->imm) fprintf(f, " (nil)\n"); else { indent_level++; fprintf(f, "\n%*sVal=", indent_level, ""); if (insn->imm->val) yasm_expr_print(insn->imm->val, f); else fprintf(f, "(nil-SHOULDN'T HAPPEN)"); fprintf(f, "\n"); fprintf(f, "%*sLen=%u, Sign=%u\n", indent_level, "", (unsigned int)insn->imm->len, (unsigned int)insn->imm->sign); indent_level--; } fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n", indent_level, "", (unsigned int)insn->opcode[0], (unsigned int)insn->opcode[1], (unsigned int)insn->opcode[2], (unsigned int)insn->opcode_len); fprintf(f, "%*sAddrSize=%u OperSize=%u LockRepPre=%02x SpPre=%02x REX=%03o\n", indent_level, "", (unsigned int)insn->addrsize, (unsigned int)insn->opersize, (unsigned int)insn->lockrep_pre, (unsigned int)insn->special_prefix, (unsigned int)insn->rex); fprintf(f, "%*sShiftOp=%u BITS=%u\n", indent_level, "", (unsigned int)insn->shift_op, (unsigned int)insn->mode_bits);}static voidx86_bc_jmp_print(const yasm_bytecode *bc, FILE *f, int indent_level){ const x86_jmp *jmp = (const x86_jmp *)bc; fprintf(f, "%*s_Jump_\n", indent_level, ""); fprintf(f, "%*sTarget=", indent_level, ""); yasm_expr_print(jmp->target, f); fprintf(f, "%*sOrigin=\n", indent_level, ""); yasm_symrec_print(jmp->origin, f, indent_level+1); fprintf(f, "\n%*sShort Form:\n", indent_level, ""); if (jmp->shortop.opcode_len == 0) fprintf(f, "%*sNone\n", indent_level+1, ""); else fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n", indent_level+1, "", (unsigned int)jmp->shortop.opcode[0], (unsigned int)jmp->shortop.opcode[1], (unsigned int)jmp->shortop.opcode[2], (unsigned int)jmp->shortop.opcode_len); fprintf(f, "%*sNear Form:\n", indent_level, ""); if (jmp->nearop.opcode_len == 0) fprintf(f, "%*sNone\n", indent_level+1, ""); else fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n", indent_level+1, "", (unsigned int)jmp->nearop.opcode[0], (unsigned int)jmp->nearop.opcode[1], (unsigned int)jmp->nearop.opcode[2], (unsigned int)jmp->nearop.opcode_len); fprintf(f, "%*sFar Form:\n", indent_level, ""); if (jmp->farop.opcode_len == 0) fprintf(f, "%*sNone\n", indent_level+1, ""); else fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n", indent_level+1, "", (unsigned int)jmp->farop.opcode[0], (unsigned int)jmp->farop.opcode[1], (unsigned int)jmp->farop.opcode[2], (unsigned int)jmp->farop.opcode_len); fprintf(f, "%*sOpSel=", indent_level, ""); switch (jmp->op_sel) { case JMP_NONE: fprintf(f, "None"); break; case JMP_SHORT: fprintf(f, "Short"); break; case JMP_NEAR: fprintf(f, "Near"); break; case JMP_SHORT_FORCED: fprintf(f, "Forced Short"); break; case JMP_NEAR_FORCED: fprintf(f, "Forced Near"); break; case JMP_FAR: fprintf(f, "Far"); break; default: fprintf(f, "UNKNOWN!!"); break; } fprintf(f, "\n%*sAddrSize=%u OperSize=%u LockRepPre=%02x\n", indent_level, "", (unsigned int)jmp->addrsize, (unsigned int)jmp->opersize, (unsigned int)jmp->lockrep_pre); fprintf(f, "%*sBITS=%u\n", indent_level, "", (unsigned int)jmp->mode_bits);}static yasm_bc_resolve_flagsx86_bc_insn_resolve(yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist){ x86_insn *insn = (x86_insn *)bc; /*@null@*/ yasm_expr *temp; x86_effaddr *x86_ea = insn->ea; yasm_effaddr *ea = &x86_ea->ea; yasm_immval *imm = insn->imm; yasm_bc_resolve_flags retval = YASM_BC_RESOLVE_MIN_LEN; if (ea) { /* Create temp copy of disp, etc. */ x86_effaddr eat = *x86_ea; /* structure copy */ unsigned char displen = ea->len; if (ea->disp) { temp = yasm_expr_copy(ea->disp); assert(temp != NULL); /* Handle shortmov special-casing */ if (insn->shortmov_op && insn->mode_bits == 64 && insn->addrsize == 32 && !yasm_expr__contains(temp, YASM_EXPR_REG)) { yasm_x86__ea_set_disponly((yasm_effaddr *)&eat); if (save) { /* Make the short form permanent. */ insn->opcode[0] = insn->opcode[1]; } } /* Check validity of effective address and calc R/M bits of * Mod/RM byte and SIB byte. We won't know the Mod field * of the Mod/RM byte until we know more about the * displacement. */ switch (yasm_x86__expr_checkea(&temp, &insn->addrsize, insn->mode_bits, ea->nosplit, &displen, &eat.modrm, &eat.valid_modrm, &eat.need_modrm, &eat.sib, &eat.valid_sib, &eat.need_sib, &eat.pcrel, &insn->rex, calc_bc_dist)) { case 1: yasm_expr_destroy(temp); /* failed, don't bother checking rest of insn */ return YASM_BC_RESOLVE_UNKNOWN_LEN|YASM_BC_RESOLVE_ERROR; case 2: yasm_expr_destroy(temp); /* failed, don't bother checking rest of insn */ return YASM_BC_RESOLVE_UNKNOWN_LEN; default: yasm_expr_destroy(temp); /* okay */ break; } if (displen != 1) { /* Fits into a word/dword, or unknown. */ retval = YASM_BC_RESOLVE_NONE; /* may not be smallest size */ /* Handle unknown case, make displen word-sized */ if (displen == 0xff) displen = (insn->addrsize == 16) ? 2U : 4U; } /* If we had forced ea->len but had to override, save it now */ if (ea->len != 0 && ea->len != displen) ea->len = displen; if (save) { *x86_ea = eat; /* structure copy */ ea->len = displen; if (displen == 0 && ea->disp) { yasm_expr_destroy(ea->disp); ea->disp = NULL; } } } /* Compute length of ea and add to total */ bc->len += eat.need_modrm + (eat.need_sib ? 1:0) + displen; bc->len += (eat.segment != 0) ? 1 : 0; } if (imm) { const yasm_intnum *num; unsigned int immlen = imm->len; if (imm->val) { temp = yasm_expr_copy(imm->val); assert(temp != NULL); /* TODO: check imm->len vs. sized len from expr? */ /* Handle shift_op special-casing */ if (insn->shift_op && temp && (num = yasm_expr_get_intnum(&temp, calc_bc_dist))) { if (num && yasm_intnum_get_uint(num) == 1) { /* We can use the ,1 form: subtract out the imm len * (as we add it back in below). */ bc->len -= imm->len; if (save) { /* Make the ,1 form permanent. */ insn->opcode[0] = insn->opcode[1]; /* Delete imm, as it's not needed. */ yasm_expr_destroy(imm->val); yasm_xfree(imm); insn->imm = (yasm_immval *)NULL; } } else retval = YASM_BC_RESOLVE_NONE; /* we could still get ,1 */ /* Not really necessary, but saves confusion over it. */ if (save) insn->shift_op = 0; } yasm_expr_destroy(temp); } bc->len += immlen; } bc->len += insn->opcode_len; bc->len += (insn->addrsize != 0 && insn->addrsize != insn->mode_bits) ? 1:0; if (insn->opersize != 0 && ((insn->mode_bits != 64 && insn->opersize != insn->mode_bits) || (insn->mode_bits == 64 && insn->opersize == 16))) bc->len++; bc->len += (insn->special_prefix != 0) ? 1:0; bc->len += (insn->lockrep_pre != 0) ? 1:0; if (insn->rex != 0xff && (insn->rex != 0 || (insn->mode_bits == 64 && insn->opersize == 64 && insn->def_opersize_64 != 64))) bc->len++; return retval;}static yasm_bc_resolve_flagsx86_bc_jmp_resolve(yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist){ x86_jmp *jmp = (x86_jmp *)bc; yasm_bc_resolve_flags retval = YASM_BC_RESOLVE_MIN_LEN; /*@null@*/ yasm_expr *temp; /*@dependent@*/ /*@null@*/ const yasm_intnum *num; long rel; unsigned char opersize; x86_jmp_opcode_sel jrtype = JMP_NONE; /* As opersize may be 0, figure out its "real" value. */ opersize = (jmp->opersize == 0) ? jmp->mode_bits : jmp->opersize; /* We only check to see if forced forms are actually legal if we're in * save mode. Otherwise we assume that they are legal. */ switch (jmp->op_sel) { case JMP_SHORT_FORCED: /* 1 byte relative displacement */ jrtype = JMP_SHORT; if (save) { temp = yasm_expr_copy(jmp->target); temp = yasm_expr_create(YASM_EXPR_SUB, yasm_expr_expr(temp), yasm_expr_sym(jmp->origin), bc->line); num = yasm_expr_get_intnum(&temp, calc_bc_dist); if (!num) { yasm__error(bc->line, N_("short jump target external or out of segment")); yasm_expr_destroy(temp); return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN; } else {
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -