dmose%mozilla.org 2ccab49e6d updating license boilerplate to xPL v1.1
git-svn-id: svn://10.0.0.236/trunk@52526 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-02 06:38:29 +00:00

702 lines
15 KiB
C

/* -*- 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<i; j++ ) printf("\t");
}
/********************************************************************
*
* function: void printByte(int i)
*
* purpose: Prints out the byte from the integer passed.
*
*
*********************************************************************/
void printByte(int i)
{
putc(i,stdout);
}
/********************************************************************
*
* function: void printHex1(int i)
*
* purpose: Prints out the hexidecimal value of one byte.
*
*
*********************************************************************/
void printHex1(int i)
{
/*hex[] stores all hex values.*/
static char hex[] = { '0','1','2','3','4','5','6','7','8','9','a',
'b','c','d','e','f' };
/*Print our the byte.*/
printByte(hex[(i>>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 (posf<j)
{
printf("\n");
printTab(4);
nested[posn]=posf-l;
/*Get opcode.*/
k=getu1(input);
posf++;
/*Check if opcode is valid.*/
if (k>0xd2) 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<count; k++ )
{
index = getu2(input);
switch(whichAttribute(getName(first_ptr,index)))
{
case LINENUMBERTABLE:
getAttributes(LINENUMBERTABLE,input,first_ptr);
printf("\n");
break;
case LOCALVARIABLETABLE:
getAttributes(LOCALVARIABLETABLE,input,first_ptr);
printf("\n");
break;
default: /*Ignore.*/
for ( length=0; length < getu4(input); length++ ) getu1(input);
}
}
break;
case EXCEPTIONS:
printf("Exceptions");
length = getu4(input);
printDec4(length);
for ( k=0; k < length; k++ ) getu1(input);
break;
case LINENUMBERTABLE:
printf("\n");
printTab(4);
printf("LineNumberTable ");
printDec4(getu4(input));
length = getu2(input);
for ( k=0; k < length; k++ )
{
printf("\n");
printTab(4);
printf("%i",k);
printf(" start ");
printDec2(getu2(input));
printf(" line ");
printDec2(getu2(input));
}
break;
case LOCALVARIABLETABLE:
printf("\n");
printTab(4);
printf("LocalVariableTable ");
printDec4(getu4(input));
length = getu2(input);
for ( k=0; k < length; k++ )
{
printf("\n");
printTab(4);
printf("%i",k);
printf(" start ");
printDec2(getu2(input));
printf(" length ");
printDec2(getu2(input));
printf(" name ");
printDec2(getu2(input));
printf(" descriptor ");
printDec2(getu2(input));
printf(" index ");
printDec2(getu2(input));
}
break;
default:
printf("\nError in Attribute");
exit(0);
}
}