8 #include <linux/sched.h>
9 #include <linux/kernel.h>
10 #include <linux/string.h>
11 #include <linux/errno.h>
12 #include <linux/ptrace.h>
19 #include <linux/module.h>
21 #include <linux/reboot.h>
25 #include <asm/uaccess.h>
31 #include <asm/debug.h>
35 #define ONELONG "%08lx: "
37 #define ONELONG "%016lx: "
40 #define OPERAND_GPR 0x1
41 #define OPERAND_FPR 0x2
42 #define OPERAND_AR 0x4
43 #define OPERAND_CR 0x8
44 #define OPERAND_DISP 0x10
45 #define OPERAND_BASE 0x20
46 #define OPERAND_INDEX 0x40
47 #define OPERAND_PCREL 0x80
48 #define OPERAND_SIGNED 0x100
49 #define OPERAND_LENGTH 0x200
158 static const struct operand operands[] =
190 [
U4_8] = { 4, 8, 0 },
191 [
U4_12] = { 4, 12, 0 },
192 [
U4_16] = { 4, 16, 0 },
193 [
U4_20] = { 4, 20, 0 },
194 [
U4_32] = { 4, 32, 0 },
195 [
U8_8] = { 8, 8, 0 },
196 [
U8_16] = { 8, 16, 0 },
197 [
U8_24] = { 8, 24, 0 },
198 [
U8_32] = { 8, 32, 0 },
207 [
M_16] = { 4, 16, 0 },
211 static const unsigned char formats[][7] = {
212 [
INSTR_E] = { 0xff, 0,0,0,0,0,0 },
325 static char *long_insn_name[] = {
535 static struct insn opcode_01[] = {
551 static struct insn opcode_a5[] = {
573 static struct insn opcode_a7[] = {
595 static struct insn opcode_aa[] = {
606 static struct insn opcode_b2[] = {
710 static struct insn opcode_b3[] = {
875 static struct insn opcode_b9[] = {
994 static struct insn opcode_c0[] = {
1014 static struct insn opcode_c2[] = {
1032 static struct insn opcode_c4[] = {
1049 static struct insn opcode_c6[] = {
1067 static struct insn opcode_c8[] = {
1078 static struct insn opcode_cc[] = {
1090 static struct insn opcode_e3[] = {
1189 static struct insn opcode_e5[] = {
1211 static struct insn opcode_eb[] = {
1282 static struct insn opcode_ec[] = {
1320 static struct insn opcode_ed[] = {
1383 static unsigned int extract_operand(
unsigned char *
code,
1390 code += operand->
shift / 8;
1391 bits = (operand->
shift & 7) + operand->
bits;
1395 val |= (
unsigned int) *code++;
1403 val = (
val & 0xff) << 12 | (
val & 0xfff00) >> 8;
1420 static inline int insn_length(
unsigned char code)
1422 return ((((
int) code + 64) >> 7) + 1) << 1;
1425 static struct insn *find_insn(
unsigned char *code)
1427 unsigned char opfrag = code[1];
1428 unsigned char opmask;
1496 opmask = formats[table->
format][0];
1497 if (table->
opfrag == (opfrag & opmask))
1519 insn = find_insn(instruction);
1522 if (insn->
name[0] ==
'\0')
1524 long_insn_name[(
int) insn->
name[1]]);
1531 static int print_insn(
char *
buffer,
unsigned char *code,
unsigned long addr)
1534 const unsigned char *
ops;
1542 insn = find_insn(code);
1544 if (insn->
name[0] ==
'\0')
1546 long_insn_name[(
int) insn->
name[1]]);
1551 for (ops = formats[insn->
format] + 1, i = 0;
1552 *ops != 0 && i < 6; ops++, i++) {
1553 operand = operands + *ops;
1554 value = extract_operand(code, operand);
1558 value == 0 && separator ==
'(') {
1563 ptr +=
sprintf(ptr,
"%c", separator);
1565 ptr +=
sprintf(ptr,
"%%r%i", value);
1567 ptr +=
sprintf(ptr,
"%%f%i", value);
1569 ptr +=
sprintf(ptr,
"%%a%i", value);
1571 ptr +=
sprintf(ptr,
"%%c%i", value);
1573 ptr +=
sprintf(ptr,
"%lx", (
signed int) value
1576 ptr +=
sprintf(ptr,
"%i", value);
1578 ptr +=
sprintf(ptr,
"%u", value);
1588 ptr +=
sprintf(ptr,
"unknown");
1589 return (
int) (ptr -
buffer);
1595 unsigned char code[64];
1596 char buffer[64], *
ptr;
1604 for (start = 32; start && regs->
psw.addr >= 34 -
start; start -= 2) {
1605 addr = regs->
psw.addr - 34 +
start;
1607 (
char __user *) addr, 2))
1610 for (end = 32; end < 64; end += 2) {
1611 addr = regs->
psw.addr + end - 32;
1613 (
char __user *) addr, 2))
1618 if ((regs->
psw.addr & 1) || start >= end) {
1619 printk(
"%s Code: Bad PSW.\n", mode);
1623 while (start < 32) {
1624 for (i = 0, hops = 0; start + i < 32 && hops < 3; hops++) {
1625 if (!find_insn(code + start + i))
1627 i += insn_length(code[start + i]);
1629 if (start + i == 32)
1636 ptr +=
sprintf(ptr,
"%s Code:", mode);
1638 while (start < end && hops < 8) {
1639 opsize = insn_length(code[start]);
1640 if (start + opsize == 32)
1642 else if (start == 32)
1646 addr = regs->
psw.addr + start - 32;
1648 if (start + opsize >= end)
1650 for (i = 0; i < opsize; i++)
1651 ptr +=
sprintf(ptr,
"%02x", code[start + i]);
1655 ptr += print_insn(ptr, code + start, addr);
1667 char buffer[64], *
ptr;
1672 opsize = insn_length(*code);
1673 ptr +=
sprintf(ptr,
"%p: ", code);
1674 for (i = 0; i < opsize; i++)
1675 ptr +=
sprintf(ptr,
"%02x", code[i]);
1679 ptr += print_insn(ptr, code, (
unsigned long) code);