jdk/test/java/lang/instrument/ilib/ClassDump.java
changeset 2 90ce3da70b43
child 5506 202f599c92aa
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    21  * have any questions.
       
    22  */
       
    23 
       
    24 package ilib;
       
    25 
       
    26 import java.io.IOException;
       
    27 import java.io.File;
       
    28 import java.io.FileOutputStream;
       
    29 import java.io.DataOutputStream;
       
    30 import java.io.PrintStream;
       
    31 import java.io.PrintWriter;
       
    32 import java.io.CharArrayWriter;
       
    33 import java.util.List;
       
    34 import java.util.Iterator;
       
    35 import java.util.ArrayList;
       
    36 
       
    37 public class ClassDump implements RuntimeConstants {
       
    38 
       
    39   public static void dump(Options opt,
       
    40                                        ClassLoader loader,
       
    41                                        String className,
       
    42                                        byte[] classfileBuffer) {
       
    43     ClassReaderWriter c = new ClassReaderWriter(classfileBuffer);
       
    44     (new ClassDump(className, c)).doit();
       
    45   }
       
    46 
       
    47     static boolean verbose = true;
       
    48 
       
    49     final String className;
       
    50     final ClassReaderWriter c;
       
    51     private final PrintStream output;
       
    52 
       
    53     int constantPoolCount;
       
    54     int methodsCount;
       
    55 
       
    56     ClassDump(String className, ClassReaderWriter c) {
       
    57         this.className = className;
       
    58         this.c = c;
       
    59         this.output = System.err;
       
    60     }
       
    61 
       
    62     void doit() {
       
    63         int i;
       
    64         c.copy(4 + 2 + 2); // magic min/maj version
       
    65         constantPoolCount = c.copyU2();
       
    66         // copy old constant pool
       
    67         c.copyConstantPool(constantPoolCount);
       
    68 
       
    69         traceln("ConstantPool size: " + constantPoolCount);
       
    70 
       
    71         c.copy(2 + 2 + 2);  // access, this, super
       
    72         int interfaceCount = c.copyU2();
       
    73         traceln("interfaceCount: " + interfaceCount);
       
    74         c.copy(interfaceCount * 2);
       
    75         copyFields(); // fields
       
    76         copyMethods(); // methods
       
    77         int attrCount = c.copyU2();
       
    78         traceln("class attrCount: " + attrCount);
       
    79         // copy the class attributes
       
    80         copyAttrs(attrCount);
       
    81     }
       
    82 
       
    83 
       
    84     void copyFields() {
       
    85         int count = c.copyU2();
       
    86         if (verbose) {
       
    87             System.out.println("fields count: " + count);
       
    88         }
       
    89         for (int i = 0; i < count; ++i) {
       
    90             c.copy(6); // access, name, descriptor
       
    91             int attrCount = c.copyU2();
       
    92             if (verbose) {
       
    93                 System.out.println("field attr count: " + attrCount);
       
    94             }
       
    95             copyAttrs(attrCount);
       
    96         }
       
    97     }
       
    98 
       
    99     void copyMethods() {
       
   100         methodsCount = c.copyU2();
       
   101         if (verbose) {
       
   102             System.out.println("methods count: " + methodsCount);
       
   103         }
       
   104         for (int i = 0; i < methodsCount; ++i) {
       
   105             copyMethod();
       
   106         }
       
   107     }
       
   108 
       
   109     void copyMethod() {
       
   110         int accessFlags = c.copyU2();// access flags
       
   111         int nameIndex = c.copyU2();  // name
       
   112         checkIndex(nameIndex, "Method name");
       
   113         String methodName = c.constantPoolString(nameIndex);
       
   114         traceln("method: " + methodName);
       
   115         int descriptorIndex = c.copyU2();                  // descriptor
       
   116         checkIndex(descriptorIndex, "Method descriptor");
       
   117         int attrCount = c.copyU2();  // attribute count
       
   118         if (verbose) {
       
   119             System.out.println("method attr count: " + attrCount);
       
   120         }
       
   121         for (int i = 0; i < attrCount; ++i) {
       
   122             copyAttrForMethod(methodName, accessFlags);
       
   123         }
       
   124     }
       
   125 
       
   126     void copyAttrs(int attrCount) {
       
   127         for (int i = 0; i < attrCount; ++i) {
       
   128             copyAttr();
       
   129         }
       
   130     }
       
   131 
       
   132     void copyAttr() {
       
   133         c.copy(2);             // name
       
   134         int len = c.copyU4();  // attr len
       
   135         if (verbose) {
       
   136             System.out.println("attr len: " + len);
       
   137         }
       
   138         c.copy(len);           // attribute info
       
   139     }
       
   140 
       
   141     void copyAttrForMethod(String methodName, int accessFlags) {
       
   142         int nameIndex = c.copyU2();   // name
       
   143         // check for Code attr
       
   144         checkIndex(nameIndex, "Method attr name");
       
   145         if (nameIndex == c.codeAttributeIndex) {
       
   146             try {
       
   147                 copyCodeAttr(methodName);
       
   148             } catch (IOException exc) {
       
   149                 System.err.println("Code Exception - " + exc);
       
   150                 System.exit(1);
       
   151             }
       
   152         } else {
       
   153             int len = c.copyU4();     // attr len
       
   154             traceln("method attr len: " + len);
       
   155             c.copy(len);              // attribute info
       
   156         }
       
   157     }
       
   158 
       
   159     void copyAttrForCode() throws IOException {
       
   160         int nameIndex = c.copyU2();   // name
       
   161 
       
   162         checkIndex(nameIndex, "Code attr name");
       
   163         int len = c.copyU4();     // attr len
       
   164         traceln("code attr len: " + len);
       
   165         c.copy(len);              // attribute info
       
   166     }
       
   167 
       
   168     void copyCodeAttr(String methodName) throws IOException {
       
   169         traceln("Code attr found");
       
   170         int attrLength = c.copyU4();        // attr len
       
   171         checkLength(attrLength, "Code attr length");
       
   172         int maxStack = c.readU2();          // max stack
       
   173         c.copyU2();                         // max locals
       
   174         int codeLength = c.copyU4();        // code length
       
   175         checkLength(codeLength, "Code length");
       
   176 
       
   177         copyExceptionTable();
       
   178 
       
   179         int attrCount = c.copyU2();
       
   180         checkLength(attrCount, "Code attr count");
       
   181         for (int i = 0; i < attrCount; ++i) {
       
   182             copyAttrForCode();
       
   183         }
       
   184     }
       
   185 
       
   186     /**
       
   187      * Copy the exception table for this method code
       
   188      */
       
   189     void copyExceptionTable() throws IOException {
       
   190         int tableLength = c.copyU2();   // exception table len
       
   191         checkLength(tableLength, "Exception Table length");
       
   192         if (tableLength > 0) {
       
   193             traceln();
       
   194             traceln("Exception table:");
       
   195             traceln(" from:old/new  to:old/new target:old/new type");
       
   196             for (int tcnt = tableLength; tcnt > 0; --tcnt) {
       
   197                 int startPC = c.readU2();
       
   198                 int endPC = c.readU2();
       
   199                 int handlerPC = c.readU2();
       
   200                 int catchType = c.copyU2();
       
   201                 if (verbose) {
       
   202                     traceFixedWidthInt(startPC, 6);
       
   203                     traceFixedWidthInt(endPC, 6);
       
   204                     traceFixedWidthInt(handlerPC, 6);
       
   205                     trace("    ");
       
   206                     if (catchType == 0)
       
   207                         traceln("any");
       
   208                     else {
       
   209                         traceln("" + catchType);
       
   210                     }
       
   211                 }
       
   212             }
       
   213         }
       
   214     }
       
   215 
       
   216     private void checkIndex(int index, String comment) {
       
   217         if (index > constantPoolCount) {
       
   218             output.println("ERROR BAD INDEX " + comment + " : " + index);
       
   219         } else {
       
   220             traceln(comment + " : " + index);
       
   221         }
       
   222     }
       
   223 
       
   224     private void checkLength(int length, String comment) {
       
   225         if (length > c.inputBytes().length) {
       
   226             output.println("ERROR BAD LENGTH " + comment + " : " + length);
       
   227         } else {
       
   228             traceln(comment + " : " + length);
       
   229         }
       
   230     }
       
   231 
       
   232     private void trace(String str) {
       
   233         if (verbose) {
       
   234             output.print(str);
       
   235         }
       
   236     }
       
   237 
       
   238     private void traceln(String str) {
       
   239         if (verbose) {
       
   240             output.println(str);
       
   241         }
       
   242     }
       
   243 
       
   244     private void traceln() {
       
   245         if (verbose) {
       
   246             output.println();
       
   247         }
       
   248     }
       
   249 
       
   250     private void trace(int i) {
       
   251         if (verbose) {
       
   252             output.print(i);
       
   253         }
       
   254     }
       
   255 
       
   256     /**
       
   257      * Print an integer so that it takes 'length' characters in
       
   258      * the output.  Temporary until formatting code is stable.
       
   259      */
       
   260     private void traceFixedWidthInt(int x, int length) {
       
   261         if (verbose) {
       
   262             CharArrayWriter baStream = new CharArrayWriter();
       
   263             PrintWriter pStream = new PrintWriter(baStream);
       
   264             pStream.print(x);
       
   265             String str = baStream.toString();
       
   266             for (int cnt = length - str.length(); cnt > 0; --cnt)
       
   267                 trace(" ");
       
   268             trace(str);
       
   269         }
       
   270     }
       
   271 
       
   272 
       
   273 }