123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360 |
- /* jadecode.c: Copyright (C) Codemist Ltd., 1996. */
- #include <stdio.h>
- #include <string.h>
- #include "machine.h"
- #include "tags.h"
- #include "cslerror.h"
- #include "externs.h"
- #include "read.h"
- #include "stream.h"
- #include "arith.h"
- #include "entries.h"
- #include "javahost.h"
- #include "javaglb.h"
- static struct { char *opname; } optable[211] = {
- "\x00""nop", /* 0 */
- "\x00""aconst_null", /* 1 */
- "\x00""iconst_m1", /* 2 */
- "\x00""iconst_0", /* 3 */
- "\x00""iconst_1", /* 4 */
- "\x00""iconst_2", /* 5 */
- "\x00""iconst_3", /* 6 */
- "\x00""iconst_4", /* 7 */
- "\x00""iconst_5", /* 8 */
- "\x00""lconst_0", /* 9 */
- "\x00""lconst_1", /* 10 */
- "\x00""fconst_0", /* 11 */
- "\x00""fconst_1", /* 12 */
- "\x00""fconst_2", /* 13 */
- "\x00""dconst_0", /* 14 */
- "\x00""dconst_1", /* 15 */
- "\x01""bipush", /* 16 */
- "\x02""sipush", /* 17 */
- "\x11""ldc1", /* 18 */
- "\x12""ldc2", /* 19 */
- "\x12""ldc2w", /* 20 */
- "\x01""iload", /* 21 */
- "\x01""lload", /* 22 */
- "\x01""fload", /* 23 */
- "\x01""dload", /* 24 */
- "\x01""aload", /* 25 */
- "\x00""iload_0", /* 26 */
- "\x00""iload_1", /* 27 */
- "\x00""iload_2", /* 28 */
- "\x00""iload_3", /* 29 */
- "\x00""lload_0", /* 30 */
- "\x00""lload_1", /* 31 */
- "\x00""lload_2", /* 32 */
- "\x00""lload_3", /* 33 */
- "\x00""fload_0", /* 34 */
- "\x00""fload_1", /* 35 */
- "\x00""fload_2", /* 36 */
- "\x00""fload_3", /* 37 */
- "\x00""dload_0", /* 38 */
- "\x00""dload_1", /* 39 */
- "\x00""dload_2", /* 40 */
- "\x00""dload_3", /* 41 */
- "\x00""aload_0", /* 42 */
- "\x00""aload_1", /* 43 */
- "\x00""aload_2", /* 44 */
- "\x00""aload_3", /* 45 */
- "\x00""iaload", /* 46 */
- "\x00""laload", /* 47 */
- "\x00""faload", /* 48 */
- "\x00""daload", /* 49 */
- "\x00""aaload", /* 50 */
- "\x00""baload", /* 51 */
- "\x00""caload", /* 52 */
- "\x00""saload", /* 53 */
- "\x01""istore", /* 54 */
- "\x01""lstore", /* 55 */
- "\x01""fstore", /* 56 */
- "\x01""dstore", /* 57 */
- "\x01""astore", /* 58 */
- "\x00""istore_0", /* 59 */
- "\x00""istore_1", /* 60 */
- "\x00""istore_2", /* 61 */
- "\x00""istore_3", /* 62 */
- "\x00""lstore_0", /* 63 */
- "\x00""lstore_1", /* 64 */
- "\x00""lstore_2", /* 65 */
- "\x00""lstore_3", /* 66 */
- "\x00""fstore_0", /* 67 */
- "\x00""fstore_1", /* 68 */
- "\x00""fstore_2", /* 69 */
- "\x00""fstore_3", /* 70 */
- "\x00""dstore_0", /* 71 */
- "\x00""dstore_1", /* 72 */
- "\x00""dstore_2", /* 73 */
- "\x00""dstore_3", /* 74 */
- "\x00""astore_0", /* 75 */
- "\x00""astore_1", /* 76 */
- "\x00""astore_2", /* 77 */
- "\x00""astore_3", /* 78 */
- "\x00""iastore", /* 79 */
- "\x00""lastore", /* 80 */
- "\x00""fastore", /* 81 */
- "\x00""dastore", /* 82 */
- "\x00""aastore", /* 83 */
- "\x00""bastore", /* 84 */
- "\x00""castore", /* 85 */
- "\x00""sastore", /* 86 */
- "\x00""pop", /* 87 */
- "\x00""pop2", /* 88 */
- "\x00""dup", /* 89 */
- "\x00""dup_x1", /* 90 */
- "\x00""dup_x2", /* 91 */
- "\x00""dup2", /* 92 */
- "\x00""dup2_x1", /* 93 */
- "\x00""dup2_x2", /* 94 */
- "\x00""swap", /* 95 */
- "\x00""iadd", /* 96 */
- "\x00""ladd", /* 97 */
- "\x00""fadd", /* 98 */
- "\x00""dadd", /* 99 */
- "\x00""isub", /* 100 */
- "\x00""lsub", /* 101 */
- "\x00""fsub", /* 102 */
- "\x00""dsub", /* 103 */
- "\x00""imul", /* 104 */
- "\x00""lmul", /* 105 */
- "\x00""fmul", /* 106 */
- "\x00""dmul", /* 107 */
- "\x00""idiv", /* 108 */
- "\x00""ldiv", /* 109 */
- "\x00""fdiv", /* 110 */
- "\x00""ddiv", /* 111 */
- "\x00""irem", /* 112 */
- "\x00""lrem", /* 113 */
- "\x00""frem", /* 114 */
- "\x00""drem", /* 115 */
- "\x00""ineg", /* 116 */
- "\x00""lneg", /* 117 */
- "\x00""fneg", /* 118 */
- "\x00""dneg", /* 119 */
- "\x00""ishl", /* 120 */
- "\x00""ishr", /* 121 */
- "\x00""iushr", /* 122 */
- "\x00""lshl", /* 123 */
- "\x00""lshr", /* 124 */
- "\x00""lushr", /* 125 */
- "\x00""iand", /* 126 */
- "\x00""land", /* 127 */
- "\x00""ior", /* 128 */
- "\x00""lor", /* 129 */
- "\x00""ixor", /* 130 */
- "\x00""lxor", /* 131 */
- "\x03""iinc", /* 132 */
- "\x00""i2l", /* 133 */
- "\x00""i2f", /* 134 */
- "\x00""i2d", /* 135 */
- "\x00""l2i", /* 136 */
- "\x00""l2f", /* 137 */
- "\x00""l2d", /* 138 */
- "\x00""f2i", /* 139 */
- "\x00""f2l", /* 140 */
- "\x00""f2d", /* 141 */
- "\x00""d2i", /* 142 */
- "\x00""d2l", /* 143 */
- "\x00""d2f", /* 144 */
- "\x00""int2byte", /* 145 */
- "\x00""int2char", /* 146 */
- "\x00""int2short", /* 147 */
- "\x00""lcmp", /* 148 */
- "\x00""fcmpl", /* 149 */
- "\x00""fcmpg", /* 150 */
- "\x00""dcmpl", /* 151 */
- "\x00""dcmpg", /* 152 */
- "\x08""ifeq", /* 153 */
- "\x08""ifne", /* 154 */
- "\x08""iflt", /* 155 */
- "\x08""ifge", /* 156 */
- "\x08""ifgt", /* 157 */
- "\x08""ifle", /* 158 */
- "\x08""if_icmpeq", /* 159 */
- "\x08""if_icmpne", /* 160 */
- "\x08""if_icmplt", /* 161 */
- "\x08""if_icmpge", /* 162 */
- "\x08""if_icmpgt", /* 163 */
- "\x08""if_icmple", /* 164 */
- "\x08""if_acmpeq", /* 165 */
- "\x08""if_acmpne", /* 166 */
- "\x08""goto", /* 167 */
- "\x08""jsr", /* 168 */
- "\x01""ret", /* 169 */
- "\x06""tableswitch", /* 170 */
- "\x07""lookupswitch", /* 171 */
- "\x00""ireturn", /* 172 */
- "\x00""lreturn", /* 173 */
- "\x00""freturn", /* 174 */
- "\x00""dreturn", /* 175 */
- "\x00""areturn", /* 176 */
- "\x00""return", /* 177 */
- "\x12""getstatic", /* 178 */
- "\x12""putstatic", /* 179 */
- "\x12""getfield", /* 180 */
- "\x12""putfield", /* 181 */
- "\x12""invokevirtual", /* 182 */
- "\x12""invokenonvirtual", /* 183 */
- "\x12""invokestatic", /* 184 */
- "\x14""invokeinterface", /* 185 */
- "\x00""<missing186>", /* 186 */
- "\x12""new", /* 187 */
- "\x01""newarray", /* 188 */
- "\x12""anewarray", /* 189 */
- "\x00""arraylength", /* 190 */
- "\x00""athrow", /* 191 */
- "\x12""checkcast", /* 192 */
- "\x12""instanceof", /* 193 */
- "\x00""monitorenter", /* 194 */
- "\x00""monitorexit", /* 195 */
- "\x01""wide", /* 196 */
- "\x13""multinewarray", /* 197 */
- "\x08""ifnull", /* 198 */
- "\x08""ifnonnull", /* 199 */
- "\x09""goto_w", /* 200 */
- "\x09""jsr_w", /* 201 */
- "\x00""breakpoint", /* 202 */
- "\x00""<missing203>", /* 203 */
- "\x00""<missing204>", /* 204 */
- "\x00""<missing205>", /* 205 */
- "\x00""<missing206>", /* 206 */
- "\x00""<missing207>", /* 207 */
- "\x00""<missing208>", /* 208 */
- "\x02""ret_w", /* 209 */
- "\x00""<missing >= 210>" };
- static unsigned char *labtab;
- static void notelab(unsigned32 l)
- { if (l < 0x10000) labtab[l/8] |= 1 << (l%8);
- /* err_printf("notelab %d\n", l); */
- }
- static int islab(unsigned32 l)
- { int b = 1 << l%8;
- /* err_printf("islab %d\n", l); */
- if (l < 0x10000 && labtab[l/8] & b)
- { /* labtab[l/8] ^= b; */
- return 1;
- }
- return 0;
- }
- static int reflab(unsigned32 l)
- { int b = 1 << l%8;
- if (l < 0x10000 && labtab[l/8] & b)
- { err_printf("L%.4x", l);
- return 1;
- }
- return 0;
- }
- #define ztos16(w) (((unsigned32)(w) ^ 0x8000) - 0x8000)
- static void decode_lit(unsigned32 n, Cp_Info *cp, unsigned32 cplen)
- { for (;;)
- { if (n == 0 || n >= cplen)
- { err_printf("<bad literal 0x%x>", n);
- return;
- }
- else switch (cp[n].tag)
- {
- case CONSTANT_Class: err_printf("Class"); goto redo;
- case CONSTANT_FieldRef: err_printf("FieldRef"); goto redo2;
- case CONSTANT_MethodRef: err_printf("MethodRef"); goto redo2;
- case CONSTANT_InterfaceMethodRef: err_printf("InterfaceMethodRef"); goto redo2;
- case CONSTANT_String: err_printf("String"); goto redo;
- case CONSTANT_Integer: err_printf("Integer:%d",n); return;
- case CONSTANT_Float: err_printf("Float:%d",n); return;
- case CONSTANT_Long: err_printf("Long:%d",n); return;
- case CONSTANT_Double: err_printf("Double:%d",n); return;
- case CONSTANT_Utf8: err_printf("Utf8[%d'%*s']", n,
- cp[n].len, cp[n].u.utf8); return;
- case CONSTANT_Unicode: err_printf("Unicode:%d",n); return;
- case CONSTANT_NameAndType: err_printf("NameAndType"); goto redo2;
- default: err_printf("<unknown literal[%.4x] %d>", n, cp[n].tag); return;
- }
- redo: err_printf("[%d]:", n); n = cp[n].u.val; continue;
- redo2: err_printf("[%d]:<", n);
- decode_lit(cp[n].u.val, cp, cplen);
- err_printf(",");
- decode_lit(cp[n].len, cp, cplen);
- err_printf(">"); return;
- }
- }
- char *jdecodeopname(unsigned32 op)
- {
- if (op >= 210) op = 210;
- return optable[op].opname+1;
- }
- void javadecode(unsigned8 *code, unsigned32 len, Cp_Info *cp, unsigned32 cplen)
- { unsigned8 *p;
- if (labtab == 0) labtab = (unsigned char *)jmalloc(0x10000/8);
- memset(labtab, 0, 0x10000/8);
- for (p = code; p < code+len;)
- { unsigned32 op = *p++;
- if (op >= 210) op = 210;
- switch (optable[op].opname[0])
- {
- default: break;
- case 0x11:
- case 0x01: p++; break;
- case 0x12:
- case 0x02: p += 2; break;
- case 0x08: notelab(p-1-code + ztos16(p[0]<<8 | p[1])); p += 2; break;
- case 0x03: p += 2; break;
- case 0x13: p += 3; break;
- case 0x14:
- case 0x04: p += 4; break;
- case 0x09: notelab(p-1-code + (p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3])); p += 4;
- break;
- case 0x06: ("\ttableswitch!"); break;
- case 0x07: ("\tlookupswitch!"); break;
- }
- }
- for (p = code; p < code+len;)
- { unsigned32 op = *p++;
- unsigned32 off;
- if (op >= 210) op = 210;
- if (islab(p-1 - code)) err_printf("L%.4x:", p-1 - code);
- err_printf("\t%s", optable[op].opname+1);
- if (optable[op].opname[0] != 0x00 && strlen(optable[op].opname+1) < 8)
- err_printf("\t");
- switch (optable[op].opname[0])
- {
- default: break;
- case 0x01: err_printf("\t%d", *p++); break;
- case 0x11: err_printf("\t"); decode_lit(*p++, cp, cplen); break;
- case 0x02: err_printf("\t0x%.4x", p[0]<<8 | p[1]); p += 2; break;
- case 0x12: err_printf("\t"); decode_lit(p[0]<<8 | p[1], cp, cplen); p += 2; break;
- case 0x08: off = ztos16(p[0]<<8 | p[1]);
- err_printf("\t");
- if (!reflab(p-1-code+off)) err_printf("$+0x%.4x", off);
- p += 2; break;
- case 0x03: err_printf("\t%d,%d", p[0], p[1]); p += 2; break;
- case 0x13: err_printf("\t"); decode_lit(p[0]<<8 | p[1], cp, cplen);
- err_printf(",%d", p[2]); p += 3; break;
- case 0x14: err_printf("\t"); decode_lit(p[0]<<8 | p[1], cp, cplen);
- err_printf(",%d,%d", p[2], p[3]); p += 4; break;
- case 0x04: err_printf("\t0x%.8x", p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3]); p += 4;
- break;
- case 0x09: off = p[0]<<24 | p[1]<<16 | p[2]<<8 | p[3];
- err_printf("\t(big)");
- if (!reflab(p-1-code+off)) err_printf("\t$+0x%.8x", off);
- p += 4; break;
- case 0x06: err_printf("\tswitch!");
- break;
- case 0x07: err_printf("\tswitch!");
- break;
- }
- err_printf("\n");
- }
- }
- /* end of jadecode.c */
|