switch (insn->opcode.bytes[0]) { case 0xf: switch (insn->opcode.bytes[1]) { case 0x01: switch (insn->modrm.bytes[0]) { case 0xc2: /* vmlaunch */ case 0xc3: /* vmresume */
op = INTEL_PT_OP_VMENTRY;
branch = INTEL_PT_BR_INDIRECT; break; case 0xca: switch (insn->prefixes.bytes[3]) { case 0xf2: /* erets */
op = INTEL_PT_OP_ERETS;
branch = INTEL_PT_BR_INDIRECT; break; case 0xf3: /* eretu */
op = INTEL_PT_OP_ERETU;
branch = INTEL_PT_BR_INDIRECT; break; default: break;
} break; default: break;
} break; case 0x05: /* syscall */ case 0x34: /* sysenter */
op = INTEL_PT_OP_SYSCALL;
branch = INTEL_PT_BR_INDIRECT; break; case 0x07: /* sysret */ case 0x35: /* sysexit */
op = INTEL_PT_OP_SYSRET;
branch = INTEL_PT_BR_INDIRECT; break; case 0x80 ... 0x8f: /* jcc */
op = INTEL_PT_OP_JCC;
branch = INTEL_PT_BR_CONDITIONAL; break; default: break;
} break; case 0x70 ... 0x7f: /* jcc */
op = INTEL_PT_OP_JCC;
branch = INTEL_PT_BR_CONDITIONAL; break; case 0xa1: if (insn_is_rex2(insn)) { /* jmpabs */
intel_pt_insn->op = INTEL_PT_OP_JMP; /* jmpabs causes a TIP packet like an indirect branch */
intel_pt_insn->branch = INTEL_PT_BR_INDIRECT;
intel_pt_insn->length = insn->length; return;
} break; case 0xc2: /* near ret */ case 0xc3: /* near ret */ case 0xca: /* far ret */ case 0xcb: /* far ret */
op = INTEL_PT_OP_RET;
branch = INTEL_PT_BR_INDIRECT; break; case 0xcf: /* iret */
op = INTEL_PT_OP_IRET;
branch = INTEL_PT_BR_INDIRECT; break; case 0xcc ... 0xce: /* int */
op = INTEL_PT_OP_INT;
branch = INTEL_PT_BR_INDIRECT; break; case 0xe8: /* call near rel */
op = INTEL_PT_OP_CALL;
branch = INTEL_PT_BR_UNCONDITIONAL; break; case 0x9a: /* call far absolute */
op = INTEL_PT_OP_CALL;
branch = INTEL_PT_BR_INDIRECT; break; case 0xe0 ... 0xe2: /* loop */
op = INTEL_PT_OP_LOOP;
branch = INTEL_PT_BR_CONDITIONAL; break; case 0xe3: /* jcc */
op = INTEL_PT_OP_JCC;
branch = INTEL_PT_BR_CONDITIONAL; break; case 0xe9: /* jmp */ case 0xeb: /* jmp */
op = INTEL_PT_OP_JMP;
branch = INTEL_PT_BR_UNCONDITIONAL; break; case 0xea: /* far jmp */
op = INTEL_PT_OP_JMP;
branch = INTEL_PT_BR_INDIRECT; break; case 0xff: /* call near absolute, call far absolute ind */
ext = (insn->modrm.bytes[0] >> 3) & 0x7; switch (ext) { case 2: /* near ind call */ case 3: /* far ind call */
op = INTEL_PT_OP_CALL;
branch = INTEL_PT_BR_INDIRECT; break; case 4: case 5:
op = INTEL_PT_OP_JMP;
branch = INTEL_PT_BR_INDIRECT; break; default: break;
} break; default: break;
}
int arch_is_uncond_branch(constunsignedchar *buf, size_t len, int x86_64)
{ struct intel_pt_insn in; if (intel_pt_get_insn(buf, len, x86_64, &in) < 0) return -1; return in.branch == INTEL_PT_BR_UNCONDITIONAL ||
in.branch == INTEL_PT_BR_INDIRECT;
}
constchar *dump_insn(struct perf_insn *x, uint64_t ip __maybe_unused,
u8 *inbuf, int inlen, int *lenp)
{ struct insn insn; int n, i, ret; int left;
ret = insn_decode(&insn, inbuf, inlen,
x->is64bit ? INSN_MODE_64 : INSN_MODE_32);
if (ret < 0 || insn.length > inlen) return""; if (lenp)
*lenp = insn.length;
left = sizeof(x->out);
n = snprintf(x->out, left, "insn: ");
left -= n; for (i = 0; i < insn.length; i++) {
n += snprintf(x->out + n, left, "%02x ", inbuf[i]);
left -= n;
} return x->out;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.