/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): */ /******************************************************************** * * classdump.h * * author: Patrick Dionisio * * purpose: Header file for classdump.c * ********************************************************************/ /*Variables.*/ /*linked_list stores the index and the name of a string in the constant_pool.*/ struct linked_list { int index; char name[255]; struct linked_list *next_ptr; }; /******************************************************************** * * function: void printTab(int i) * * purpose: Used for standout format. Prints out tabs * in by the number of i. * *********************************************************************/ void printTab(int i) { int j; for (j=0; j>4)&15]); printByte(hex[i&15]); } /******************************************************************** * * function: void printHex2(int i) * * purpose: Prints out the hexidecimal value of two bytes. * * *********************************************************************/ void printHex2(int i) { /*Print high-byte.*/ printHex1(i>>8); /*Print low-byte.*/ printHex1(i&0xff); } /******************************************************************** * * function: void printHex4(int i) * * purpose: Prints out the hexidecimal value of four bytes. * * *********************************************************************/ void printHex4(int i) { /*Print out the first two bytes.*/ printHex2(i>>16); /*Print out the next two bytes.*/ printHex2(i&0xffff); } /******************************************************************** * * function: void printDec4(int i) * * purpose: Prints out the decimal value of four bytes. * * *********************************************************************/ void printDec4(int i) { int k,j=1; /*Check if i is negative. If it is, then print out a '-' and make i positive.*/ if ( i < 0 ) { putc('-',stdout); i = -i; } /*Print out the bytes.*/ k = i; while ( k /= 10 ) j *= 10; while (j) { k = i/j; printByte(k+'0'); i -= k*j; j /= 10; } } /******************************************************************** * * function: void printDec2(int i) * * purpose: Prints out the decimal value of the two bytes. * * *********************************************************************/ void printDec2(int i) { printDec4(i&0xffff); } /******************************************************************** * * function: int printDec1(int i) * * purpose: Prints out the decimal value of the one byte. * * *********************************************************************/ void printDec1(int i) { printDec4(i&0xff); } /******************************************************************** * * function: char * getName(struct linked_list *first_ptr,int index) * * purpose: Returns the name stored in the given index from the * constant_pool. * *********************************************************************/ char* getName(struct linked_list *first_ptr,int index) { /*The pointer to use in going through the linked list.*/ struct linked_list *current_ptr = NULL; current_ptr = first_ptr; /*Find the name in the list.*/ while ( current_ptr != NULL ) { if ( (*current_ptr).index == index ) return (*current_ptr).name; else current_ptr = (*current_ptr).next_ptr; } return "Error in getName"; } /******************************************************************** * * function: void freeList(struct linked_list *first_ptr) * * purpose: Frees up the allocated memory. * * *********************************************************************/ void freeList(struct linked_list *first_ptr) { /*The pointer to use in going through the linked list.*/ struct linked_list *current_ptr = NULL; current_ptr = first_ptr; /*Go through and clean the list.*/ while ( first_ptr != NULL ) { current_ptr = (*current_ptr).next_ptr; free(first_ptr); first_ptr = current_ptr; } } /******************************************************************** * * function: char* getBytecode(int i, FILE *input) * * purpose: Prints the bytecode value. * * *********************************************************************/ void getBytecode(int i, FILE *input) { /*Local variables.*/ int nested[10]; int j,k,l,m,n,o; int posn = 0; /*Index for nested.*/ int posf = 0; /*Current length of code.*/ /*Reference type table.*/ static char typ[256] = { /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ /*0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*1*/ 1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /*2*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*3*/ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /*4*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*5*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*6*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*7*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*8*/ 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*9*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, /*a*/ 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 7, 8, 0, 0, 0, 0, /*b*/ 0, 0, 2, 2, 2, 2, 2, 2, 2, 9,10, 2, 0, 2, 0, 0, /*c*/ 2, 2, 0, 0,11, 5, 2, 2, 3, 3, 0, 0, 0, 2, 0, 0, /*d*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*f*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; l=posf; j=posf+i; posn++; /*Print out bytecodes till the length has been reached.*/ while (posf0xd2) k=0xd2; /*Refer to the type table and print out the correct bytecode along with any values.*/ switch (typ[k]) { case 0: printf(mnem[k]); break; case 1: m=getu1(input); printf(mnem[k]); printf(" "); printHex1(m); posf++; break; case 2: m=getu2(input); printf(mnem[k]); printf(" "); printHex2(m); posf = posf + 2; break; case 3: m=getu4(input); printf(mnem[k]); printf(" "); printHex4(m); posf = posf + 4; break; case 4: m=getu1(input); n=getu1(input); printf(mnem[k]); printf(" "); printHex1(m); printf(","); printHex1(n); posf = posf + 2; break; case 5: m=getu2(input); n=getu1(input); printf(mnem[k]); printf(" "); printHex2(m); printf(","); printHex1(n); posf = posf + 3; break; case 6: m=getu2(input); printf(mnem[k]); printf(" "); printHex2(m+nested[posn]); posf = posf + 2; break; case 7: /*Special case for tableswitch*/ /*Read and ignore padded bytes.*/ for (m=(nested[posn]&3)^3; m>0; m--) { getu1(input); posf++; } m=getu4(input); n=getu4(input); o=getu4(input); posf = posf + 12; printf(mnem[k]); printTab(1); printHex4(m+nested[posn]); printf(","); printHex4(n); printf(","); printHex2(o); posn++; nested[posn]=n; /*Print jump-offsets.*/ while (nested[posn] <= o) { m=getu4(input); printf("\n"); printTab(6); posf = posf + 4; printHex4(m+nested[posn-1]); nested[posn]++; } posn--; printf("\n"); break; case 8: /*Special case for lookupswitch. */ /*Read and ignore padded bytes.*/ for (m=(nested[posn]&3)^3; m>0; m--) { getu1(input); posf++; } m=getu4(input); n=getu4(input); posf = posf + 8; printf(mnem[k]); printTab(1); printHex4(m+nested[posn]); printf(","); printHex4(n); printf("\n"); printTab(6); posn++; nested[posn]=0; /*Print out offset pairs.*/ while (nested[posn] < n) { m=getu4(input); o=getu4(input); posf = posf + 8; printHex4(m); printf(" : "); printHex4(o+nested[posn-1]); nested[posn]++; printf("\n"); printTab(6); } posn--; printf("\n"); break; case 9: m=getu2(input); n=getu1(input); o=getu1(input); posf = posf + 4; printf(mnem[k]); printf(" "); printHex2(m); printf(","); printHex1(n); printf(","); printHex1(o); break; case 10: m=getu1(input); posf++; printf(mnem[k]); printf(" "); switch (m) { case 4: printf("T_BOOLEAN"); break; case 5: printf("T_CHAR"); break; case 6: printf("T_FLOAT"); break; case 7: printf("T_DOUBLE"); break; case 8: printf("T_BYTE"); break; case 9: printf("T_SHORT"); break; case 10: printf("T_INT"); break; case 11: printf("T_LONG"); break; default: printf("\nError"); } break; case 11: m=getu1(input); n=getu1(input); posf = posf + 2; if ( n<0x15 || (n>0x19 && n<0x36) || (n>0x3a && n!=0x84)) printf("\nError"); m=(m<<8)+getu1(input); posf++; printf(mnem[n]); printf(" "); printHex2(m); break; default: printf("\nError"); } } if (posf!=j) printf("\nError"); posn--; printf("\n"); } /******************************************************************** * * function: int whichAttribute(char *constant_pool_name) * * purpose: Returns the attribute of the passed string. * * *********************************************************************/ int whichAttribute(char *constant_pool_name) { if ( strcmp("SourceFile",constant_pool_name) == 0 ) return SOURCE_FILE; if ( strcmp("ConstantValue",constant_pool_name) == 0 ) return CONSTANT_VALUE; if ( strcmp("Code",constant_pool_name) == 0 ) return CODE; if ( strcmp("Exceptions",constant_pool_name) == 0 ) return EXCEPTIONS; if ( strcmp("LineNumberTable",constant_pool_name) == 0 ) return LINENUMBERTABLE; if ( strcmp("LocalVariableTable",constant_pool_name) == 0 ) return LOCALVARIABLETABLE; } /******************************************************************** * * function: void getAttributes(int attr, FILE *input, struct linked_list *first_ptr) * * purpose: Prints out the attribute info. * * *********************************************************************/ void getAttributes(int attr, FILE *input, struct linked_list *first_ptr) { /*Local variables.*/ int length = 0; int k = 0; int count = 0; int index = 0; /*Print out the appropriate attribute. Refer to the JVM Spec for more info.*/ switch (attr) { case SOURCE_FILE: printf("SourceFile"); printf(" length "); printDec4(getu4(input)); printf(" index "); printDec2(getu2(input)); break; case CONSTANT_VALUE: printf("ConstantValue"); printf(" length "); printDec4(getu4(input)); printf(" index "); printDec2(getu2(input)); break; case CODE: printf("Code"); printf("\n"); printTab(2); printf("length"); printTab(2); printDec4(getu4(input)); printf("\n"); printTab(2); printf("max_stack"); printTab(1); printDec2(getu2(input)); printf("\n"); printTab(2); printf("max_local"); printTab(1); printDec2(getu2(input)); printf("\n"); printTab(2); printf("length"); printTab(2); length = getu4(input); printDec4(length); /*Print out the bytecodes.*/ printf("\n\t\tbytecode"); getBytecode(length,input); printf("\n"); printTab(2); printf("exceptions"); length = getu2(input); printTab(1); printDec2(length); for ( k=0; k < length; k++ ) { printf("\n"); printTab(4); printf("exception %i",k); printf("\n"); printTab(4); printf("start_pc: "); printDec2(getu2(input)); printf("end_pc: "); printDec2(getu2(input)); printf("handler_pc: "); printDec2(getu2(input)); printf("catch_type: "); printDec2(getu2(input)); } printf("\n"); printTab(2); printf("attributes"); printTab(1); count = getu2(input); printDec2(count); for ( k=0; k