Commit 9cfc9a9b6fff9ea7a19814b4472b3cb18b7bbdcc

Authored by Paul Mundt
1 parent edfd6da040

sh: Add a simple code dumper for SUPERH32 show_regs().

This implements a simple show_code() that is in turn plugged in to
show_regs() to provide minimal code dumping at the end of the trace.

Built on top of a simple instruction disassembler derived from the
binutils opcode table.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>

Showing 4 changed files with 579 additions and 3 deletions Side-by-side Diff

arch/sh/include/asm/processor_32.h
... ... @@ -175,6 +175,7 @@
175 175  
176 176 void show_trace(struct task_struct *tsk, unsigned long *sp,
177 177 struct pt_regs *regs);
  178 +void show_code(struct pt_regs *regs);
178 179 extern unsigned long get_wchan(struct task_struct *p);
179 180  
180 181 #define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)
arch/sh/kernel/Makefile_32
... ... @@ -9,9 +9,10 @@
9 9 CFLAGS_REMOVE_ftrace.o = -pg
10 10 endif
11 11  
12   -obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process_32.o \
13   - ptrace_32.o setup.o signal_32.o sys_sh.o sys_sh32.o \
14   - syscalls_32.o time_32.o topology.o traps.o traps_32.o
  12 +obj-y := debugtraps.o disassemble.o io.o io_generic.o irq.o \
  13 + machvec.o process_32.o ptrace_32.o setup.o signal_32.o \
  14 + sys_sh.o sys_sh32.o syscalls_32.o time_32.o topology.o \
  15 + traps.o traps_32.o
