📄 dis.c
字号:
{ "cvby", 0x06, INSTR_RXY_RRRD }, { "ag", 0x08, INSTR_RXY_RRRD }, { "sg", 0x09, INSTR_RXY_RRRD }, { "alg", 0x0a, INSTR_RXY_RRRD }, { "slg", 0x0b, INSTR_RXY_RRRD }, { "msg", 0x0c, INSTR_RXY_RRRD }, { "dsg", 0x0d, INSTR_RXY_RRRD }, { "cvbg", 0x0e, INSTR_RXY_RRRD }, { "lrvg", 0x0f, INSTR_RXY_RRRD }, { "lt", 0x12, INSTR_RXY_RRRD }, { "lray", 0x13, INSTR_RXY_RRRD }, { "lgf", 0x14, INSTR_RXY_RRRD }, { "lgh", 0x15, INSTR_RXY_RRRD }, { "llgf", 0x16, INSTR_RXY_RRRD }, { "llgt", 0x17, INSTR_RXY_RRRD }, { "agf", 0x18, INSTR_RXY_RRRD }, { "sgf", 0x19, INSTR_RXY_RRRD }, { "algf", 0x1a, INSTR_RXY_RRRD }, { "slgf", 0x1b, INSTR_RXY_RRRD }, { "msgf", 0x1c, INSTR_RXY_RRRD }, { "dsgf", 0x1d, INSTR_RXY_RRRD }, { "cg", 0x20, INSTR_RXY_RRRD }, { "clg", 0x21, INSTR_RXY_RRRD }, { "stg", 0x24, INSTR_RXY_RRRD }, { "cvdy", 0x26, INSTR_RXY_RRRD }, { "cvdg", 0x2e, INSTR_RXY_RRRD }, { "strvg", 0x2f, INSTR_RXY_RRRD }, { "cgf", 0x30, INSTR_RXY_RRRD }, { "clgf", 0x31, INSTR_RXY_RRRD }, { "strvh", 0x3f, INSTR_RXY_RRRD }, { "bctg", 0x46, INSTR_RXY_RRRD }, { "sty", 0x50, INSTR_RXY_RRRD }, { "msy", 0x51, INSTR_RXY_RRRD }, { "ny", 0x54, INSTR_RXY_RRRD }, { "cly", 0x55, INSTR_RXY_RRRD }, { "oy", 0x56, INSTR_RXY_RRRD }, { "xy", 0x57, INSTR_RXY_RRRD }, { "ly", 0x58, INSTR_RXY_RRRD }, { "cy", 0x59, INSTR_RXY_RRRD }, { "ay", 0x5a, INSTR_RXY_RRRD }, { "sy", 0x5b, INSTR_RXY_RRRD }, { "aly", 0x5e, INSTR_RXY_RRRD }, { "sly", 0x5f, INSTR_RXY_RRRD }, { "sthy", 0x70, INSTR_RXY_RRRD }, { "lay", 0x71, INSTR_RXY_RRRD }, { "stcy", 0x72, INSTR_RXY_RRRD }, { "icy", 0x73, INSTR_RXY_RRRD }, { "lb", 0x76, INSTR_RXY_RRRD }, { "lgb", 0x77, INSTR_RXY_RRRD }, { "lhy", 0x78, INSTR_RXY_RRRD }, { "chy", 0x79, INSTR_RXY_RRRD }, { "ahy", 0x7a, INSTR_RXY_RRRD }, { "shy", 0x7b, INSTR_RXY_RRRD }, { "ng", 0x80, INSTR_RXY_RRRD }, { "og", 0x81, INSTR_RXY_RRRD }, { "xg", 0x82, INSTR_RXY_RRRD }, { "mlg", 0x86, INSTR_RXY_RRRD }, { "dlg", 0x87, INSTR_RXY_RRRD }, { "alcg", 0x88, INSTR_RXY_RRRD }, { "slbg", 0x89, INSTR_RXY_RRRD }, { "stpq", 0x8e, INSTR_RXY_RRRD }, { "lpq", 0x8f, INSTR_RXY_RRRD }, { "llgc", 0x90, INSTR_RXY_RRRD }, { "llgh", 0x91, INSTR_RXY_RRRD }, { "llc", 0x94, INSTR_RXY_RRRD }, { "llh", 0x95, INSTR_RXY_RRRD },#endif { "lrv", 0x1e, INSTR_RXY_RRRD }, { "lrvh", 0x1f, INSTR_RXY_RRRD }, { "strv", 0x3e, INSTR_RXY_RRRD }, { "ml", 0x96, INSTR_RXY_RRRD }, { "dl", 0x97, INSTR_RXY_RRRD }, { "alc", 0x98, INSTR_RXY_RRRD }, { "slb", 0x99, INSTR_RXY_RRRD }, { "", 0, INSTR_INVALID }};static struct insn opcode_e5[] = {#ifdef CONFIG_64BIT { "strag", 0x02, INSTR_SSE_RDRD },#endif { "lasp", 0x00, INSTR_SSE_RDRD }, { "tprot", 0x01, INSTR_SSE_RDRD }, { "mvcsk", 0x0e, INSTR_SSE_RDRD }, { "mvcdk", 0x0f, INSTR_SSE_RDRD }, { "", 0, INSTR_INVALID }};static struct insn opcode_eb[] = {#ifdef CONFIG_64BIT { "lmg", 0x04, INSTR_RSY_RRRD }, { "srag", 0x0a, INSTR_RSY_RRRD }, { "slag", 0x0b, INSTR_RSY_RRRD }, { "srlg", 0x0c, INSTR_RSY_RRRD }, { "sllg", 0x0d, INSTR_RSY_RRRD }, { "tracg", 0x0f, INSTR_RSY_RRRD }, { "csy", 0x14, INSTR_RSY_RRRD }, { "rllg", 0x1c, INSTR_RSY_RRRD }, { "clmh", 0x20, INSTR_RSY_RURD }, { "clmy", 0x21, INSTR_RSY_RURD }, { "stmg", 0x24, INSTR_RSY_RRRD }, { "stctg", 0x25, INSTR_RSY_CCRD }, { "stmh", 0x26, INSTR_RSY_RRRD }, { "stcmh", 0x2c, INSTR_RSY_RURD }, { "stcmy", 0x2d, INSTR_RSY_RURD }, { "lctlg", 0x2f, INSTR_RSY_CCRD }, { "csg", 0x30, INSTR_RSY_RRRD }, { "cdsy", 0x31, INSTR_RSY_RRRD }, { "cdsg", 0x3e, INSTR_RSY_RRRD }, { "bxhg", 0x44, INSTR_RSY_RRRD }, { "bxleg", 0x45, INSTR_RSY_RRRD }, { "tmy", 0x51, INSTR_SIY_URD }, { "mviy", 0x52, INSTR_SIY_URD }, { "niy", 0x54, INSTR_SIY_URD }, { "cliy", 0x55, INSTR_SIY_URD }, { "oiy", 0x56, INSTR_SIY_URD }, { "xiy", 0x57, INSTR_SIY_URD }, { "icmh", 0x80, INSTR_RSE_RURD }, { "icmh", 0x80, INSTR_RSY_RURD }, { "icmy", 0x81, INSTR_RSY_RURD }, { "clclu", 0x8f, INSTR_RSY_RRRD }, { "stmy", 0x90, INSTR_RSY_RRRD }, { "lmh", 0x96, INSTR_RSY_RRRD }, { "lmy", 0x98, INSTR_RSY_RRRD }, { "lamy", 0x9a, INSTR_RSY_AARD }, { "stamy", 0x9b, INSTR_RSY_AARD },#endif { "rll", 0x1d, INSTR_RSY_RRRD }, { "mvclu", 0x8e, INSTR_RSY_RRRD }, { "tp", 0xc0, INSTR_RSL_R0RD }, { "", 0, INSTR_INVALID }};static struct insn opcode_ec[] = {#ifdef CONFIG_64BIT { "brxhg", 0x44, INSTR_RIE_RRP }, { "brxlg", 0x45, INSTR_RIE_RRP },#endif { "", 0, INSTR_INVALID }};static struct insn opcode_ed[] = {#ifdef CONFIG_64BIT { "mayl", 0x38, INSTR_RXF_FRRDF }, { "myl", 0x39, INSTR_RXF_FRRDF }, { "may", 0x3a, INSTR_RXF_FRRDF }, { "my", 0x3b, INSTR_RXF_FRRDF }, { "mayh", 0x3c, INSTR_RXF_FRRDF }, { "myh", 0x3d, INSTR_RXF_FRRDF }, { "ley", 0x64, INSTR_RXY_FRRD }, { "ldy", 0x65, INSTR_RXY_FRRD }, { "stey", 0x66, INSTR_RXY_FRRD }, { "stdy", 0x67, INSTR_RXY_FRRD },#endif { "ldeb", 0x04, INSTR_RXE_FRRD }, { "lxdb", 0x05, INSTR_RXE_FRRD }, { "lxeb", 0x06, INSTR_RXE_FRRD }, { "mxdb", 0x07, INSTR_RXE_FRRD }, { "keb", 0x08, INSTR_RXE_FRRD }, { "ceb", 0x09, INSTR_RXE_FRRD }, { "aeb", 0x0a, INSTR_RXE_FRRD }, { "seb", 0x0b, INSTR_RXE_FRRD }, { "mdeb", 0x0c, INSTR_RXE_FRRD }, { "deb", 0x0d, INSTR_RXE_FRRD }, { "maeb", 0x0e, INSTR_RXF_FRRDF }, { "mseb", 0x0f, INSTR_RXF_FRRDF }, { "tceb", 0x10, INSTR_RXE_FRRD }, { "tcdb", 0x11, INSTR_RXE_FRRD }, { "tcxb", 0x12, INSTR_RXE_FRRD }, { "sqeb", 0x14, INSTR_RXE_FRRD }, { "sqdb", 0x15, INSTR_RXE_FRRD }, { "meeb", 0x17, INSTR_RXE_FRRD }, { "kdb", 0x18, INSTR_RXE_FRRD }, { "cdb", 0x19, INSTR_RXE_FRRD }, { "adb", 0x1a, INSTR_RXE_FRRD }, { "sdb", 0x1b, INSTR_RXE_FRRD }, { "mdb", 0x1c, INSTR_RXE_FRRD }, { "ddb", 0x1d, INSTR_RXE_FRRD }, { "madb", 0x1e, INSTR_RXF_FRRDF }, { "msdb", 0x1f, INSTR_RXF_FRRDF }, { "lde", 0x24, INSTR_RXE_FRRD }, { "lxd", 0x25, INSTR_RXE_FRRD }, { "lxe", 0x26, INSTR_RXE_FRRD }, { "mae", 0x2e, INSTR_RXF_FRRDF }, { "mse", 0x2f, INSTR_RXF_FRRDF }, { "sqe", 0x34, INSTR_RXE_FRRD }, { "mee", 0x37, INSTR_RXE_FRRD }, { "mad", 0x3e, INSTR_RXF_FRRDF }, { "msd", 0x3f, INSTR_RXF_FRRDF }, { "", 0, INSTR_INVALID }};/* Extracts an operand value from an instruction. */static unsigned int extract_operand(unsigned char *code, const struct operand *operand){ unsigned int val; int bits; /* Extract fragments of the operand byte for byte. */ code += operand->shift / 8; bits = (operand->shift & 7) + operand->bits; val = 0; do { val <<= 8; val |= (unsigned int) *code++; bits -= 8; } while (bits > 0); val >>= -bits; val &= ((1U << (operand->bits - 1)) << 1) - 1; /* Check for special long displacement case. */ if (operand->bits == 20 && operand->shift == 20) val = (val & 0xff) << 12 | (val & 0xfff00) >> 8; /* Sign extend value if the operand is signed or pc relative. */ if ((operand->flags & (OPERAND_SIGNED | OPERAND_PCREL)) && (val & (1U << (operand->bits - 1)))) val |= (-1U << (operand->bits - 1)) << 1; /* Double value if the operand is pc relative. */ if (operand->flags & OPERAND_PCREL) val <<= 1; /* Length x in an instructions has real length x + 1. */ if (operand->flags & OPERAND_LENGTH) val++; return val;}static inline int insn_length(unsigned char code){ return ((((int) code + 64) >> 7) + 1) << 1;}static struct insn *find_insn(unsigned char *code){ unsigned char opfrag = code[1]; unsigned char opmask; struct insn *table; switch (code[0]) { case 0x01: table = opcode_01; break; case 0xa5: table = opcode_a5; break; case 0xa7: table = opcode_a7; break; case 0xb2: table = opcode_b2; break; case 0xb3: table = opcode_b3; break; case 0xb9: table = opcode_b9; break; case 0xc0: table = opcode_c0; break; case 0xc2: table = opcode_c2; break; case 0xc8: table = opcode_c8; break; case 0xe3: table = opcode_e3; opfrag = code[5]; break; case 0xe5: table = opcode_e5; break; case 0xeb: table = opcode_eb; opfrag = code[5]; break; case 0xec: table = opcode_ec; opfrag = code[5]; break; case 0xed: table = opcode_ed; opfrag = code[5]; break; default: table = opcode; opfrag = code[0]; break; } while (table->format != INSTR_INVALID) { opmask = formats[table->format][0]; if (table->opfrag == (opfrag & opmask)) return table; table++; } return NULL;}static int print_insn(char *buffer, unsigned char *code, unsigned long addr){ struct insn *insn; const unsigned char *ops; const struct operand *operand; unsigned int value; char separator; char *ptr; int i; ptr = buffer; insn = find_insn(code); if (insn) { ptr += sprintf(ptr, "%.5s\t", insn->name); /* Extract the operands. */ separator = 0; for (ops = formats[insn->format] + 1, i = 0; *ops != 0 && i < 6; ops++, i++) { operand = operands + *ops; value = extract_operand(code, operand); if ((operand->flags & OPERAND_INDEX) && value == 0) continue; if ((operand->flags & OPERAND_BASE) && value == 0 && separator == '(') { separator = ','; continue; } if (separator) ptr += sprintf(ptr, "%c", separator); if (operand->flags & OPERAND_GPR) ptr += sprintf(ptr, "%%r%i", value); else if (operand->flags & OPERAND_FPR) ptr += sprintf(ptr, "%%f%i", value); else if (operand->flags & OPERAND_AR) ptr += sprintf(ptr, "%%a%i", value); else if (operand->flags & OPERAND_CR) ptr += sprintf(ptr, "%%c%i", value); else if (operand->flags & OPERAND_PCREL) ptr += sprintf(ptr, "%lx", (signed int) value + addr); else if (operand->flags & OPERAND_SIGNED) ptr += sprintf(ptr, "%i", value); else ptr += sprintf(ptr, "%u", value); if (operand->flags & OPERAND_DISP) separator = '('; else if (operand->flags & OPERAND_BASE) { ptr += sprintf(ptr, ")"); separator = ','; } else separator = ','; } } else ptr += sprintf(ptr, "unknown"); return (int) (ptr - buffer);}void show_code(struct pt_regs *regs){ char *mode = (regs->psw.mask & PSW_MASK_PSTATE) ? "User" : "Krnl"; unsigned char code[64]; char buffer[64], *ptr; mm_segment_t old_fs; unsigned long addr; int start, end, opsize, hops, i; /* Get a snapshot of the 64 bytes surrounding the fault address. */ old_fs = get_fs(); set_fs((regs->psw.mask & PSW_MASK_PSTATE) ? USER_DS : KERNEL_DS); for (start = 32; start && regs->psw.addr >= 34 - start; start -= 2) { addr = regs->psw.addr - 34 + start; if (__copy_from_user(code + start - 2, (char __user *) addr, 2)) break; } for (end = 32; end < 64; end += 2) { addr = regs->psw.addr + end - 32; if (__copy_from_user(code + end, (char __user *) addr, 2)) break; } set_fs(old_fs); /* Code snapshot useable ? */ if ((regs->psw.addr & 1) || start >= end) { printk("%s Code: Bad PSW.\n", mode); return; } /* Find a starting point for the disassembly. */ while (start < 32) { for (i = 0, hops = 0; start + i < 32 && hops < 3; hops++) { if (!find_insn(code + start + i)) break; i += insn_length(code[start + i]); } if (start + i == 32) /* Looks good, sequence ends at PSW. */ break; start += 2; } /* Decode the instructions. */ ptr = buffer; ptr += sprintf(ptr, "%s Code:", mode); hops = 0; while (start < end && hops < 8) { *ptr++ = (start == 32) ? '>' : ' '; addr = regs->psw.addr + start - 32; ptr += sprintf(ptr, ONELONG, addr); opsize = insn_length(code[start]); if (start + opsize >= end) break; for (i = 0; i < opsize; i++) ptr += sprintf(ptr, "%02x", code[start + i]); *ptr++ = '\t'; if (i < 6) *ptr++ = '\t'; ptr += print_insn(ptr, code + start, addr); start += opsize; printk(buffer); ptr = buffer; ptr += sprintf(ptr, "\n "); hops++; } printk("\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -