00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdio.h>
00024 #include "sysdep.h"
00025 #include "opcode/pj.h"
00026 #include "dis-asm.h"
00027
00028 extern const pj_opc_info_t pj_opc_info[512];
00029
00030 static int get_int PARAMS ((bfd_vma, int *, struct disassemble_info *));
00031
00032
00033 static int
00034 get_int (memaddr, iptr, info)
00035 bfd_vma memaddr;
00036 int *iptr;
00037 struct disassemble_info *info;
00038 {
00039 unsigned char ival[4];
00040
00041 int status = info->read_memory_func (memaddr, ival, 4, info);
00042
00043 *iptr = (ival[0] << 24)
00044 | (ival[1] << 16)
00045 | (ival[2] << 8)
00046 | (ival[3] << 0);
00047
00048 return status;
00049 }
00050
00051 int
00052 print_insn_pj (addr, info)
00053 bfd_vma addr;
00054 struct disassemble_info *info;
00055 {
00056 fprintf_ftype fprintf_fn = info->fprintf_func;
00057 void *stream = info->stream;
00058 unsigned char opcode;
00059 int status;
00060
00061 if ((status = info->read_memory_func (addr, &opcode, 1, info)))
00062 goto fail;
00063
00064 if (opcode == 0xff)
00065 {
00066 unsigned char byte_2;
00067 if ((status = info->read_memory_func (addr + 1, &byte_2, 1, info)))
00068 goto fail;
00069 fprintf_fn (stream, "%s\t", pj_opc_info[opcode + byte_2].u.name);
00070 return 2;
00071 }
00072 else
00073 {
00074 char *sep = "\t";
00075 int insn_start = addr;
00076 const pj_opc_info_t *op = &pj_opc_info[opcode];
00077 int a;
00078 addr++;
00079 fprintf_fn (stream, "%s", op->u.name);
00080
00081
00082
00083
00084 if (strcmp (op->u.name, "tableswitch") == 0)
00085 {
00086 int lowval;
00087 int highval;
00088 int val;
00089
00090 addr = (addr + 3) & ~3;
00091 if ((status = get_int (addr, &val, info)))
00092 goto fail;
00093
00094 fprintf_fn (stream, " default: ");
00095 (*info->print_address_func) (val + insn_start, info);
00096 addr += 4;
00097
00098 if ((status = get_int (addr, &lowval, info)))
00099 goto fail;
00100 addr += 4;
00101
00102 if ((status = get_int (addr, &highval, info)))
00103 goto fail;
00104 addr += 4;
00105
00106 while (lowval <= highval)
00107 {
00108 if ((status = get_int (addr, &val, info)))
00109 goto fail;
00110 fprintf_fn (stream, " %d:[", lowval);
00111 (*info->print_address_func) (val + insn_start, info);
00112 fprintf_fn (stream, " ]");
00113 addr += 4;
00114 lowval++;
00115 }
00116 return addr - insn_start;
00117 }
00118
00119
00120
00121
00122
00123 if (strcmp (op->u.name, "lookupswitch") == 0)
00124 {
00125 int count;
00126 int val;
00127
00128 addr = (addr + 3) & ~3;
00129 if ((status = get_int (addr, &val, info)))
00130 goto fail;
00131 addr += 4;
00132
00133 fprintf_fn (stream, " default: ");
00134 (*info->print_address_func) (val + insn_start, info);
00135
00136 if ((status = get_int (addr, &count, info)))
00137 goto fail;
00138 addr += 4;
00139
00140 while (count--)
00141 {
00142 if ((status = get_int (addr, &val, info)))
00143 goto fail;
00144 addr += 4;
00145 fprintf_fn (stream, " %d:[", val);
00146
00147 if ((status = get_int (addr, &val, info)))
00148 goto fail;
00149 addr += 4;
00150
00151 (*info->print_address_func) (val + insn_start, info);
00152 fprintf_fn (stream, " ]");
00153 }
00154 return addr - insn_start;
00155 }
00156 for (a = 0; op->arg[a]; a++)
00157 {
00158 unsigned char data[4];
00159 int val = 0;
00160 int i;
00161 int size = ASIZE (op->arg[a]);
00162
00163 if ((status = info->read_memory_func (addr, data, size, info)))
00164 goto fail;
00165
00166 val = (UNS (op->arg[0]) || ((data[0] & 0x80) == 0)) ? 0 : -1;
00167
00168 for (i = 0; i < size; i++)
00169 val = (val << 8) | (data[i] & 0xff);
00170
00171 if (PCREL (op->arg[a]))
00172 (*info->print_address_func) (val + insn_start, info);
00173 else
00174 fprintf_fn (stream, "%s%d", sep, val);
00175
00176 sep = ",";
00177 addr += size;
00178 }
00179 return op->len;
00180 }
00181
00182 fail:
00183 info->memory_error_func (status, addr, info);
00184 return -1;
00185 }