15 16  
16 17 obj-y += cpu/ timers/
17 18 obj-$(CONFIG_VSYSCALL) += vsyscall/
arch/sh/kernel/disassemble.c
  1 +/*
  2 + * Disassemble SuperH instructions.
  3 + *
  4 + * Copyright (C) 1999 kaz Kojima
  5 + * Copyright (C) 2008 Paul Mundt
  6 + *
  7 + * This file is subject to the terms and conditions of the GNU General Public
  8 + * License. See the file "COPYING" in the main directory of this archive
  9 + * for more details.
  10 + */
  11 +#include <linux/kernel.h>
  12 +#include <linux/string.h>
  13 +#include <linux/uaccess.h>
  14 +
  15 +/*
  16 + * Format of an instruction in memory.
  17 + */
  18 +typedef enum {
  19 + HEX_0, HEX_1, HEX_2, HEX_3, HEX_4, HEX_5, HEX_6, HEX_7,
  20 + HEX_8, HEX_9, HEX_A, HEX_B, HEX_C, HEX_D, HEX_E, HEX_F,
  21 + REG_N, REG_M, REG_NM, REG_B,
  22 + BRANCH_12, BRANCH_8,
  23 + DISP_8, DISP_4,
  24 + IMM_4, IMM_4BY2, IMM_4BY4, PCRELIMM_8BY2, PCRELIMM_8BY4,
  25 + IMM_8, IMM_8BY2, IMM_8BY4,
  26 +} sh_nibble_type;
  27 +
  28 +typedef enum {
  29 + A_END, A_BDISP12, A_BDISP8,
  30 + A_DEC_M, A_DEC_N,
  31 + A_DISP_GBR, A_DISP_PC, A_DISP_REG_M, A_DISP_REG_N,
  32 + A_GBR,
  33 + A_IMM,
  34 + A_INC_M, A_INC_N,
  35 + A_IND_M, A_IND_N, A_IND_R0_REG_M, A_IND_R0_REG_N,
  36 + A_MACH, A_MACL,
  37 + A_PR, A_R0, A_R0_GBR, A_REG_M, A_REG_N, A_REG_B,
  38 + A_SR, A_VBR, A_SSR, A_SPC, A_SGR, A_DBR,
  39 + F_REG_N, F_REG_M, D_REG_N, D_REG_M,
  40 + X_REG_N, /* Only used for argument parsing */
  41 + X_REG_M, /* Only used for argument parsing */
  42 + DX_REG_N, DX_REG_M, V_REG_N, V_REG_M,
  43 + FD_REG_N,
  44 + XMTRX_M4,
  45 + F_FR0,
  46 + FPUL_N, FPUL_M, FPSCR_N, FPSCR_M,
  47 +} sh_arg_type;
  48 +
  49 +static struct sh_opcode_info {
  50 + char *name;
  51 + sh_arg_type arg[7];
  52 + sh_nibble_type nibbles[4];
  53 +} sh_table[] = {
  54 + {"add",{A_IMM,A_REG_N},{HEX_7,REG_N,IMM_8}},
  55 + {"add",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_C}},
  56 + {"addc",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_E}},
  57 + {"addv",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_F}},
  58 + {"and",{A_IMM,A_R0},{HEX_C,HEX_9,IMM_8}},
  59 + {"and",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_9}},
  60 + {"and.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_D,IMM_8}},
  61 + {"bra",{A_BDISP12},{HEX_A,BRANCH_12}},
  62 + {"bsr",{A_BDISP12},{HEX_B,BRANCH_12}},
  63 + {"bt",{A_BDISP8},{HEX_8,HEX_9,BRANCH_8}},
  64 + {"bf",{A_BDISP8},{HEX_8,HEX_B,BRANCH_8}},
  65 + {"bt.s",{A_BDISP8},{HEX_8,HEX_D,BRANCH_8}},
  66 + {"bt/s",{A_BDISP8},{HEX_8,HEX_D,BRANCH_8}},
  67 + {"bf.s",{A_BDISP8},{HEX_8,HEX_F,BRANCH_8}},
  68 + {"bf/s",{A_BDISP8},{HEX_8,HEX_F,BRANCH_8}},
  69 + {"clrmac",{0},{HEX_0,HEX_0,HEX_2,HEX_8}},
  70 + {"clrs",{0},{HEX_0,HEX_0,HEX_4,HEX_8}},
  71 + {"clrt",{0},{HEX_0,HEX_0,HEX_0,HEX_8}},
  72 + {"cmp/eq",{A_IMM,A_R0},{HEX_8,HEX_8,IMM_8}},
  73 + {"cmp/eq",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_0}},
  74 + {"cmp/ge",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_3}},
  75 + {"cmp/gt",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_7}},
  76 + {"cmp/hi",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_6}},
  77 + {"cmp/hs",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_2}},
  78 + {"cmp/pl",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_5}},
  79 + {"cmp/pz",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_1}},
  80 + {"cmp/str",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_C}},
  81 + {"div0s",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_7}},
  82 + {"div0u",{0},{HEX_0,HEX_0,HEX_1,HEX_9}},
  83 + {"div1",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_4}},
  84 + {"exts.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_E}},
  85 + {"exts.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_F}},
  86 + {"extu.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_C}},
  87 + {"extu.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_D}},
  88 + {"jmp",{A_IND_N},{HEX_4,REG_N,HEX_2,HEX_B}},
  89 + {"jsr",{A_IND_N},{HEX_4,REG_N,HEX_0,HEX_B}},
  90 + {"ldc",{A_REG_N,A_SR},{HEX_4,REG_N,HEX_0,HEX_E}},
  91 + {"ldc",{A_REG_N,A_GBR},{HEX_4,REG_N,HEX_1,HEX_E}},
  92 + {"ldc",{A_REG_N,A_VBR},{HEX_4,REG_N,HEX_2,HEX_E}},
  93 + {"ldc",{A_REG_N,A_SSR},{HEX_4,REG_N,HEX_3,HEX_E}},
  94 + {"ldc",{A_REG_N,A_SPC},{HEX_4,REG_N,HEX_4,HEX_E}},
  95 + {"ldc",{A_REG_N,A_DBR},{HEX_4,REG_N,HEX_7,HEX_E}},
  96 + {"ldc",{A_REG_N,A_REG_B},{HEX_4,REG_N,REG_B,HEX_E}},
  97 + {"ldc.l",{A_INC_N,A_SR},{HEX_4,REG_N,HEX_0,HEX_7}},
  98 + {"ldc.l",{A_INC_N,A_GBR},{HEX_4,REG_N,HEX_1,HEX_7}},
  99 + {"ldc.l",{A_INC_N,A_VBR},{HEX_4,REG_N,HEX_2,HEX_7}},
  100 + {"ldc.l",{A_INC_N,A_SSR},{HEX_4,REG_N,HEX_3,HEX_7}},
  101 + {"ldc.l",{A_INC_N,A_SPC},{HEX_4,REG_N,HEX_4,HEX_7}},
  102 + {"ldc.l",{A_INC_N,A_DBR},{HEX_4,REG_N,HEX_7,HEX_7}},
  103 + {"ldc.l",{A_INC_N,A_REG_B},{HEX_4,REG_N,REG_B,HEX_7}},
  104 + {"lds",{A_REG_N,A_MACH},{HEX_4,REG_N,HEX_0,HEX_A}},
  105 + {"lds",{A_REG_N,A_MACL},{HEX_4,REG_N,HEX_1,HEX_A}},
  106 + {"lds",{A_REG_N,A_PR},{HEX_4,REG_N,HEX_2,HEX_A}},
  107 + {"lds",{A_REG_M,FPUL_N},{HEX_4,REG_M,HEX_5,HEX_A}},
  108 + {"lds",{A_REG_M,FPSCR_N},{HEX_4,REG_M,HEX_6,HEX_A}},
  109 + {"lds.l",{A_INC_N,A_MACH},{HEX_4,REG_N,HEX_0,HEX_6}},
  110 + {"lds.l",{A_INC_N,A_MACL},{HEX_4,REG_N,HEX_1,HEX_6}},
  111 + {"lds.l",{A_INC_N,A_PR},{HEX_4,REG_N,HEX_2,HEX_6}},
  112 + {"lds.l",{A_INC_M,FPUL_N},{HEX_4,REG_M,HEX_5,HEX_6}},
  113 + {"lds.l",{A_INC_M,FPSCR_N},{HEX_4,REG_M,HEX_6,HEX_6}},
  114 + {"ldtlb",{0},{HEX_0,HEX_0,HEX_3,HEX_8}},
  115 + {"mac.w",{A_INC_M,A_INC_N},{HEX_4,REG_N,REG_M,HEX_F}},
  116 + {"mov",{A_IMM,A_REG_N},{HEX_E,REG_N,IMM_8}},
  117 + {"mov",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_3}},
  118 + {"mov.b",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_4}},
  119 + {"mov.b",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_4}},
  120 + {"mov.b",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_0}},
  121 + {"mov.b",{A_DISP_REG_M,A_R0},{HEX_8,HEX_4,REG_M,IMM_4}},
  122 + {"mov.b",{A_DISP_GBR,A_R0},{HEX_C,HEX_4,IMM_8}},
  123 + {"mov.b",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_C}},
  124 + {"mov.b",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_4}},
  125 + {"mov.b",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_0}},
  126 + {"mov.b",{A_R0,A_DISP_REG_M},{HEX_8,HEX_0,REG_M,IMM_4}},
  127 + {"mov.b",{A_R0,A_DISP_GBR},{HEX_C,HEX_0,IMM_8}},
  128 + {"mov.l",{ A_REG_M,A_DISP_REG_N},{HEX_1,REG_N,REG_M,IMM_4BY4}},
  129 + {"mov.l",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_6}},
  130 + {"mov.l",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_6}},
  131 + {"mov.l",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_2}},
  132 + {"mov.l",{A_DISP_REG_M,A_REG_N},{HEX_5,REG_N,REG_M,IMM_4BY4}},
  133 + {"mov.l",{A_DISP_GBR,A_R0},{HEX_C,HEX_6,IMM_8BY4}},
  134 + {"mov.l",{A_DISP_PC,A_REG_N},{HEX_D,REG_N,PCRELIMM_8BY4}},
  135 + {"mov.l",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_E}},
  136 + {"mov.l",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_6}},
  137 + {"mov.l",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_2}},
  138 + {"mov.l",{A_R0,A_DISP_GBR},{HEX_C,HEX_2,IMM_8BY4}},
  139 + {"mov.w",{ A_REG_M,A_IND_R0_REG_N},{HEX_0,REG_N,REG_M,HEX_5}},
  140 + {"mov.w",{ A_REG_M,A_DEC_N},{HEX_2,REG_N,REG_M,HEX_5}},
  141 + {"mov.w",{ A_REG_M,A_IND_N},{HEX_2,REG_N,REG_M,HEX_1}},
  142 + {"mov.w",{A_DISP_REG_M,A_R0},{HEX_8,HEX_5,REG_M,IMM_4BY2}},
  143 + {"mov.w",{A_DISP_GBR,A_R0},{HEX_C,HEX_5,IMM_8BY2}},
  144 + {"mov.w",{A_DISP_PC,A_REG_N},{HEX_9,REG_N,PCRELIMM_8BY2}},
  145 + {"mov.w",{A_IND_R0_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_D}},
  146 + {"mov.w",{A_INC_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_5}},
  147 + {"mov.w",{A_IND_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_1}},
  148 + {"mov.w",{A_R0,A_DISP_REG_M},{HEX_8,HEX_1,REG_M,IMM_4BY2}},
  149 + {"mov.w",{A_R0,A_DISP_GBR},{HEX_C,HEX_1,IMM_8BY2}},
  150 + {"mova",{A_DISP_PC,A_R0},{HEX_C,HEX_7,PCRELIMM_8BY4}},
  151 + {"movca.l",{A_R0,A_IND_N},{HEX_0,REG_N,HEX_C,HEX_3}},
  152 + {"movt",{A_REG_N},{HEX_0,REG_N,HEX_2,HEX_9}},
  153 + {"muls",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_F}},
  154 + {"mul.l",{ A_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_7}},
  155 + {"mulu",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_E}},
  156 + {"neg",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_B}},
  157 + {"negc",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_A}},
  158 + {"nop",{0},{HEX_0,HEX_0,HEX_0,HEX_9}},
  159 + {"not",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_7}},
  160 + {"ocbi",{A_IND_N},{HEX_0,REG_N,HEX_9,HEX_3}},
  161 + {"ocbp",{A_IND_N},{HEX_0,REG_N,HEX_A,HEX_3}},
  162 + {"ocbwb",{A_IND_N},{HEX_0,REG_N,HEX_B,HEX_3}},
  163 + {"or",{A_IMM,A_R0},{HEX_C,HEX_B,IMM_8}},
  164 + {"or",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_B}},
  165 + {"or.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_F,IMM_8}},
  166 + {"pref",{A_IND_N},{HEX_0,REG_N,HEX_8,HEX_3}},
  167 + {"rotcl",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_4}},
  168 + {"rotcr",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_5}},
  169 + {"rotl",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_4}},
  170 + {"rotr",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_5}},
  171 + {"rte",{0},{HEX_0,HEX_0,HEX_2,HEX_B}},
  172 + {"rts",{0},{HEX_0,HEX_0,HEX_0,HEX_B}},
  173 + {"sets",{0},{HEX_0,HEX_0,HEX_5,HEX_8}},
  174 + {"sett",{0},{HEX_0,HEX_0,HEX_1,HEX_8}},
  175 + {"shad",{ A_REG_M,A_REG_N},{HEX_4,REG_N,REG_M,HEX_C}},
  176 + {"shld",{ A_REG_M,A_REG_N},{HEX_4,REG_N,REG_M,HEX_D}},
  177 + {"shal",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_0}},
  178 + {"shar",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_1}},
  179 + {"shll",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_0}},
  180 + {"shll16",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_8}},
  181 + {"shll2",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_8}},
  182 + {"shll8",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_8}},
  183 + {"shlr",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_1}},
  184 + {"shlr16",{A_REG_N},{HEX_4,REG_N,HEX_2,HEX_9}},
  185 + {"shlr2",{A_REG_N},{HEX_4,REG_N,HEX_0,HEX_9}},
  186 + {"shlr8",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_9}},
  187 + {"sleep",{0},{HEX_0,HEX_0,HEX_1,HEX_B}},
  188 + {"stc",{A_SR,A_REG_N},{HEX_0,REG_N,HEX_0,HEX_2}},
  189 + {"stc",{A_GBR,A_REG_N},{HEX_0,REG_N,HEX_1,HEX_2}},
  190 + {"stc",{A_VBR,A_REG_N},{HEX_0,REG_N,HEX_2,HEX_2}},
  191 + {"stc",{A_SSR,A_REG_N},{HEX_0,REG_N,HEX_3,HEX_2}},
  192 + {"stc",{A_SPC,A_REG_N},{HEX_0,REG_N,HEX_4,HEX_2}},
  193 + {"stc",{A_SGR,A_REG_N},{HEX_0,REG_N,HEX_6,HEX_2}},
  194 + {"stc",{A_DBR,A_REG_N},{HEX_0,REG_N,HEX_7,HEX_2}},
  195 + {"stc",{A_REG_B,A_REG_N},{HEX_0,REG_N,REG_B,HEX_2}},
  196 + {"stc.l",{A_SR,A_DEC_N},{HEX_4,REG_N,HEX_0,HEX_3}},
  197 + {"stc.l",{A_GBR,A_DEC_N},{HEX_4,REG_N,HEX_1,HEX_3}},
  198 + {"stc.l",{A_VBR,A_DEC_N},{HEX_4,REG_N,HEX_2,HEX_3}},
  199 + {"stc.l",{A_SSR,A_DEC_N},{HEX_4,REG_N,HEX_3,HEX_3}},
  200 + {"stc.l",{A_SPC,A_DEC_N},{HEX_4,REG_N,HEX_4,HEX_3}},
  201 + {"stc.l",{A_SGR,A_DEC_N},{HEX_4,REG_N,HEX_6,HEX_3}},
  202 + {"stc.l",{A_DBR,A_DEC_N},{HEX_4,REG_N,HEX_7,HEX_3}},
  203 + {"stc.l",{A_REG_B,A_DEC_N},{HEX_4,REG_N,REG_B,HEX_3}},
  204 + {"sts",{A_MACH,A_REG_N},{HEX_0,REG_N,HEX_0,HEX_A}},
  205 + {"sts",{A_MACL,A_REG_N},{HEX_0,REG_N,HEX_1,HEX_A}},
  206 + {"sts",{A_PR,A_REG_N},{HEX_0,REG_N,HEX_2,HEX_A}},
  207 + {"sts",{FPUL_M,A_REG_N},{HEX_0,REG_N,HEX_5,HEX_A}},
  208 + {"sts",{FPSCR_M,A_REG_N},{HEX_0,REG_N,HEX_6,HEX_A}},
  209 + {"sts.l",{A_MACH,A_DEC_N},{HEX_4,REG_N,HEX_0,HEX_2}},
  210 + {"sts.l",{A_MACL,A_DEC_N},{HEX_4,REG_N,HEX_1,HEX_2}},
  211 + {"sts.l",{A_PR,A_DEC_N},{HEX_4,REG_N,HEX_2,HEX_2}},
  212 + {"sts.l",{FPUL_M,A_DEC_N},{HEX_4,REG_N,HEX_5,HEX_2}},
  213 + {"sts.l",{FPSCR_M,A_DEC_N},{HEX_4,REG_N,HEX_6,HEX_2}},
  214 + {"sub",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_8}},
  215 + {"subc",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_A}},
  216 + {"subv",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_B}},
  217 + {"swap.b",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_8}},
  218 + {"swap.w",{ A_REG_M,A_REG_N},{HEX_6,REG_N,REG_M,HEX_9}},
  219 + {"tas.b",{A_IND_N},{HEX_4,REG_N,HEX_1,HEX_B}},
  220 + {"trapa",{A_IMM},{HEX_C,HEX_3,IMM_8}},
  221 + {"tst",{A_IMM,A_R0},{HEX_C,HEX_8,IMM_8}},
  222 + {"tst",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_8}},
  223 + {"tst.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_C,IMM_8}},
  224 + {"xor",{A_IMM,A_R0},{HEX_C,HEX_A,IMM_8}},
  225 + {"xor",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_A}},
  226 + {"xor.b",{A_IMM,A_R0_GBR},{HEX_C,HEX_E,IMM_8}},
  227 + {"xtrct",{ A_REG_M,A_REG_N},{HEX_2,REG_N,REG_M,HEX_D}},
  228 + {"mul.l",{ A_REG_M,A_REG_N},{HEX_0,REG_N,REG_M,HEX_7}},
  229 + {"dt",{A_REG_N},{HEX_4,REG_N,HEX_1,HEX_0}},
  230 + {"dmuls.l",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_D}},
  231 + {"dmulu.l",{ A_REG_M,A_REG_N},{HEX_3,REG_N,REG_M,HEX_5}},
  232 + {"mac.l",{A_INC_M,A_INC_N},{HEX_0,REG_N,REG_M,HEX_F}},
  233 + {"braf",{A_REG_N},{HEX_0,REG_N,HEX_2,HEX_3}},
  234 + {"bsrf",{A_REG_N},{HEX_0,REG_N,HEX_0,HEX_3}},
  235 + {"fabs",{FD_REG_N},{HEX_F,REG_N,HEX_5,HEX_D}},
  236 + {"fadd",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_0}},
  237 + {"fadd",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_0}},
  238 + {"fcmp/eq",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_4}},
  239 + {"fcmp/eq",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_4}},
  240 + {"fcmp/gt",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_5}},
  241 + {"fcmp/gt",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_5}},
  242 + {"fcnvds",{D_REG_N,FPUL_M},{HEX_F,REG_N,HEX_B,HEX_D}},
  243 + {"fcnvsd",{FPUL_M,D_REG_N},{HEX_F,REG_N,HEX_A,HEX_D}},
  244 + {"fdiv",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_3}},
  245 + {"fdiv",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_3}},
  246 + {"fipr",{V_REG_M,V_REG_N},{HEX_F,REG_NM,HEX_E,HEX_D}},
  247 + {"fldi0",{F_REG_N},{HEX_F,REG_N,HEX_8,HEX_D}},
  248 + {"fldi1",{F_REG_N},{HEX_F,REG_N,HEX_9,HEX_D}},
  249 + {"flds",{F_REG_N,FPUL_M},{HEX_F,REG_N,HEX_1,HEX_D}},
  250 + {"float",{FPUL_M,FD_REG_N},{HEX_F,REG_N,HEX_2,HEX_D}},
  251 + {"fmac",{F_FR0,F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_E}},
  252 + {"fmov",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_C}},
  253 + {"fmov",{DX_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_C}},
  254 + {"fmov",{A_IND_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
  255 + {"fmov",{A_IND_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
  256 + {"fmov",{F_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
  257 + {"fmov",{DX_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
  258 + {"fmov",{A_INC_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
  259 + {"fmov",{A_INC_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
  260 + {"fmov",{F_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
  261 + {"fmov",{DX_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
  262 + {"fmov",{A_IND_R0_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
  263 + {"fmov",{A_IND_R0_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
  264 + {"fmov",{F_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
  265 + {"fmov",{DX_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
  266 + {"fmov.d",{A_IND_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
  267 + {"fmov.d",{DX_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
  268 + {"fmov.d",{A_INC_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
  269 + {"fmov.d",{DX_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
  270 + {"fmov.d",{A_IND_R0_REG_M,DX_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
  271 + {"fmov.d",{DX_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
  272 + {"fmov.s",{A_IND_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_8}},
  273 + {"fmov.s",{F_REG_M,A_IND_N},{HEX_F,REG_N,REG_M,HEX_A}},
  274 + {"fmov.s",{A_INC_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_9}},
  275 + {"fmov.s",{F_REG_M,A_DEC_N},{HEX_F,REG_N,REG_M,HEX_B}},
  276 + {"fmov.s",{A_IND_R0_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_6}},
  277 + {"fmov.s",{F_REG_M,A_IND_R0_REG_N},{HEX_F,REG_N,REG_M,HEX_7}},
  278 + {"fmul",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_2}},
  279 + {"fmul",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_2}},
  280 + {"fneg",{FD_REG_N},{HEX_F,REG_N,HEX_4,HEX_D}},
  281 + {"frchg",{0},{HEX_F,HEX_B,HEX_F,HEX_D}},
  282 + {"fschg",{0},{HEX_F,HEX_3,HEX_F,HEX_D}},
  283 + {"fsqrt",{FD_REG_N},{HEX_F,REG_N,HEX_6,HEX_D}},
  284 + {"fsts",{FPUL_M,F_REG_N},{HEX_F,REG_N,HEX_0,HEX_D}},
  285 + {"fsub",{F_REG_M,F_REG_N},{HEX_F,REG_N,REG_M,HEX_1}},
  286 + {"fsub",{D_REG_M,D_REG_N},{HEX_F,REG_N,REG_M,HEX_1}},
  287 + {"ftrc",{FD_REG_N,FPUL_M},{HEX_F,REG_N,HEX_3,HEX_D}},
  288 + {"ftrv",{XMTRX_M4,V_REG_N},{HEX_F,REG_NM,HEX_F,HEX_D}},
  289 + { 0 },
  290 +};
  291 +
  292 +static void print_sh_insn(u32 memaddr, u16 insn)
  293 +{
  294 + int relmask = ~0;
  295 + int nibs[4] = { (insn >> 12) & 0xf, (insn >> 8) & 0xf, (insn >> 4) & 0xf, insn & 0xf};
  296 + int lastsp;
  297 + struct sh_opcode_info *op = sh_table;
  298 +
  299 + for (; op->name; op++) {
  300 + int n;
  301 + int imm = 0;
  302 + int rn = 0;
  303 + int rm = 0;
  304 + int rb = 0;
  305 + int disp_pc;
  306 + int disp_pc_addr = 0;
  307 +
  308 + for (n = 0; n < 4; n++) {
  309 + int i = op->nibbles[n];
  310 +
  311 + if (i < 16) {
  312 + if (nibs[n] == i)
  313 + continue;
  314 + goto fail;
  315 + }
  316 + switch (i) {
  317 + case BRANCH_8:
  318 + imm = (nibs[2] << 4) | (nibs[3]);
  319 + if (imm & 0x80)
  320 + imm |= ~0xff;
  321 + imm = ((char)imm) * 2 + 4 ;
  322 + goto ok;
  323 + case BRANCH_12:
  324 + imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
  325 + if (imm & 0x800)
  326 + imm |= ~0xfff;
  327 + imm = imm * 2 + 4;
  328 + goto ok;
  329 + case IMM_4:
  330 + imm = nibs[3];
  331 + goto ok;
  332 + case IMM_4BY2:
  333 + imm = nibs[3] <<1;
  334 + goto ok;
  335 + case IMM_4BY4:
  336 + imm = nibs[3] <<2;
  337 + goto ok;
  338 + case IMM_8:
  339 + imm = (nibs[2] << 4) | nibs[3];
  340 + goto ok;
  341 + case PCRELIMM_8BY2:
  342 + imm = ((nibs[2] << 4) | nibs[3]) <<1;
  343 + relmask = ~1;
  344 + goto ok;
  345 + case PCRELIMM_8BY4:
  346 + imm = ((nibs[2] << 4) | nibs[3]) <<2;
  347 + relmask = ~3;
  348 + goto ok;
  349 + case IMM_8BY2:
  350 + imm = ((nibs[2] << 4) | nibs[3]) <<1;
  351 + goto ok;
  352 + case IMM_8BY4:
  353 + imm = ((nibs[2] << 4) | nibs[3]) <<2;
  354 + goto ok;
  355 + case DISP_8:
  356 + imm = (nibs[2] << 4) | (nibs[3]);
  357 + goto ok;
  358 + case DISP_4:
  359 + imm = nibs[3];
  360 + goto ok;
  361 + case REG_N:
  362 + rn = nibs[n];
  363 + break;
  364 + case REG_M:
  365 + rm = nibs[n];
  366 + break;
  367 + case REG_NM:
  368 + rn = (nibs[n] & 0xc) >> 2;
  369 + rm = (nibs[n] & 0x3);
  370 + break;
  371 + case REG_B:
  372 + rb = nibs[n] & 0x07;
  373 + break;
  374 + default:
  375 + return;
  376 + }
  377 + }
  378 +
  379 + ok:
  380 + printk("%-8s ", op->name);
  381 + lastsp = (op->arg[0] == A_END);
  382 + disp_pc = 0;
  383 + for (n = 0; n < 6 && op->arg[n] != A_END; n++) {
  384 + if (n && op->arg[1] != A_END)
  385 + printk(", ");
  386 + switch (op->arg[n]) {
  387 + case A_IMM:
  388 + printk("#%d", (char)(imm));
  389 + break;
  390 + case A_R0:
  391 + printk("r0");
  392 + break;
  393 + case A_REG_N:
  394 + printk("r%d", rn);
  395 + break;
  396 + case A_INC_N:
  397 + printk("@r%d+", rn);
  398 + break;
  399 + case A_DEC_N:
  400 + printk("@-r%d", rn);
  401 + break;
  402 + case A_IND_N:
  403 + printk("@r%d", rn);
  404 + break;
  405 + case A_DISP_REG_N:
  406 + printk("@(%d,r%d)", imm, rn);
  407 + break;
  408 + case A_REG_M:
  409 + printk("r%d", rm);
  410 + break;
  411 + case A_INC_M:
  412 + printk("@r%d+", rm);
  413 + break;
  414 + case A_DEC_M:
  415 + printk("@-r%d", rm);
  416 + break;
  417 + case A_IND_M:
  418 + printk("@r%d", rm);
  419 + break;
  420 + case A_DISP_REG_M:
  421 + printk("@(%d,r%d)", imm, rm);
  422 + break;
  423 + case A_REG_B:
  424 + printk("r%d_bank", rb);
  425 + break;
  426 + case A_DISP_PC:
  427 + disp_pc = 1;
  428 + disp_pc_addr = imm + 4 + (memaddr & relmask);
  429 + printk("%08x <%pS>", disp_pc_addr,
  430 + (void *)disp_pc_addr);
  431 + break;
  432 + case A_IND_R0_REG_N:
  433 + printk("@(r0,r%d)", rn);
  434 + break;
  435 + case A_IND_R0_REG_M:
  436 + printk("@(r0,r%d)", rm);
  437 + break;
  438 + case A_DISP_GBR:
  439 + printk("@(%d,gbr)",imm);
  440 + break;
  441 + case A_R0_GBR:
  442 + printk("@(r0,gbr)");
  443 + break;
  444 + case A_BDISP12:
  445 + case A_BDISP8:
  446 + printk("%08x", imm + memaddr);
  447 + break;
  448 + case A_SR:
  449 + printk("sr");
  450 + break;
  451 + case A_GBR:
  452 + printk("gbr");
  453 + break;
  454 + case A_VBR:
  455 + printk("vbr");
  456 + break;
  457 + case A_SSR:
  458 + printk("ssr");
  459 + break;
  460 + case A_SPC:
  461 + printk("spc");
  462 + break;
  463 + case A_MACH:
  464 + printk("mach");
  465 + break;
  466 + case A_MACL:
  467 + printk("macl");
  468 + break;
  469 + case A_PR:
  470 + printk("pr");
  471 + break;
  472 + case A_SGR:
  473 + printk("sgr");
  474 + break;
  475 + case A_DBR:
  476 + printk("dbr");
  477 + break;
  478 + case FD_REG_N:
  479 + if (0)
  480 + goto d_reg_n;
  481 + case F_REG_N:
  482 + printk("fr%d", rn);
  483 + break;
  484 + case F_REG_M:
  485 + printk("fr%d", rm);
  486 + break;
  487 + case DX_REG_N:
  488 + if (rn & 1) {
  489 + printk("xd%d", rn & ~1);
  490 + break;
  491 + }
  492 + d_reg_n:
  493 + case D_REG_N:
  494 + printk("dr%d", rn);
  495 + break;
  496 + case DX_REG_M:
  497 + if (rm & 1) {
  498 + printk("xd%d", rm & ~1);
  499 + break;
  500 + }
  501 + case D_REG_M:
  502 + printk("dr%d", rm);
  503 + break;
  504 + case FPSCR_M:
  505 + case FPSCR_N:
  506 + printk("fpscr");
  507 + break;
  508 + case FPUL_M:
  509 + case FPUL_N:
  510 + printk("fpul");
  511 + break;
  512 + case F_FR0:
  513 + printk("fr0");
  514 + break;
  515 + case V_REG_N:
  516 + printk("fv%d", rn*4);
  517 + break;
  518 + case V_REG_M:
  519 + printk("fv%d", rm*4);
  520 + break;
  521 + case XMTRX_M4:
  522 + printk("xmtrx");
  523 + break;
  524 + default:
  525 + return;
  526 + }
  527 + }
  528 +
  529 + if (disp_pc && strcmp(op->name, "mova") != 0) {
  530 + u32 val;
  531 +
  532 + if (relmask == ~1)
  533 + __get_user(val, (u16 *)disp_pc_addr);
  534 + else
  535 + __get_user(val, (u32 *)disp_pc_addr);
  536 +
  537 + printk(" ! %08x <%pS>", val, (void *)val);
  538 + }
  539 +
  540 + return;
  541 + fail:
  542 + ;
  543 +
  544 + }
  545 +
  546 + printk(".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
  547 +}
  548 +
  549 +void show_code(struct pt_regs *regs)
  550 +{
  551 + unsigned short *pc = (unsigned short *)regs->pc;
  552 + long i;
  553 +
  554 + if (regs->pc & 0x1)
  555 + return;
  556 +
  557 + printk("Code:\n");
  558 +
  559 + for (i = -3 ; i < 6 ; i++) {
  560 + unsigned short insn;
  561 +
  562 + if (__get_user(insn, pc + i)) {
  563 + printk(" (Bad address in pc)\n");
  564 + break;
  565 + }
  566 +
  567 + printk("%s%08lx: ", (i ? " ": "->"), (unsigned long)(pc + i));
  568 + print_sh_insn((unsigned long)(pc + i), insn);
  569 + printk("\n");
  570 + }
  571 +
  572 + printk("\n");
  573 +}
arch/sh/kernel/process_32.c
... ... @@ -148,6 +148,7 @@
148 148 regs->mach, regs->macl, regs->gbr, regs->pr);
149 149  
150 150 show_trace(NULL, (unsigned long *)regs->regs[15], regs);
  151 + show_code(regs);
151 152 }
152 153  
153 154 /*