classfile

This commit is contained in:
Imgaojp 2017-02-18 14:24:15 +08:00
parent ce66f8c134
commit cacf9b8226
11 changed files with 768 additions and 1 deletions

View File

@ -1,5 +1,6 @@
package com.gabongao.jvm;
import com.gabongao.jvm.classfile.ClassFile;
import com.gabongao.jvm.classpath.ClassPath;
import java.io.File;
@ -41,11 +42,13 @@ public class Jvm {
startJvm(cmd);
}
}
private static void startJvm(Cmd cmd) {
public static void startJvm(Cmd cmd) {
/* ch01
System.out.printf("classpath: %s class: %s args:%s\n", cmd.getCpOption(), cmd.getClassName(), Arrays.asList(cmd.getArgs()).toString());
*/
/* ch02
ClassPath cp = new ClassPath();
cp.parse(cmd.jreOption, cmd.cpOption);
System.out.printf("classpath: %s\tclass: %s\targs: %s\n",cmd.cpOption,cmd.className, Arrays.asList(cmd.args));
@ -59,5 +62,35 @@ public class Jvm {
) {
System.out.printf("%X",b);
}
*/
ClassPath cp = new ClassPath();
cp.parse(cmd.jreOption, cmd.cpOption);
String className = cmd.className.replace(".", "/").concat(".class");
ClassFile classFile = new ClassFile(cp.readClass(className));
classFile.read();
System.out.println(cmd.className);
printClassInfo(classFile);
}
public static void printClassInfo(ClassFile classFile) {
System.out.printf("version: %d.%d\n", (int) classFile.getMajorVersion(), (int) classFile.getMinorVersion());
System.out.printf("constants count: %d\n", (classFile.getConstantPool()).getConstantInfos().length);
System.out.printf("access flags: 0X%X\n", (int) classFile.getAccessFlags());
System.out.printf("this class: %s\n", classFile.thisClassName());
System.out.printf("super class: %s\n", classFile.superClassName());
if (classFile.interfaceNames().length > 0) {
System.out.printf("interfaces: %s\n", Arrays.asList(classFile.interfaceNames()));
}
System.out.printf("fields: %d\n", (classFile.getFields()).length);
for (int i = 0; i < classFile.getFields().length; i++) {
System.out.printf("\t\t%s\n", classFile.getFields()[i].getName());
}
System.out.println("methods count : " + classFile.getMethods().length);
for (int i = 0; i < classFile.getMethods().length; i++) {
System.out.printf("\t\t%s\n", classFile.getMethods()[i].getName());
}
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.classfile;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/18.
*/
public interface AttributeInfo {
public void readInfo(ClassReader classReader);
}

View File

@ -0,0 +1,258 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.classfile;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/18.
*/
public class ClassFile {
static final int CONSTANT_Class = 7;
static final int CONSTANT_Fieldref = 9;
static final int CONSTANT_Methodref = 10;
static final int CONSTANT_InterfaceMethodref = 11;
static final int CONSTANT_String = 8;
static final int CONSTANT_Integer = 3;
static final int CONSTANT_Float = 4;
static final int CONSTANT_Long = 5;
static final int CONSTANT_Double = 6;
static final int CONSTANT_NameAndType = 12;
static final int CONSTANT_Utf8 = 1;
static final int CONSTANT_MethodHandle = 15;
static final int CONSTANT_MethodType = 16;
static final int CONSTANT_InvokeDynamic = 18;
char majorVersion;
ConstantPool constantPool;
char accessFlags;
char thisClass;
char superClass;
char[] interfaces;
MemberInfo[] fields;
MemberInfo[] methods;
AttributeInfo[] attributes;
ClassReader classReader;
private char minorVersion;
public ClassFile(byte[] classData) {
this.classReader = new ClassReader(classData);
}
public static AttributeInfo[] readAttributes(ClassReader classReader, ConstantPool constantPool) {
char attributesCount = classReader.readUint16();
AttributeInfo[] attributes = new AttributeInfo[attributesCount];
for (int i = 0; i < attributesCount; i++) {
attributes[i] = readAttribute(classReader, constantPool);
}
return attributes;
}
public static AttributeInfo readAttribute(ClassReader cr, ConstantPool cp) {
char attrNameIndex = cr.readUint16();
String attrName = cp.getUTF8(attrNameIndex);
int attrlen = cr.readUint32();
AttributeInfo attrInfo = newAttributeInfo(attrName, attrlen, cp);
attrInfo.readInfo(cr);
return attrInfo;
}
public static AttributeInfo newAttributeInfo(String attrName, int attrlen, ConstantPool cp) {
switch (attrName) {
case "Code":
return new AttrCode(cp);
case "ConstantValue":
return new AttrConstantValue();
case "Deprecated":
return new AttrDeprecated();
case "Exceptions":
return new AttrExceptions();
case "LineNumberTable":
return new AttrLineNumberTable();
case "LocalVariableTable":
return new AttrLocalVariableTable();
case "SourceFile":
return new AttrSourceFile(cp);
case "Synthetic":
return new AttrSynthetic();
default:
return new AttrUnparsed(attrName, attrlen);
}
}
public void read() {
readAndCheckMagic();
readAndCheckVersion();
constantPool = readConstantPool();
accessFlags = classReader.readUint16();
thisClass = classReader.readUint16();
superClass = classReader.readUint16();
interfaces = classReader.readUint16s();
fields = readMembers(constantPool);
methods = readMembers(constantPool);
attributes = readAttributes(classReader, constantPool);
}
public void readAndCheckMagic() {
int magicReadFromFile = classReader.readUint32();
int magic = ((0xcafe << 16) & 0xffff0000) | ((0xbabe) & 0x0000ffff);
if (magicReadFromFile != magic) {
throw new RuntimeException("Class format error:Magic");
}
}
public MemberInfo[] readMembers(ConstantPool cp) {
int memberCount = classReader.readUint16();
MemberInfo[] members = new MemberInfo[memberCount];
for (int i = 0; i < memberCount; i++) {
members[i] = new MemberInfo(classReader, cp);
}
return members;
}
public ConstantPool readConstantPool() {
int cpCount = classReader.readUint16();
ConstantInfo[] constantInfos = new ConstantInfo[cpCount];
for (int i = 1; i < cpCount; i++) {
constantInfos[i] = readConstantInfo();
if (constantInfos[i] instanceof ConstantLongInfo || constantInfos[i] instanceof ConstantDoubleInfo) {
i++;
}
}
ConstantPool cp = new ConstantPool();
cp.setConstantInfos(constantInfos);
return cp;
}
public ConstantInfo readConstantInfo() {
int tag = classReader.readUint8();
ConstantInfo constantInfo = newConstantInfo(tag, constantPool);
constantInfo.readInfo(classReader);
return constantInfo;
}
public ConstantInfo newConstantInfo(int tag, ConstantPool constantPool) {
switch (tag) {
case CONSTANT_Integer:
return new ConstantIntegerInfo();
case CONSTANT_Float:
return new ConstantFloatInfo();
case CONSTANT_Long:
return new ConstantLongInfo();
case CONSTANT_Double:
return new ConstantDoubleInfo();
case CONSTANT_Utf8:
return new ConstantUtf8Info();
case CONSTANT_String:
return new ConstantStringInfo(constantPool);
case CONSTANT_Class:
return new ConstantClassInfo(constantPool);
case CONSTANT_Fieldref:
return new ConstantFieldrefInfo(constantPool);
case CONSTANT_Methodref:
return new ConstantMethodrefInfo(constantPool);
case CONSTANT_InterfaceMethodref:
return new ConstantInterfaceMemberrefInfo(constantPool);
case CONSTANT_NameAndType:
return new ConstantNameAndTypeInfo();
// case CONSTANT_MethodType:
// return new ConstantInterInfo();
// case CONSTANT_MethodHandle:
// return new ConstantInterInfo();
// case CONSTANT_InvokeDynamic:
// return new ConstantInterInfo();
default:
throw new RuntimeException("Class format error:constant pool tag");
}
}
public void readAndCheckVersion() {
minorVersion = classReader.readUint16();
majorVersion = classReader.readUint16();
switch (majorVersion) {
case 45:
break;
case 46:
case 47:
case 48:
case 49:
case 50:
case 51:
case 52:
if (minorVersion == 0) {
break;
}
default:
throw new RuntimeException("Unsupported class version");
}
}
public String thisClassName() {
return constantPool.getClassName(thisClass);
}
public String superClassName() {
if (superClass > 0) {
return constantPool.getClassName(superClass);
}
return "";
}
public String[] interfaceNames() {
String[] interfaceNames = new String[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
interfaceNames[i] = constantPool.getClassName(interfaces[i]);
}
return interfaceNames;
}
public char getMinorVersion() {
return minorVersion;
}
public char getMajorVersion() {
return majorVersion;
}
public ConstantPool getConstantPool() {
return constantPool;
}
public char getAccessFlags() {
return accessFlags;
}
public MemberInfo[] getFields() {
return fields;
}
public MemberInfo[] getMethods() {
return methods;
}
}

View File

@ -0,0 +1,87 @@
package com.gabongao.jvm.classfile;
import java.awt.*;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/17.
*/
public class ClassReader {
public byte[] data;
public ClassReader(byte[] classData) {
this.data = classData;
}
public byte readUint8() {
byte[] tempData = this.data;
data = new byte[tempData.length - 1];
System.arraycopy(tempData, 1, data, 0, tempData.length - 1);
return tempData[0];
}
public char readUint16() {
byte[] tempData = this.data;
data = new byte[tempData.length - 2];
System.arraycopy(tempData, 2, data, 0, tempData.length - 2);
return (char) (((((char) tempData[0]) << 8) & 0xff00) | (((char) tempData[1]) & 0x00ff));
}
public int readUint32() {
byte[] tempData = this.data;
data = new byte[tempData.length - 4];
System.arraycopy(tempData, 4, data, 0, tempData.length - 4);
return ((((int) tempData[0]) << 24) & 0xff000000) | ((((int) tempData[1]) << 16) & 0x00ff0000) | ((((int) tempData[2]) << 8) & 0x0000ff00) | (((int) tempData[3]) & 0x000000ff);
}
public long readUint64() {
byte[] tempData = this.data;
data = new byte[tempData.length - 8];
System.arraycopy(tempData, 8, data, 0, tempData.length - 8);
return (((((long) tempData[0]) << 56) & 0xff00000000000000L) | ((((long) tempData[1]) << 48) & 0x00ff000000000000L) | ((((long) tempData[2]) << 40) & 0x0000ff0000000000L) | (((long) tempData[3] << 32) & 0x000000ff00000000L)) & 0xffffffff00000000L | (((((long) tempData[4]) << 24) & 0xff000000) | ((((long) tempData[5]) << 16) & 0x00ff0000) | ((((long) tempData[6]) << 8) & 0x0000ff00) | (((long) tempData[7]) & 0x000000ff)) & 0x00000000ffffffffL;
}
public char[] readUint16s() {
int n = readUint16();
if (n == 0) {
return null;
}
char[] chars = new char[n];
for (int i = 0; i < n; i++) {
chars[i] = readUint16();
}
// byte[] tempData = this.data;
// data = new byte[tempData.length - (n )];
// System.arraycopy(tempData, (n + 1), data, 0, tempData.length - (n + 1));
return chars;
}
public byte[] readBytes(int length) {
byte[] tempData = this.data;
data = new byte[tempData.length - length];
System.arraycopy(tempData, length, data, 0, tempData.length - length);
byte[] res = new byte[length];
System.arraycopy(tempData, 0, res, 0, length);
return res;
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.classfile;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/18.
*/
public class ConstantDoubleInfo extends ConstantInfo {
double val;
public double getVal() {
return val;
}
@Override
public void readInfo(ClassReader classReader) {
val = Double.longBitsToDouble(classReader.readUint64());
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.classfile;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/18.
*/
public class ConstantFloatInfo extends ConstantInfo {
float val;
public float getVal() {
return val;
}
@Override
public void readInfo(ClassReader classReader) {
val = Float.intBitsToFloat(classReader.readUint32());
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.classfile;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/18.
*/
public abstract class ConstantInfo {
public abstract void readInfo(ClassReader classReader);
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.classfile;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/18.
*/
public class ConstantIntegerInfo extends ConstantInfo {
int val;
@Override
public void readInfo(ClassReader classReader) {
val = classReader.readUint32();
}
public int getVal() {
return val;
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.classfile;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/18.
*/
public class ConstantLongInfo extends ConstantInfo {
long val;
@Override
public void readInfo(ClassReader classReader) {
val = classReader.readUint64();
}
public long getVal() {
return val;
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.classfile;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/18.
*/
public class ConstantPool {
ConstantInfo[] constantInfos;
public ConstantInfo[] getConstantInfos() {
return constantInfos;
}
public void setConstantInfos(ConstantInfo[] constantInfos) {
this.constantInfos = constantInfos;
}
public ConstantInfo getConstantInfo(char index) {
ConstantInfo cpInfo = constantInfos[index];
if (cpInfo != null) {
return cpInfo;
}
throw new RuntimeException("Invalid constant pool index");
}
public String[] getNameAndType(char index) {
ConstantNameAndTypeInfo info = (ConstantNameAndTypeInfo) getConstantInfo(index);
return new String[]{getUTF8(info.nameIndex), getUTF8(info.descriptorIndex)};
}
public String getClassName(char index) {
return getUTF8(((ConstantClassInfo) getConstantInfo(index)).nameIndex);
}
public String getUTF8(char index) {
return ((ConstantUtf8Info) getConstantInfo(index)).getString();
}
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2017. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.gabongao.jvm.classfile;
/**
*            + +
*         + +
*               
*               ++ + + +
*        +
*                +
*              
*                + +
*           
*             
*              + + + +
*                 Code is far away from bug with the animal protecting
*              +     神兽保佑,代码无bug
*             
*               +
*               + +
*                  
*                  
*           + + + +
*            
*            + + + +
* Created by Imgaojp on 2017/2/18.
*/
public class MemberInfo {
ConstantPool cp;
char accessFlags, nameIndex, descriptorIndex;
AttributeInfo[] attributes;
public MemberInfo(ClassReader classReader, ConstantPool cp) {
this.cp = cp;
this.accessFlags = classReader.readUint16();
this.nameIndex = classReader.readUint16();
this.descriptorIndex = classReader.readUint16();
this.attributes = ClassFile.readAttributes(classReader, cp);
}
public String getName() {
return cp.getUTF8(nameIndex);
}
public String getDescriptor() {
return cp.getUTF8(descriptorIndex);
}
public char getAccessFlags() {
return accessFlags;
}
}