[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Jilc-patches] CVS: jilc/src jdasm.c,1.6,1.7 jdasm.h,1.8,1.9
From: |
Gaurav Vaish <address@hidden> |
Subject: |
[Jilc-patches] CVS: jilc/src jdasm.c,1.6,1.7 jdasm.h,1.8,1.9 |
Date: |
Mon, 22 Apr 2002 05:12:43 -0400 |
Update of /cvsroot/jilc/jilc/src
In directory subversions:/tmp/cvs-serv26156
Modified Files:
jdasm.c jdasm.h
Log Message:
2002-22-04 Gaurav Vaish <address@hidden>
* jdasm.c, jdasm.h: Abhaya's Code
Index: jdasm.c
===================================================================
RCS file: /cvsroot/jilc/jilc/src/jdasm.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- jdasm.c 27 Feb 2002 04:30:58 -0000 1.6
+++ jdasm.c 22 Apr 2002 09:12:37 -0000 1.7
@@ -1,577 +1,996 @@
-/**
- * jdasm.c -- Deassembler implementation file.
+
+/*
+ * jdasm.c - java Disassembler
+ *
+ * Copyright (C) 2002 Free Software Foundation India
+ *
+ * Author : Gopal.V
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * Author: Gaurav Vaish <address@hidden>
- * Gopal V (address@hidden)
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * (C) Gaurav Vaish, Gopal V; 2002
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <jdasm.h>
-#include <jopcodes.h>
-#include <jparser.h>
-
-void print_interfaces(JVClass *klass, JVCPEntry *cp_entry)
-{
- int i;
- for(i = 0; i < klass->interface_count; i++)
- {
- printf(".implements %s\n",
klass->interface_entries[i].full_name);
- }
-}
-
-void print_fields(JVClass *klass, JVCPEntry *cp_entry)
-{
- int i;
- for(i = 0; i < klass->field_count; i++)
- {
- printf(".field %s %s %s\n", klass->field_entries[i].full_flags,
\
- klass->field_entries[i].full_name,
klass->field_entries[i].full_type);
- }
-}
-
-void print_string_cp(JVCPEntry *cp_entry, unsigned int index)
-{
- switch(cp_entry[index].type)
- {
- case UTF8: printf("%s", cp_entry[index].values.utf8string);
- break;
- case STRING: printf("\"%s\"",
cp_entry[cp_entry[index].values.strvalue].values.utf8string);
- break;
- case INTEGER: printf("%d", cp_entry[index].values.intvalue);
- break;
- case LONG: printf("%ld", cp_entry[index].values.longvalue);
- break;
- case FLOAT: printf("%f", cp_entry[index].values.floatvalue);
- break;
- case DOUBLE: printf("%d", cp_entry[index].values.doublevalue);
- break;
- case CLASSREF: printf("%s",
cp_entry[index].values.class_value.full_name);
- break;
- case FIELDREF: printf("%s/%s %s",
cp_entry[index].values.ref_value.full_class, \
- cp_entry[index].values.ref_value.full_name, \
- cp_entry[index].values.ref_value.full_type);
- break;
- case METHODREF:
- case INTERFACEMETHODREF:
- printf("%s/%s %s",
cp_entry[index].values.ref_value.full_class, \
- cp_entry[index].values.ref_value.full_name, \
- cp_entry[index].values.ref_value.full_type);
- break;
- case NAMEANDTYPE:
- printf("%s", resolve_name_type(index, cp_entry));
- break;
- }
-}
-/**
- * collect JUMP offset,
- * param @code the bytecode
- * param @codelen code length
+#include <stdio.h>
+#include <stdlib.h>
+#include "jopcodes.h"
+//#include "pretty.h"
+#define OK 0
+#define ERROR 1
+//#define DEBUG 1
+FILE * DEBUG_OUT;
+int pretty_print=0;
+#define IF_PRETTY_PRINT(x) if(pretty_print)x;
+typedef unsigned char byte;
+typedef unsigned char UInt8;
+typedef short Int16 ;
+typedef unsigned short UInt16;
+typedef int Int32;
+typedef unsigned int UInt32;
+typedef long long Int64;
+typedef unsigned long long UInt64;
+
+typedef struct
+{
+ byte *data;
+ UInt32 next;
+ UInt32 left;
+}jbuffer;
+
+#define CONSTANT_Utf8 1
+#define CONSTANT_Integer 3
+#define CONSTANT_Float 4
+#define CONSTANT_Long 5
+#define CONSTANT_Double 6
+#define CONSTANT_Classref 7
+#define CONSTANT_String 8
+#define CONSTANT_Fieldref 9
+#define CONSTANT_Methodref 10
+#define CONSTANT_InterfaceMethodref 11
+#define CONSTANT_NameAndType 12
+char* CPTable[]=\
+{
+ "Junk","CONSTANT_Utf8","Junk","CONSTANT_Integer","CONSTANT_Float",
+ "CONSTANT_Long","CONSTANT_Double","CONSTANT_Class","CONSTANT_String",
+ "CONSTANT_Field","CONSTANT_Method","CONSTANT_InterfaceMethod",
+ "CONSTANT_NameAndType","Junk","Junk","Junk"
+};
+//access flags
+#define ACC_PUBLIC 0x0001
+#define ACC_PRIVATE 0x0002
+#define ACC_PROTECTED 0x0004
+#define ACC_STATIC 0x0008
+#define ACC_FINAL 0x0010
+#define ACC_SYNCHRONIZED 0x0020
+#define ACC_VOLATILE 0x0040
+#define ACC_TRANSIENT 0x0080
+#define ACC_NATIVE 0x0100
+#define ACC_ABSTRACT 0x0400
+//attribute types
+#define ATTR_TOP 0
+#define ATTR_FIELD 1
+#define ATTR_METHOD 2
+#define ATTR_CODE 3
+
+#define PRINT_OPCODE_NAME(x) ILColorBold();ILColorBlue();\
+ printf("\t %s ",x.name);ILColorClear();
+#define OPCODE_PRINT(x) x
+/*
+ * end of my defs
*/
-UInt32 * get_jump_points(byte *code,int codelen)
+inline UInt8 read_byte(FILE *fp)
{
- Int32 *jump_points;
- jopcode_map found;
- int start=0;
- int i,count,j;
- Int32 high,low;
- Int32 dest;
- Int32 insn_offset;
- jump_points=(UInt32*)calloc(codelen >> 5,sizeof(UInt32));
- //a bit for each byte in code
-#ifndef __STABLE__
- while(start<codelen)
- {
- i=search_jopcode_map(code[start]);
- found=get_jopcode_map(i);
- insn_offset=start;
- switch(found.args)
- {
- /*case NONE:
- start++; // default: already
does this
- break;*/
- case I_S1:
- case I_U1:
- case CONSTANT_U1:
- case ARRAYTYPE_U1:
- start++;
- start += 1;
- break;
- case I_U2:
- case I_S2:
- case II_U1_S1:
- case FIELD_U2:
- case METHOD_U2:
- case CLASS_U2:
- case CONSTANT_U2:
- case BIGCONSTANT_U2:
- start++;
- start += 2;
- break;
- case LABEL_S2:
- start++;
-
dest=insn_offset+READ_INT16(code,start);
- if(dest<codelen)
-
jump_points[dest/32]|=(UInt32)(1L << \
-
(dest%32));
- else
-
fprintf(stderr,"illegal jump offset %ld\n"\
-
,dest);
- start += 2;
- break;
- case LABEL_S4:
- start++;
-
dest=insn_offset+READ_INT32(code,start);
- if(dest<codelen)
-
jump_points[dest/32]|=(UInt32)(1L << \
-
(dest%32));
- else
-
fprintf(stderr,"illegal jump offset %ld\n"\
-
,dest);
- start+=4;
- break;
- case LOOKUP_SWITCH:
- start++;
- while( (start % 4) != 0)
- {
- start++;
- }
- dest =
insn_offset+READ_INT32(code,start);
- if(dest<codelen) //
default offset
-
jump_points[dest/32]|=(UInt32)(1L << \
-
(dest%32));
- else
-
fprintf(stderr,"illegal jump offset %ld\n",\
-
dest);
- start += 4;
- count =
READ_INT32(code,start);
- start += 4;
- for(j = 0; j < count;
j++)
- {
- start += 4;//skip key
-
dest=insn_offset+READ_INT32(code,start);
- if(dest<codelen)
-
jump_points[dest/32]|=(UInt32)(1L <<\
-
(dest%32));
- else
fprintf(stderr,"illegal jump offset");
- start += 4;
- }
- break;
- case TABLE_SWITCH:
- start++;
- while( (start % 4) != 0)
- {
- start++;
- }
- dest =
insn_offset+READ_INT32(code,start);
- if(dest<codelen) //
default offset
-
jump_points[dest/32]|=(UInt32)(1L << \
-
(dest%32));
- else
-
fprintf(stderr,"illegal jump offset %ld\n",\
-
dest);
- start += 4;
- low =
READ_INT32(code,start);
- start+= 4;
- high =
READ_INT32(code,start);
- start+= 4;
- if(low>high)
- {
-
fprintf(stderr,"Error !\n");
- return NULL;
- }
- for(j=low;j<=high;j++)
- {
-
dest=insn_offset+READ_INT32(code,start);
- if(dest<codelen)
-
jump_points[dest/32]|=(UInt32)(1L <<\
-
(dest%32));
- else
fprintf(stderr,"illegal jump offset");
- start+=4;
- }
- break;
- case MARRAY_U2_U1:
- start++;
- start+=3;
- break;
- case INTERFACE_U2_U1_X1:
- start++;
- start+=4;//skip one
byte xtra coz SUN says so
- break;
- default: //this does the work of none and
ignore
- start++;
- }
- }
-#endif
- return jump_points;
+ UInt8 retval;
+ retval=fgetc(fp);
+ return retval;
}
-
-void print_byte_code(byte *code, int *start_index, int code_len, int
*wide,UInt32 *jump_points,JVCPEntry *cp_entry)
+inline UInt16 read_uint16(FILE *fp)
{
- int start = *start_index;
- Int32 key;
- Int32 offset;
- Int32 default_offset;
- Int32 count;
- Int32 low,high;
- int insn_offset = start;
- int j;
- /* code to solve printf("%d") sign problem*/
- UInt16 uint_16;
- UInt32 uint_32;
- Int16 int_16;
- Int32 int_32;
-
- int i = search_jopcode_map(code[start]);
- jopcode_map found;
-
- if(i >= 0)
- {
- found = get_jopcode_map(i);
- if((jump_points[insn_offset/32] & (UInt32)(1L << (insn_offset
%32)))!=0)
- printf("j_%04d :",insn_offset);
- else
- printf("\t");
- switch(found.args)
- {
- case NONE:
- PRINT_OP_NAME(found);
- start++;
- break;
- case I_U1:
- PRINT_OP_NAME(found);
- start++;
- if(*wide==1)
- {
-
uint_16=(UInt16)READ_UINT16(code,start);
- printf(" %u ",uint_16);
- start += 2;
- }
- else
- {
- printf(" %u ", (unsigned
char)(code[start]));
- start += 1;
- }
- break;
- case I_U2:
- PRINT_OP_NAME(found);
- start++;
-
uint_16=(UInt16)READ_UINT16(code,start);
- printf(" %u ",uint_16);
- start += 2;
- break;
- case I_S1:
- PRINT_OP_NAME(found);
- start++;
- printf(" %d ",(signed
char)(code[start]));
- start += 1;
- break;
- case I_S2:
- PRINT_OP_NAME(found);
- start++;
-
int_16=(Int16)READ_INT16(code,start);
- printf(" %d ",int_16);
- start += 2;
- break;
- case II_U1_S1:
- PRINT_OP_NAME(found);
- start++;
- if(*wide ==1)
- {
-
uint_16=READ_UINT16(code,start);
- printf(" %u ", uint_16);
- start+=2;
-
int_16=READ_INT16(code,start);
- printf("%d ", int_16);
- start+=2;
- }
- else
- {
- printf(" %u %d", (unsigned
char)(code[start]), \
-
(signed char)(code[start + 1]));
- start += 2;
- }
- break;
- case FIELD_U2:
- case METHOD_U2:
- case CLASS_U2:
- case CONSTANT_U2:
- case BIGCONSTANT_U2:
- PRINT_OP_NAME(found);
- start++;
- print_string_cp(cp_entry,
READ_UINT16(code,start));
- start += 2;
- break;
- case CONSTANT_U1:
- PRINT_OP_NAME(found);
- start++;
- print_string_cp(cp_entry, code[start]);
- start += 1;
- break;
- case LOOKUP_SWITCH:
- PRINT_OP_NAME(found);
- start++;
- while( (start % 4) != 0)
- {
- start++;
- }
- default_offset =
READ_INT32(code,start);
- start += 4;
- count = READ_INT32(code,start);
- start += 4;
- printf(" %ld key-values\n",
count);
- for(j = 0; j < count; j++)
- {
- key =
READ_INT32(code,start);
- start += 4;
- offset =
READ_INT32(code,start);
- start += 4;
- printf("\t\t%ld\t: j_%04d\n",
key, insn_offset + \
-
offset);
- }
- printf("\t\tdefault\t: j_%04d",
insn_offset + \
-
default_offset);
- break;
- case TABLE_SWITCH:
- PRINT_OP_NAME(found);
- start++;
- while( (start % 4) != 0)
- {
- start++;
- }
- default_offset =
READ_INT32(code,start);
- start += 4;
- low = READ_INT32(code,start);
- start+= 4;
- printf(" %d; low value\n",low);
- high = READ_INT32(code,start);
- start+= 4;
- if(low>high)
- {
- fprintf(stderr,"Error
!\n");
- return;
- }
- for(j=low;j<=high;j++)
- {
- offset =
READ_INT32(code,start);
- start += 4;
- printf("\t\t j_%04d; offset for
%d\n",\
-
insn_offset + offset,j);
- }
- printf("\t default:j_%04d",
insn_offset + \
-
default_offset);
- break;
- case LABEL_S2:
- PRINT_OP_NAME(found);
- start++;
- int_16=insn_offset +
READ_INT16(code,start);
- printf(" j_%04d",int_16);
- start += 2;
- break;
- case LABEL_S4:
- PRINT_OP_NAME(found);
- start++;
- int_32=insn_offset +
(Int32)(READ_INT32(code,start));
- printf(" j_%04d",int_32);
- start+=4;
- break;
- case MARRAY_U2_U1:
- PRINT_OP_NAME(found);
- start++;
-
uint_16=(UInt16)(READ_UINT16(code,start));
-
print_string_cp(cp_entry,uint_16);
- printf(" %u ",(unsigned
char)code[start+2]);
- start+=3;
- break;
- case ARRAYTYPE_U1:
- PRINT_OP_NAME(found);
- start++;
- if(code[start]<4 ||
code[start]>11)
- {
- fprintf(stderr,"invalid
array type => %d\n",\
-
code[start]);
- }
- else
- printf(" %s
",array_types[code[start]]);
- start+=1;
- break;
- case INTERFACE_U2_U1_X1:
- PRINT_OP_NAME(found);
- start++;
-
uint_16=(UInt16)(READ_UINT16(code,start));
-
print_string_cp(cp_entry,uint_16);
- printf(" %u ",(unsigned
char)code[start+2]);
- start+=4;//skip one byte coz
SUN says so
- break;
- case IGNORE: // wide opcode !
- PRINT_OP_NAME(found);
- start++;
- *wide=1;
- break;
- default: printf(": Unknown instruction %d",
code[start]);
- start++;
- }
- if(*wide && (found.opcode != JAVA_WIDE))
- {
- *wide=0;
- }
- printf("\n");
- }
- *start_index = start;
-}
-void mark_try_catch_blocks(JVAttributeEntry *code,int codelen, UInt32
*jump_points,JVCPEntry *cp_entry)
-{
- int i;
- JVExceptionHandler handle;
- Int32 dest;
- for(i=0;i<code->attributes.code.handler_count;i++)
- {
- handle=code->attributes.code.handlers[i];
- printf(".catch ");
- print_string_cp(cp_entry,handle.catch_type);
- printf(" from j_%04d to j_%04d using j_%04d
\n",handle.start_pc,\
-
handle.end_pc,handle.handler_pc);
- dest = handle.start_pc;
- if(dest<codelen)
- jump_points[dest/32]|=(UInt32)(1L << (dest%32));
- else fprintf(stderr,"illegal jump offset");
- dest = handle.end_pc;
- if(dest<codelen)
- jump_points[dest/32]|=(UInt32)(1L << (dest%32));
- else fprintf(stderr,"illegal jump offset");
- dest = handle.handler_pc;
- if(dest<codelen)
- jump_points[dest/32]|=(UInt32)(1L << (dest%32));
- else fprintf(stderr,"illegal jump offset");
- }
-}
-void print_method_code(JVMethodEntry *method, JVCPEntry *cp_entry)
-{
- int i;
- int start = 0;
- byte *code =
method->attr_entries[method->code_index].attributes.code.code;
- int codelen =
method->attr_entries[method->code_index].attributes.code.code_count;
- UInt32 *jump_points;
- int wide=0;
-
- if( (method->acc_flags & ACCESS_ABSTRACT) != 0 || codelen == 0)
- {
- return;
- }
- if((method->status_flags & METHOD_CODE)==0)
- {
- return;//no code attribute ?
- }
- printf(".limit stack %d\n",
method->attr_entries[method->code_index].attributes.code.max_stack);
- printf(".limit locals %d\n",
method->attr_entries[method->code_index].attributes.code.max_locals);
- print_method_throws(method,cp_entry);
- jump_points=get_jump_points(code,codelen);
-
mark_try_catch_blocks(&(method->attr_entries[method->code_index]),codelen,\
- jump_points,cp_entry);
- while(start < codelen)
- {
- print_byte_code(code, &start, codelen,
&wide,jump_points,cp_entry);
- }
- //printf(": TODO-> label management\n"); worked out
- printf(": TODO-> wide opcode not supported\n");
-}
-
-void print_method_throws(JVMethodEntry *method,JVCPEntry *cp_entry)
-{
- int i;
- int
count=method->attr_entries[method->except_index].attributes.exception.except_count;
- if((method->status_flags & METHOD_EXCEPTION) ==0)
- {
- return;
- //no throws clause ? (you mean just like no santa clause ? ;-)
- }
- for(i=0;i<count;i++)
- {
- printf("\t .throws ");
-
print_string_cp(cp_entry,method->attr_entries[method->except_index].attributes.exception.excepts[i].class_index);
- printf("\n");
- }
-}
-void print_methods(JVClass *klass, JVCPEntry *cp_entry)
-{
- int i;
- for(i = 0; i < klass->method_count; i++)
- {
- printf(".method %s %s%s\n",
klass->method_entries[i].full_flags, \
- klass->method_entries[i].full_name,
- klass->method_entries[i].full_type);
- print_method_code(&((klass->method_entries)[i]), cp_entry);
- printf(".end method\n");
- }
-}
-
-void print_class(JVClass *klass, JVCPEntry *cp_entry)
-{
- printf(".class %s %s\n", klass->full_flags, klass->full_name);
- printf(".super %s\n", klass->full_super);
- print_interfaces(klass, cp_entry);
- print_fields(klass, cp_entry);
- print_methods(klass, cp_entry);
+ UInt16 retval=0;
+ retval=((UInt16)read_byte(fp))<<8|((UInt16)read_byte(fp));
+ return retval;
}
-
-void usage()
+inline UInt32 read_uint32(FILE *fp)
{
- printf("\tjdasm 0.0.1 - Java Deassembler\n");
- printf("\n");
- printf("usage: jdasm [OPTIONS] <class-file>\n\n");
- printf("Options:\n");
- printf("\t--version\n\t Print version and exit\n");
- printf("\t--help\n\t Print this help screen\n");
+ UInt32 retval=0;
+ retval=((UInt32)read_uint16(fp))<<16 | ((UInt32)read_uint16(fp));
+ return retval;
}
+inline UInt64 read_uint64(FILE *fp)
+{
+ UInt64 retval;
+ retval=((UInt64)read_uint32(fp)) << 32 | ((UInt64)read_uint32(fp));
+ return retval;
+}
+inline void skip_bytes(FILE *fp,int bytes)
+{
+ int i;
+ for(i=0;i<bytes;i++)fgetc(fp);
+}
+/*
+ *
+ * buffer operations (he he ha !)
+ */
+inline byte bufread_byte(jbuffer *buf)
+{
+ byte retval;
+ if(buf->left==0)
+ {
+ fprintf(DEBUG_OUT,"Buffer empty");
+ return 0;
+ }
+ buf->left--;
+ retval=buf->data[buf->next];
+ buf->next++;
+ return retval;
+}
+inline UInt16 bufread_uint16(jbuffer *buf)
+{
+ return ((UInt16)bufread_byte(buf))<<8 | (UInt16)bufread_byte(buf);
+}
+inline UInt16 bufread_uint32(jbuffer *buf)
+{
+ return ((UInt32)bufread_uint16(buf))<<16 | (UInt16)bufread_uint16(buf);
+}
+inline void bufskip_bytes(jbuffer *buf,UInt32 bytes)
+{
+ if(buf->left < bytes || bytes < 0 )
+ {
+ fprintf(DEBUG_OUT,"**OOPS Cannot do this \n");
+ return;
+ }
+ buf->next+=bytes;
+ buf->left-=bytes;
+}
+/*
+ * End of Little Endian read funcs
+ */
+typedef struct
+{
+ UInt8 type;
+ UInt16 length;
+ UInt8 skip;//for Longs and Doubles this is 1
+ union
+ {
+ char *utf8string;
+ Int32 intvalue;
+ Int64 longvalue;
+ float floatvalue;
+ double doublevalue;
+ UInt32 strvalue;
+ struct
+ {
+ UInt32 name_index;
+ //filled in during resolve
+ char *full_name;
+ } class_value;
+ struct
+ {
+ UInt32 class_index;
+ UInt32 name_and_type;
+ char *full_class;
+ char *full_name;
+ char *full_type;
+ } ref_value;
+ struct
+ {
+ UInt32 name_index;
+ UInt32 type_index;
+ char *full_name;
+ char *full_type;
+ } name_and_type;
+ } un;
+} JVCPEntry;
+
+typedef struct
+{
+ UInt16 start_pc;
+ UInt16 end_pc;
+ UInt16 handler_pc;
+ UInt16 catch_type;
+}JVExceptionHandler;
+typedef struct
+{
+ UInt16 class_index;
+ char *class_name;
+}JVException;
+typedef struct _JVAttributeEntry
+{
+ UInt16 name_index;
+ UInt32 byte_count;
+ UInt8 type;
+ jbuffer *buf;
+ union
+ {
+ struct
+ {
+ UInt16 source_index;
+ char *full_source;
+ }source;
+ struct
+ {
+ UInt16 except_count;
+ JVException *excepts;
+ }exception;
+ struct
+ {
+ UInt16 max_stack;
+ UInt16 max_locals;
+ UInt32 code_count;
+ byte *code;
+ UInt16 handler_count;
+ JVExceptionHandler *handlers;
+ UInt16 attr_count;
+ byte *attributes;
+ }code;
+ }un;
+ //description attrs -- resolved
+ char *full_name;
+}JVAttributeEntry;
+
+typedef struct
+{
+ UInt16 acc_flags;
+ UInt16 name_index;
+ UInt16 type_index;
+ UInt16 attr_count;
+ JVAttributeEntry *attr_entries;
+ char *full_flags;
+ char *full_name;
+ char *full_type;
+}JVFieldEntry;
+
+typedef struct
+{
+ UInt16 index;
+ char *full_name;
+}JVInterfaceEntry;
+
+typedef struct
+{
+ UInt16 acc_flags;
+ UInt16 name_index;
+ UInt16 type_index;
+ UInt16 attr_count;
+ JVAttributeEntry *attr_entries;
+ //resolved
+ UInt16 code_index;
+ UInt16 except_index;
+ char *full_flags;
+ char *full_name;
+ char *full_type;
+}JVMethodEntry;
+typedef struct
+{
+ UInt32 magic;
+ UInt16 min_version;
+ UInt16 maj_version;
+ UInt16 cp_count;
+ JVCPEntry *cp_entries;
+ UInt16 acc_flags;
+ UInt16 this_class;
+ UInt16 super_class;
+ UInt16 interface_count;
+ JVInterfaceEntry *inter_entries;
+ UInt16 field_count;
+ JVFieldEntry *field_entries;
+ UInt16 methods_count;
+ JVMethodEntry *method_entries;
+ UInt16 attr_count;
+ JVAttributeEntry *attr_entries;
+
+ //description entries
+ char *full_name;
+ char *full_super;
+ char *full_flags;
+}JVClass;
+int read_cp_entry(FILE *fp,JVCPEntry *cp_entry)
+{
+ Int32 f;
+ Int64 d;
+ cp_entry->type=read_byte(fp);
+ switch(cp_entry->type)
+ {
+ case CONSTANT_Utf8:
+ cp_entry->length=read_uint16(fp);
+ cp_entry->un.utf8string=(byte*)calloc(cp_entry->length+1,\
+ sizeof(char));
+
fread(cp_entry->un.utf8string,cp_entry->length,sizeof(char),fp);
+ break;
+ case CONSTANT_Integer:
+ cp_entry->un.intvalue=read_uint32(fp);
+ break;
+ case CONSTANT_Float:
+ f=read_uint32(fp);
+ memcpy(&cp_entry->un.floatvalue,&f,sizeof(float));
+ break;
+ case CONSTANT_Long:
+ cp_entry->un.longvalue=read_uint64(fp);
+ cp_entry->skip=1;//skip the next
+ break;
+ case CONSTANT_Double:
+ d=read_uint64(fp);
+ cp_entry->skip=1;//skip the next
+ memcpy(&cp_entry->un.doublevalue,&d,sizeof(double));
+ break;
+ case CONSTANT_String:
+ cp_entry->un.strvalue=read_uint16(fp);
+ break;
+ case CONSTANT_Classref:
+ cp_entry->un.class_value.name_index=read_uint16(fp);
+ break;
+ case CONSTANT_Fieldref:
+ case CONSTANT_Methodref:
+ case CONSTANT_InterfaceMethodref:
+ cp_entry->un.ref_value.class_index=read_uint16(fp);
+ cp_entry->un.ref_value.name_and_type=read_uint16(fp);
+ break;
+ case CONSTANT_NameAndType:
+ cp_entry->un.name_and_type.name_index=read_uint16(fp);
+ cp_entry->un.name_and_type.type_index=read_uint16(fp);
+ break;
+ default:
+ cp_entry->type=0;
+ //return ERROR;
+ }
+ return OK;
+}
+int read_cp(FILE *fp,JVClass *klass)
+{
+ int i,j;
+ klass->cp_count=read_uint16(fp);
+ klass->cp_entries=(JVCPEntry*)calloc(klass->cp_count,\
+ sizeof(JVCPEntry));
+#ifdef DEBUG
+ fprintf(DEBUG_OUT,"No of CP : %d\n",klass->cp_count);
+#endif
+ //leave cp_entries[0] as empty
+ for(i=1;i<klass->cp_count;i++)
+ {
+ read_cp_entry(fp,&klass->cp_entries[i]);
+#ifdef DEBUG
+ fprintf(DEBUG_OUT,"%3d ) Constant_pool : %d |
%s\n",i,klass->cp_entries[i].type,\
+ CPTable[klass->cp_entries[i].type]);
+#endif
+ i+=klass->cp_entries[i].skip;
+ }
+ return OK;
+}
+int read_flags(FILE *fp,JVClass *klass)
+{
+ int errors=OK;
+ klass->acc_flags=read_uint16(fp);
+ klass->this_class=read_uint16(fp);
+ klass->super_class=read_uint16(fp);
+ return errors;
+}
+int read_interfaces(FILE *fp,JVClass *klass)
+{
+ int errors=OK;
+ int i;
+ klass->interface_count=read_uint16(fp);
+ //since there is only one format for
+ //interfaces i am writing all the code here
+ klass->inter_entries=(JVInterfaceEntry *)calloc(klass->interface_count\
+ ,sizeof(JVInterfaceEntry));
+ for(i=0;i<klass->interface_count;i++)
+ {
+ klass->inter_entries[i].index=read_uint16(fp);
+ }
+ return errors;
+}
+JVAttributeEntry* read_attributes(FILE *fp,int n,int type)
+{
+ int i,j;
+ JVAttributeEntry *retval=(JVAttributeEntry *)calloc(n,\
+ sizeof(JVAttributeEntry));
+ for(i=0;i<n;i++)
+ {
+ retval[i].type=type;
+ retval[i].name_index=read_uint16(fp);
+ retval[i].byte_count=read_uint32(fp);
+ retval[i].buf=(jbuffer*)calloc(1,sizeof(jbuffer));
+ retval[i].buf->data=(byte*)calloc(retval[i].byte_count,sizeof(char));
+ retval[i].buf->left=retval[i].byte_count;
+ fread(retval[i].buf->data,sizeof(char),retval[i].byte_count,fp);
+ }
+ return retval;
+}
+int read_fields(FILE *fp,JVClass *klass)
+{
+ int errors=OK;
+ int i;
+ klass->field_count=read_uint16(fp);
+ klass->field_entries= (JVFieldEntry*)calloc(klass->field_count,\
+ sizeof(JVFieldEntry));
+ for(i=0;i<klass->field_count;i++)
+ {
+ klass->field_entries[i].acc_flags=read_uint16(fp);
+ klass->field_entries[i].name_index=read_uint16(fp);
+ klass->field_entries[i].type_index=read_uint16(fp);
+ klass->field_entries[i].attr_count=read_uint16(fp);
+ klass->field_entries[i].attr_entries=read_attributes(fp,\
+ klass->field_entries[i].attr_count,ATTR_FIELD);
+ }
+ return errors;
+}
+int read_methods(FILE *fp,JVClass *klass)
+{
+ int i,errors=0;
+ klass->methods_count=read_uint16(fp);
+ klass->method_entries=(JVMethodEntry*)calloc(klass->methods_count,\
+ sizeof(JVMethodEntry));
+ for(i=0;i<klass->methods_count;i++)
+ {
+ klass->method_entries[i].acc_flags=read_uint16(fp);
+ klass->method_entries[i].name_index=read_uint16(fp);
+ klass->method_entries[i].type_index=read_uint16(fp);
+ klass->method_entries[i].attr_count=read_uint16(fp);
+ klass->method_entries[i].attr_entries=read_attributes(fp,\
+ klass->method_entries[i].attr_count,ATTR_METHOD);
+#ifdef DEBUG
+ fprintf(DEBUG_OUT,"Method : ");
+ fwrite(\
+ klass->cp_entries[klass->method_entries[i].name_index].un.utf8string\
+ ,sizeof(char),\
+
klass->cp_entries[klass->method_entries[i].name_index].length,DEBUG_OUT);
+ fprintf(DEBUG_OUT,"\n");
+#endif
-void version()
+ }
+ return errors;
+}
+int read_class(FILE *fp,JVClass *klass)
{
- printf("\tjdasm 0.0.1 - Java Deassembler\n");
- printf("\n");
+ int errors=OK;
+ klass->magic=read_uint32(fp);
+ if(klass->magic != 0xCAFEBABE)
+ {
+ fprintf(DEBUG_OUT,"I got %4X for magic\n",klass->magic);
+ fprintf(DEBUG_OUT,"I need a .class file !\n");
+ return ERROR;
+ }
+ klass->min_version=read_uint16(fp);
+ klass->maj_version=read_uint16(fp);
+ errors|=read_cp(fp,klass);
+ read_flags(fp,klass);
+ read_interfaces(fp,klass);
+ read_fields(fp,klass);
+ read_methods(fp,klass);
+ klass->attr_count=read_uint16(fp);
+ klass->attr_entries=read_attributes(fp,klass->attr_count,ATTR_TOP);
+//
fwrite(klass->cp_entries[klass->attr_entries[0].name_index],sizeof(byte),\
+ klass->cp_entries[
+ return errors;
+}
+/******************************************************************************
+ * end reading methods
+ * now start the resolving methods
+
******************************************************************************/
+char * resolve_utf8(UInt16 index,JVCPEntry *cp)
+//made it a function for type safety
+{
+ if(cp[index].type!=CONSTANT_Utf8)fprintf(DEBUG_OUT,"OOPS !\n");
+ return cp[index].un.utf8string;
+}
+char *resolve_string(UInt16 index,JVCPEntry *cp)
+{
+ return resolve_utf8(cp[index].un.strvalue,cp);
+}
+char *resolve_classref(UInt16 index,JVCPEntry *cp)
+{
+ cp[index].un.class_value.full_name=\
+ resolve_utf8(cp[index].un.class_value.name_index,cp);
+ return cp[index].un.class_value.full_name;
+}
+JVCPEntry* resolve_name_type(UInt16 index,JVCPEntry *cp)
+{
+ JVCPEntry *retval=&cp[index];
+ retval->un.name_and_type.full_name=\
+ resolve_utf8(retval->un.name_and_type.name_index,cp);
+ retval->un.name_and_type.full_type=\
+ resolve_utf8(retval->un.name_and_type.type_index,cp);
+ return retval;
+}
+JVCPEntry* resolve_ref(UInt16 index,JVCPEntry *cp)
+//for intreface,field,and method
+{
+ JVCPEntry *ref=&cp[index];
+ JVCPEntry *name_type=resolve_name_type(ref->un.ref_value.name_and_type,cp);
+ ref->un.ref_value.full_class=\
+ resolve_classref(ref->un.ref_value.class_index,cp);
+ ref->un.ref_value.full_name=name_type->un.name_and_type.full_name;
+ ref->un.ref_value.full_type=name_type->un.name_and_type.full_type;
+ return ref;//use pointers to the MAX
+}
+int resolve_cp(JVClass *klass,JVCPEntry *cp)//just for uniformity
+{
+ int i;
+ int errors=OK;
+ for(i=1;i<klass->cp_count;i++)
+ {
+ switch(cp[i].type)
+ {
+ case CONSTANT_Classref:
+ resolve_classref(i,cp);
+ break;
+ case CONSTANT_Fieldref:
+ case CONSTANT_Methodref:
+ case CONSTANT_InterfaceMethodref:
+ resolve_ref(i,cp);
+ break;
+ case CONSTANT_NameAndType:
+ resolve_name_type(i,cp);
+ break;
+ }
+ }
+ return errors;
+}
+char * resolve_flags(UInt16 flag,JVCPEntry *cp)
+// gvaish: Why do you need (JVCPEntry*)?
+{
+ char *retval=(char*)calloc(101,sizeof(char));//100+1 for luck
+ if(flag == 0x0000)strcat(retval," ");//I don't know why java has a 0 flag
+ if(flag & ACC_PUBLIC)strcat(retval,"public");
+ if(flag & ACC_PRIVATE)strcat(retval,"private");
+ if(flag & ACC_PROTECTED)strcat(retval,"protected");
+ if(flag & ACC_STATIC)strcat(retval," static");
+ if(flag & ACC_FINAL)strcat(retval," final");
+ if(flag & ACC_SYNCHRONIZED)strcat(retval," synchronized");
+ if(flag & ACC_VOLATILE)strcat(retval," volatile");
+ if(flag & ACC_TRANSIENT)strcat(retval," transient");
+ if(flag & ACC_NATIVE)strcat(retval," native");
+ if(flag & ACC_ABSTRACT)strcat(retval," abstract");
+ retval=realloc(retval,strlen(retval));//why waste memory ?
+ return retval;
+}
+int resolve_all_interfaces(JVClass *klass,JVCPEntry *cp)
+{
+ int errors=OK;
+ int i;
+ for(i=0;i<klass->interface_count;i++)
+ {
+ klass->inter_entries[i].full_name=resolve_classref(\
+ klass->inter_entries[i].index,cp);
+#ifdef DEBUG
+ fprintf(DEBUG_OUT,".implements
%s\n",klass->inter_entries[i].full_name);
+#endif
+ }
+ return errors;
+}
+//attribute processing
+int process_source_attribute(JVAttributeEntry *attr,JVCPEntry *cp)
+{
+ int errors=OK;
+ if(attr->type==ATTR_TOP && attr->byte_count==2)
+ if(!strncmp("SourceFile",resolve_utf8(attr->name_index,cp),10))
+ {
+ attr->un.source.source_index=bufread_uint16(attr->buf);
+ attr->un.source.full_source=\
+ resolve_utf8(attr->un.source.source_index,cp);
+ printf(".source %s\n",attr->un.source.full_source);
+ //plonk it to save memory
+ }
+ return errors;
+}
+int resolve_top_attributes(JVClass *klass,JVCPEntry *cp)
+{
+ int errors=OK;
+ int i;
+ for(i=0;i<klass->attr_count;i++)
+ {
+ klass->attr_entries[i].full_name=\
+ resolve_utf8(klass->attr_entries[i].name_index,cp);
+ errors|=process_source_attribute(&klass->attr_entries[i],cp);
+ }
+ return errors;
+}
+//int resolve_field_attributes(JVFieldEntry *
+int resolve_field(JVFieldEntry *field,JVCPEntry *cp)
+{
+ int errors=OK;
+ field->full_flags=resolve_flags(field->acc_flags,cp);
+ field->full_name=resolve_utf8(field->name_index,cp);
+ field->full_type=resolve_utf8(field->type_index,cp);
+#ifdef DEBUG
+ fprintf(DEBUG_OUT,".field %s %s %s\n",field->full_flags,field->full_name,\
+ field->full_type);
+#endif
+ return errors;
+}
+int resolve_all_fields(JVClass *klass,JVCPEntry *cp)
+{
+ int errors=OK;
+ int i;
+ for(i=0;i<klass->field_count;i++)
+ {
+ errors|=resolve_field(&klass->field_entries[i],cp);
+ }
+ return errors;
+}
+//method !
+int process_methodcode_attribute(JVAttributeEntry *code,JVCPEntry *cp)
+{
+ int i;
+ code->un.code.max_stack=bufread_uint16(code->buf);
+ code->un.code.max_locals=bufread_uint16(code->buf);
+ code->un.code.code_count=bufread_uint32(code->buf);
+#ifdef DEBUG
+ fprintf(DEBUG_OUT,"Code : %d | %d | %d\n",code->un.code.max_stack,\
+ code->un.code.max_locals,code->un.code.code_count);
+#endif
+ code->un.code.code=&(code->buf->data[code->buf->next]);
+ bufskip_bytes(code->buf,code->un.code.code_count);
+ code->un.code.handler_count=bufread_uint16(code->buf);
+#ifdef DEBUG
+ fprintf(DEBUG_OUT,"Exceptions %d\n",code->in.code.handler_count);
+#endif
+ code->un.code.handlers=(JVExceptionHandler *)\
+ calloc(code->un.code.handler_count,sizeof(JVExceptionHandler));
+ for(i=0;i<code->un.code.handler_count;i++)
+ {
+ code->un.code.handlers[i].start_pc=bufread_uint16(code->buf);
+ code->un.code.handlers[i].end_pc=bufread_uint16(code->buf);
+ code->un.code.handlers[i].handler_pc=bufread_uint16(code->buf);
+ code->un.code.handlers[i].catch_type=bufread_uint16(code->buf);
+ }
+ //I am ignoring the other attributes
+ return OK;
+}
+int resolve_all_method_attributes(JVMethodEntry *method,JVCPEntry *cp)
+{
+ int errors=OK;
+ int i;
+ for(i=0;i<method->attr_count;i++)
+ {
+ method->attr_entries[i].full_name=\
+ resolve_utf8(method->attr_entries[i].name_index,cp);
+ if(!strncmp(method->attr_entries[i].full_name,"Code",4))
+ {
+ method->code_index=i;
+ errors|=process_methodcode_attribute(&method->attr_entries[i],cp);
+ }
+#ifdef DEBUG
+ fprintf(DEBUG_OUT,".attribute %s\n",method->attr_entries[i].full_name);
+#endif
+ }
+ return errors;
+}
+int resolve_method(JVMethodEntry *method,JVCPEntry *cp)
+{
+ int errors=OK;
+ method->full_flags=resolve_flags(method->acc_flags,cp);
+ method->full_name=resolve_utf8(method->name_index,cp);
+ method->full_type=resolve_utf8(method->type_index,cp);
+#ifdef DEBUG
+ fprintf(DEBUG_OUT,".method %s %s
%s\n",method->full_flags,method->full_name,\
+ method->full_type);
+#endif
+ resolve_all_method_attributes(method,cp);
+ return errors;
}
-int main(int argc, char **argv)
+int resolve_all_methods(JVClass *klass,JVCPEntry *cp)
+{
+ int errors=OK;
+ int i;
+ for(i=0;i<klass->methods_count;i++)
+ {
+ errors|=resolve_method(&klass->method_entries[i],cp);
+ }
+ return errors;
+}
+int resolve_class(JVClass *klass,JVCPEntry *cp)
+{
+ int errors=OK;
+ klass->full_flags=resolve_flags(klass->acc_flags,cp);
+ klass->full_name=resolve_classref(klass->this_class,cp);
+ klass->full_super=resolve_classref(klass->super_class,cp);
+ resolve_cp(klass,cp);
+ resolve_all_interfaces(klass,cp);
+ resolve_all_fields(klass,cp);
+ resolve_all_methods(klass,cp);
+ resolve_top_attributes(klass,cp);
+ return errors;
+}
+int process_interfaces(JVClass *klass,JVCPEntry *cp)
+{
+ int i;
+ for(i=0;i<klass->interface_count;i++)
+ {
+ ILColorBold();
+ printf(".implements");
+ ILColorClear();
+ printf(" %s\n",klass->inter_entries[i].full_name);
+ }
+ return OK;
+}
+int process_fields(JVClass *klass,JVCPEntry *cp)
+{
+ int i;
+ for(i=0;i<klass->field_count;i++)
+ {
+ ILColorBold();
+ printf(".field");
+ ILColorClear();
+ printf("%s %s %s\n",klass->field_entries[i].full_flags,
+ klass->field_entries[i].full_name,klass->field_entries[i].full_type);
+ }
+ return OK;
+}
+char* print_string_cp(JVCPEntry *cp,int i)
+{
+ ILColorBold();ILColorYellow();
+ switch(cp[i].type)
+ {
+ case CONSTANT_Utf8:
+ printf("%s",cp[i].un.utf8string);
+ break;
+ case CONSTANT_String:
+ printf("\"%s\"",cp[cp[i].un.strvalue].un.utf8string);
+ break;
+ case CONSTANT_Integer:
+ printf("%d",cp[i].un.intvalue);
+ break;
+ case CONSTANT_Long:
+ printf("%ld",cp[i].un.longvalue);
+ break;
+ case CONSTANT_Float:
+ printf("%f",cp[i].un.floatvalue);
+ break;
+ case CONSTANT_Double:
+ printf("%g",cp[i].un.doublevalue);
+ break;
+ case CONSTANT_Classref:
+ printf("%s",cp[i].un.class_value.full_name);
+ break;
+ case CONSTANT_Fieldref://handle field and methods seperateld
+ printf("%s/%s %s",\
+ cp[i].un.ref_value.full_class,\
+ cp[i].un.ref_value.full_name,\
+ cp[i].un.ref_value.full_type);
+ break;
+ case CONSTANT_Methodref:
+ case CONSTANT_InterfaceMethodref:
+ printf("%s/%s%s",\
+ cp[i].un.ref_value.full_class,\
+ cp[i].un.ref_value.full_name,\
+ cp[i].un.ref_value.full_type);
+ break;
+ case CONSTANT_NameAndType:
+ printf("%s",resolve_name_type(i,cp));
+ break;
+ }
+ ILColorClear();
+}
+int process_byte_code(byte *code,int *_start,int code_len,JVCPEntry *cp)
+{
+ int start=*(_start);
+ //for lookupswitch
+ Int32 key,offset,count,default_offset;
+ int insn_offset=start;
+ int j;
+ ///end for lookupswitch
+ int i=search_opcode_table(code[start]);
+ opcode_table found_code;
+ if(i>=0)
+ {
+ found_code=op_tab[i];
+ //printf(";code offset %d\n",start);
+ ILColorGreen();IF_PRETTY_PRINT(printf("_%d:",start);)
+ ILColorClear();
+ switch(found_code.args)
+ {
+ case NONE:
+ PRINT_OPCODE_NAME(found_code);
+ //printf("\t %s",found_code.name);
+ start=start+1;
+ break;
+ case I:
+ PRINT_OPCODE_NAME(found_code);
+ //printf("\t %s %d",found_code.name,code[start+1]);
+ start=start+2;
+ break;
+ case II:
+ PRINT_OPCODE_NAME(found_code);
+ //printf("\t %s
%d",found_code.name,code[start+1]<<8|code[start+2]);
+ printf("%d",code[start+1]<<8|code[start+2]);
+ start=start+3;
+ break;
+ case FIELD:
+ case METHOD:
+ case CLASS:
+ case BIGCONSTANT:
+ PRINT_OPCODE_NAME(found_code);
+ //printf("\t %s ",found_code.name);
+ print_string_cp(cp,code[start+1]<<8|code[start+2]);
+ start=start+3;
+ break;
+/* case METHOD:
+ printf("\t %s ",found_code.name);
+ print_string_cp(cp,code[start+1]<<8|code[start+2]);
+ start=start+3;
+ break;
+ case CLASS:
+ printf("\t %s ",found_code.name);
+ print_string_cp(cp,code[start+1]<<8|code[start+2]);
+ start=start+2;
+ break;*/
+ case CONSTANT:
+ PRINT_OPCODE_NAME(found_code);
+ //printf("\t %s ",found_code.name);
+ print_string_cp(cp,code[start+1]);
+ start=start+2;
+ break;
+/* case BIGCONSTANT:
+ printf("\t %s ",found_code.name);
+ print_string_cp(cp,code[start+1]<<8|code[start+2]);
+ start=start+3;
+ break;*/
+ case SWITCH://variable length operand
+ PRINT_OPCODE_NAME(found_code);
+ //printf("\t %s ",found_code.name);
+ start=start+1;
+ while(start%4!=0)start++;
+ default_offset=\
+ ((Int32)code[start])<<24 |((Int32)code[start+1]<<16)|\
+ ((Int32)code[start+2]<<8) | ((Int32)code[start+3]);
+ start=start+4;
+ count=\
+ ((Int32)code[start])<<24 |((Int32)code[start+1]<<16)|\
+ ((Int32)code[start+2]<<8) | ((Int32)code[start+3]);
+ start=start+4;
+ printf("; %ld key-values\n",count);
+ for(j=0;j<count;j++)
+ {
+ key= ((Int32)code[start])<<24 |((Int32)code[start+1]<<16)|\
+ ((Int32)code[start+2]<<8) |
((Int32)code[start+3]);
+ start=start+4;
+ offset=((Int32)code[start])<<24 |
((Int32)code[start+1]<<16)|\
+ ((Int32)code[start+2]<<8) | ((Int32)code[start+3]);
+ start=start+4;
+ printf("\t\t%ld\t : %ld\n",key,insn_offset+offset);
+ }
+ printf("\t\tdefault : %ld",insn_offset+default_offset);
+ break;
+ case LABEL:
+ PRINT_OPCODE_NAME(found_code);
+ //printf("\t %s ",found_code.name);
+ printf("%d;code offset ",
+
insn_offset+(Int16)(code[start+1]<<8|code[start+2]));
+ start=start+3;
+ break;
+ default:
+ ILColorBold();ILColorRed();
+ printf("; Unknown instruction %d",code[start]);
+ ILColorClear();
+ start=start+1;
+ }
+ printf("\n");
+ }
+ *(_start)=start;
+}
+int process_method_code(JVMethodEntry *mthd,JVCPEntry *cp)
+{
+ int i;
+ int start=0;
+ byte *code=mthd->attr_entries[mthd->code_index].un.code.code;
+ int codelen=mthd->attr_entries[mthd->code_index].un.code.code_count;
+ ILColorBold();
+ printf(".limit");
+ ILColorClear();
+ printf(" stack %d\n",
+ mthd->attr_entries[mthd->code_index].un.code.max_stack);
+
+ ILColorBold();
+ printf(".limit ");
+ ILColorClear();
+
+ printf("locals %d\n",
+ mthd->attr_entries[mthd->code_index].un.code.max_locals);
+ if((mthd->acc_flags & ACC_ABSTRACT) || (codelen==0))return OK;
+ while(start<codelen)process_byte_code(code,&start,codelen,cp);
+ printf("; TODO: label management\n");
+ printf("; TODO: wide opcode not supported\n");
+ return OK;
+}
+int process_methods(JVClass *klass,JVCPEntry *cp)
+{
+ int i;
+ for(i=0;i<klass->methods_count;i++)
+ {
+ printf(".method %s %s%s\n",klass->method_entries[i].full_flags,\
+ klass->method_entries[i].full_name,\
+ klass->method_entries[i].full_type);
+ process_method_code(&(klass->method_entries[i]),cp);
+ printf(".end method\n");
+ }
+}
+int process_class(JVClass *klass,JVCPEntry *cp)
+{
+ printf(".class %s %s\n",klass->full_flags,klass->full_name);
+ printf(".super %s\n",klass->full_super);
+ process_interfaces(klass,cp);
+ process_fields(klass,cp);
+ process_methods(klass,cp);
+ return OK;
+}
+void usage()
+{
+ printf("JDASM 0.0.7 - Java Disassembler\n");
+ printf("Usage : jdasm [options] <file.class>\n\n");
+ printf("Options\n");
+ printf("\t--pretty or -p\n\t pretty print\n");
+ printf("\t--version or -v\n\t version \n");
+ printf("\t--help or -h\n\t this help screen\n");
+}
+void version()
{
- FILE *fp;
- JVClass *klass;
- if(argc <= 1)
- {
- usage();
- return ERROR;
- }
- while(argv[1][0] == '-' && argc > 1)
- {
- if(strcmp(argv[1], "--version") == 0)
+printf("JDASM 0.0.7 - Java Disassembler\n");
+printf("Copyright (c) 2002 Free Software Foundation India Ltd.\n\n");
+printf("JDASM comes with ABSOLUTELY NO WARRANTY. This is free software,\n");
+printf("and you are welcome to redistribute it under the terms of the \n");
+printf("GNU General Public License.\n\n");
+printf("Use the `--help' option to get help on the command-line options.\n");
+}
+int main(int argc,char *argv[])
+{
+ FILE *fp;
+ JVClass *klass;
+ DEBUG_OUT=fopen("/tmp/jdasm.log","w");
+ if(argc<=1)
+ {
+ usage();
+ return 1;
+ }
+ while(argv[1][0]=='-' && argc > 1)
+ {
+ if((strcmp(argv[1],"-p")==0) || (strcmp(argv[1],"--pretty")==0))
+ pretty_print=1;
+ else if(strcmp(argv[1],"--help")==0 || strcmp(argv[1],"-h")==0)
+ {
+ usage();
+ return 0;
+ }
+ else if(strcmp(argv[1],"--version")==0 ||
strcmp(argv[1],"-v")==0)
{
version();
return 0;
- } else if(strcmp(argv[1], "--help") == 0)
+ }
+ else
{
- usage();
+ fprintf(stderr,"Unknown Option %s \n",argv[1]);
+ fprintf(stderr,"Try --help for valid options \n");
return 0;
- } else
- {
- fprintf(stderr, "Unknown option: %s\n", argv[1]);
- fprintf(stderr, "Try --help for valid options.\n");
- return 1;
}
- argv++;
- argc--;
- }
- fp = fopen(argv[1], "rb");
- if(fp == NULL)
- {
- fprintf(stderr, "Cannot open file: %s\n", argv[1]);
- return 2;
- }
- klass = (JVClass *)calloc(1, sizeof(JVClass));
- if(read_class(fp, klass) != OK)
- {
- fprintf(stderr, "Cannot read file: %s\n", argv[1]);
- fclose(fp);
- return 3;
- }
- resolve_class(klass, klass->cp_entries);
- print_class(klass, klass->cp_entries);
- return 0;
+ argv++;argc--;
+ }
+ if(argc<1)
+ {
+ usage();
+ return 1;
+ }
+ fp=fopen(argv[1],"rb");
+ if(fp==NULL)
+ {
+ fprintf(DEBUG_OUT,"Cannot read %s\n",argv[1]);
+ return ERROR;
+ }
+ klass=(JVClass*)calloc(1,sizeof(JVClass));
+ if(read_class(fp,klass)==ERROR)return ERROR;
+ resolve_class(klass,klass->cp_entries);
+ process_class(klass,klass->cp_entries);
+ //must implement destroy class functions
+ return OK;
}
+
Index: jdasm.h
===================================================================
RCS file: /cvsroot/jilc/jilc/src/jdasm.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- jdasm.h 27 Feb 2002 04:30:58 -0000 1.8
+++ jdasm.h 22 Apr 2002 09:12:37 -0000 1.9
@@ -1,5 +1,5 @@
/**
- * jdasm.h -- Deassembler header file.
+ * jdasm.h -- Deassembler / Parser header file.
*
* Author: Gaurav Vaish <address@hidden>
* Gopal V (address@hidden)
@@ -10,68 +10,308 @@
#ifndef __JDASM_H
#define __JDASM_H
-#include <jparser.h>
+#include <jopcodes.h>
-#define PRINT_OP_NAME(x) printf(" %s ", (x).mnemonic)
+#define OK 0
+#define ERROR 1
-/*
-#define READ_INT32(code,start) ( (((Int32)code[start]) << 0x18) | \
- (((Int32)code[start + 1])
<< 0x10) | \
- (((Int32)code[start + 2])
<< 0x08) | \
- ((Int32)code[start + 3]) )
-*/
-//hoping these work ! ;-)
-#define READ_INT32(code,start) ( (Int32)((((Int32)code[start] ) << 0x18) | \
- (((Int32)code[start + 1] )<< 0x10) | \
- (((Int32)code[start + 2] )<< 0x08) | \
- (((Int32)code[start + 3] ) )) )
-
-#define READ_UINT32(code,start) ((UInt32)((((UInt32)code[start] ) << 0x18) | \
- (((UInt32)code[start + 1] )<< 0x10) |
\
- (((UInt32)code[start + 2] )<< 0x08) |
\
- (((UInt32)code[start + 3] ) )) )
-
-/*
-#define READ_INT16(code,start) ( (((Int16)code[start]) << 0x08 | \
- (Int16)code[start+1]) )
-*/
-
-#define READ_INT16(code,start) (Int16) ((((Int16)code[start] << 0x08) | \
- ((Int16)code[start + 1])) )
-
-#define READ_UINT16(code,start) (UInt16)(((UInt16)code[start] << 0x08) | \
- ((UInt16)code[start + 1]) )
-/**
- * Methods to help printing the deassmbled code.
- */
-char *array_types[]=
-{
- "JUNK 0",
- "JUNK 1",
- "JUNK 2",
- "JUNK 3",
- "boolean",//4
- "char",//5
- "float",//6
- "double",//7
- "byte",//8
- "short",//9
- "int",//10
- "long"//11
-};
-void print_interfaces(JVClass *klass, JVCPEntry *cp_entry);
-void print_fields(JVClass *klass, JVCPEntry *cp_entry);
-void print_string_cp(JVCPEntry *cp_entry, unsigned int i);
-void print_byte_code(byte *code, int *start_index, int code_len, int
*wide,UInt32 * jump_points, JVCPEntry *cp_entry);
-void print_method_code(JVMethodEntry *method, JVCPEntry *cp_entry);
-void print_methods(JVClass *klass, JVCPEntry *cp_entry);
-void print_class(JVClass *klass, JVCPEntry *cp_entry);
-
-/* exception handling */
-void print_method_throws(JVMethodEntry *method,JVCPEntry *cp_entry);
-void mark_try_catch_blocks(JVAttributeEntry *code,int codelen, UInt32
*jump_points,JVCPEntry *cp_entry);
-/* label management */
-UInt32 * get_jump_points(byte *code,int codelen);
-void usage(void);
+typedef unsigned char byte;
+typedef unsigned char UInt8;
+typedef unsigned short UInt16;
+typedef unsigned int UInt32;
+typedef unsigned long long UInt64;
-#endif __JDASM_H
+typedef short Int16;
+typedef int Int32;
+typedef long long Int64;
+
+typedef struct
+{
+ byte* data;
+ UInt32 next;
+ UInt32 left;
+} jbuffer;
+
+/**
+ * Constant Pool Entries : Values
+ */
+
+#define UTF8 1
+#define INTEGER 3
+#define FLOAT 4
+#define LONG 5
+#define DOUBLE 6
+#define CLASSREF 7
+#define STRING 8
+#define FIELDREF 9
+#define METHODREF 10
+#define INTERFACEMETHODREF 11
+#define NAMEANDTYPE 12
+
+/**
+ * Contant Pool Entries Table : Literal Strings
+ */
+
+char* CPTable[] = {
+ "Junk",
+ "CONSTANT_Utf8",
+ "Junk",
+ "CONSTANT_Integer",
+ "CONSTANT_Float",
+ "CONSTANT_Long",
+ "CONSTANT_Double",
+ "CONSTANT_Class",
+ "CONSTANT_String",
+ "CONSTANT_Field",
+ "CONSTANT_Method",
+ "CONSTANT_InterfaceMethod",
+ "CONSTANT_NameAndType",
+ "Junk",
+ "Junk",
+ "Junk"
+}
+
+/**
+ * Attribute Types
+ */
+
+#define ATTRIBUTE_TOP 0
+#define ATTRIBUTE_FIELD 1
+#define ATTRIBUTE_METHOD 2
+#define ATTRIBUTE_CODE 3
+
+/**
+ * Access Type (Flags)
+ */
+
+#define ACCESS_PUBLIC 0x0001
+#define ACCESS_PRIVATE 0x0002
+#define ACCESS_PROTECTED 0x0004
+#define ACCESS_STATIC 0x0008
+#define ACCESS_FINAL 0x0010
+#define ACCESS_SYNCHRONIZED 0x0020
+#define ACCESS_VOLATILE 0x0040
+#define ACCESS_TRANSIENT 0x0080
+#define ACCESS_NATIVE 0x0100
+#define ACCESS_ABSTRACT 0x0400
+
+/**
+ * Java Constant Pool Entry structure
+ */
+
+typedef struct
+{
+ UInt8 type;
+ UInt16 length;
+ UInt8 skip;
+ union
+ {
+ char *utf8string;
+ Int32 intvalue;
+ Int64 longvalue;
+ float floatvalue;
+ double doublevalue;
+ UInt32 strvalue;
+ struct
+ {
+ UInt32 name_index;
+ char *full_name;
+ } class_value;
+ struct
+ {
+ UInt32 class_index;
+ UInt32 name_type;
+ char *full_class;
+ char *full_name;
+ char *full_type;
+ } ref_value;
+ struct
+ {
+ UInt32 name_index;
+ UInt32 type_index;
+ char *full_name;
+ char *full_type;
+ } name_type;
+ } values;
+} JVCPEntry;
+
+/**
+ * Java Exception Handler structure
+ */
+
+typedef struct
+{
+ UInt16 start_pc;
+ UInt16 end_pc;
+ UInt16 handler_pc;
+ UInt16 catch_type;
+} JVExceptionHandler;
+
+/**
+ * Java Exception structure
+ */
+
+typedef struct
+{
+ UInt16 class_index;
+ char *class_name;
+} JVException;
+
+/**
+ * Java Attribute Entry structure
+ */
+
+typedef struct
+{
+ UInt16 name_index;
+ UInt32 byte_count;
+ UInt8 type;
+ jbuffer *buf;
+ union
+ {
+ struct
+ {
+ UInt16 source_index;
+ char *full_source;
+ } source;
+ struct
+ {
+ UInt16 except_count;
+ JVException *excepts;
+ } exception;
+ struct
+ {
+ UInt16 max_stack;
+ UInt16 max_locals;
+ UInt32 code_count;
+ byte *code;
+ UInt16 handler_count;
+ JVExceptionHandler *handlers;
+ UInt16 attr_count;
+ byte *attributes;
+ } code;
+ } attributes;
+} JVAttributeEntry;
+
+/**
+ * Java Field Entry structure
+ */
+
+typedef struct
+{
+ UInt16 acc_flags;
+ UInt16 name_index;
+ UInt16 type_index;
+ UInt16 attr_count;
+ JVAttributeEntry *attr_entries;
+ char *full_flags;
+ char *full_name;
+ char *full_type;
+} JVFieldEntry;
+
+/**
+ * Java Interface Entry structure
+ */
+
+typedef struct
+{
+ UInt16 index;
+ char *full_name;
+} JVInterfaceEntry;
+
+/**
+ * Java Method Entry structure
+ */
+
+typedef struct
+{
+ UInt16 acc_flags;
+ UInt16 name_index;
+ UInt16 type_index;
+ UInt16 attr_count;
+ JVAttributeEntry *attr_entries;
+ UInt16 code_index;
+ UInt16 except_index;
+ char *full_flags;
+ char *full_name;
+ char *full_type;
+} JVMethodEntry;
+
+/**
+ * Java Class structure
+ */
+
+typedef struct
+{
+ UInt32 magic;
+ UInt16 version_minor;
+ UInt16 version_major;
+ UInt16 cp_count;
+ JVCPEntry *cp_entries;
+ UInt16 acc_flags;
+ UInt16 this_class;
+ UInt16 super_class;
+ UInt16 interface_count;
+ JVInterfaceEntry *interface_entries;
+ UInt16 field_count;
+ JVFieldEntry *field_entries;
+ UInt16 method_count;
+ JVMethodEntry *method_entries;
+ UInt16 attr_count;
+ JVAttributeEntry *attr_entries;
+} JVClass;
+
+/**
+ * File reader methods
+ */
+
+inline UInt8 read_byte(FILE *fp);
+inline UInt16 read_uint16(FILE *fp);
+inline UInt32 read_uint32(FILE *fp);
+inline UInt64 read_uint64(FILE *fp);
+
+inline void skip_bytes(FILE *fp);
+
+byte buffer_read_byte(jbuffer *buffer);
+inline UInt16 buffer_read_uint16(jbuffer *buffer);
+inline UInt32 buffer_read_uint32(jbuffer *buffer);
+
+void buffer_skip_bytes(jbuffer *buffer, UInt32 length);
+
+/**
+ * Parser Methods (provide values to JVClass structure entries)
+ */
+
+int read_cp_entry(FILE *fp, JVCPEntry *cp_entry);
+int read_cp(FILE *fp, JVClass *klass);
+int read_flags(FILE *fp, JVClass *klass);
+int read_interfaces(FILE *fp, JVClass *klass);
+
+JVAttributeEntry* read_attributes(FILE *fp, int count, int type);
+int read_fields(FILE *fp, JVClass *klass)
+int read_methods(FILE *fp, JVClass *klass);
+int read_class(FILE *fp, JVClass *klass);
+
+/**
+ * Resolving methods (resolve all entries in the class)
+ */
+
+char* resolve_utf8(UInt16 index, JVCPEntry *cp_entry);
+char* resolve_string(UInt16 index, JVCPEntry *cp_entry);
+char* resolve_classref(UInt16 index, JVCPEntry *cp_entry);
+
+JVCPEntry* resolve_name_type(UInt16 index, JVCPEntry *cp_entry);
+JVCPEntry* resolve_ref(UInt16 index, JVCPEntry *cp_entry);
+
+int resolve_cp(JVClass *klass, JVCPEntry *cp_entry);
+char* resolve_flags(UInt16 flags);
+
+int resolve_all_interfaces(JVClass *klass, JVCPEntry *cp_entry);
+int process_source_attribute(JVAttributeEntry *attr_entry, JVCPEntry
*cp_entry);
+int resolve_top_attributes(JVClass *klass, JVCPEntry *cp_entry);
+int resolve_field(JVFieldEntry *field_entry, JVCPEntry *cp_entry);
+int resolve_all_fields(JVFieldEntry *field_entry, JVCPEntry *cp_entry);
+int process_methodcode_attribute(JVAttributeEntry *code, JVCPEntry *cp_entry);
+int resolve_all_method_attributes(JVMethodEntry *method, JVCPEntry *cp_entry);
+
+#endif
\ No newline at end of file
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Jilc-patches] CVS: jilc/src jdasm.c,1.6,1.7 jdasm.h,1.8,1.9,
Gaurav Vaish <address@hidden> <=