360 lines
8.5 KiB
C
360 lines
8.5 KiB
C
// types for Java's Classfile structure
|
|
// https://docs.oracle.com/javase/specs/jvms/se22/html/jvms-4.html
|
|
|
|
#include <stdint.h>
|
|
|
|
#pragma pack(1)
|
|
|
|
typedef uint8_t u1;
|
|
typedef uint16_t u2;
|
|
typedef uint32_t u4;
|
|
|
|
typedef enum {
|
|
ACC_PUBLIC = 0x0001,
|
|
ACC_PRIVATE = 0x0002,
|
|
ACC_PROTECTED = 0x0004,
|
|
ACC_STATIC = 0x0008,
|
|
ACC_FINAL = 0x0010,
|
|
ACC_SUPER = 0x0020,
|
|
ACC_SYNCHRONIZED = 0x0020,
|
|
ACC_VOLATLE = 0x0040,
|
|
ACC_BRIDGE = 0x0040,
|
|
ACC_TRANSIENT = 0x0080,
|
|
ACC_VARARGS = 0x0080,
|
|
ACC_NATIVE = 0x0100,
|
|
ACC_INTERFACE = 0x0200,
|
|
ACC_ABSTRACT = 0x0400,
|
|
ACC_STRICT = 0x0800,
|
|
ACC_SYNTHETIC = 0x1000,
|
|
ACC_ANNOTATION = 0x2000,
|
|
ACC_ENUM = 0x4000,
|
|
ACC_MODULE = 0x8000,
|
|
} ACCESS_FLAGS;
|
|
|
|
typedef enum {
|
|
CONSTANT_Class = 7,
|
|
CONSTANT_Fieldref = 9,
|
|
CONSTANT_Methodref = 10,
|
|
CONSTANT_InterfaceMethodref = 11,
|
|
CONSTANT_String = 8,
|
|
CONSTANT_Integer = 3,
|
|
CONSTANT_Float = 4,
|
|
CONSTANT_Long = 5,
|
|
CONSTANT_Double = 6,
|
|
CONSTANT_NameAndType = 12,
|
|
CONSTANT_Utf8 = 1,
|
|
CONSTANT_MethodHandle = 15,
|
|
CONSTANT_MethodType = 16,
|
|
CONSTANT_Dynamic = 17,
|
|
CONSTANT_InvokeDynamic = 18,
|
|
CONSTANT_Module = 19,
|
|
CONSTANT_Package = 20,
|
|
} CONSTANT_TAGS;
|
|
|
|
static const char* CONSTANT_TAGS_STRINGS[] = {"",
|
|
"UTF-8",
|
|
"",
|
|
"Interger",
|
|
"Float",
|
|
"Long",
|
|
"Double",
|
|
"Class",
|
|
"String",
|
|
"Fieldref",
|
|
"Methodref",
|
|
"InterfaceMethodref",
|
|
"NameAndType",
|
|
"",
|
|
"",
|
|
"MethodHandle",
|
|
"MethodType",
|
|
"Dynamic",
|
|
"InvokeDynamic",
|
|
"Module",
|
|
"Package"};
|
|
|
|
typedef struct {
|
|
u2 name_index;
|
|
} CONSTANT_Class_info;
|
|
|
|
typedef struct {
|
|
u2 class_index;
|
|
u2 name_and_type_index;
|
|
} CONSTANT_Fieldref_info;
|
|
typedef CONSTANT_Fieldref_info CONSTANT_Methodref_info;
|
|
typedef CONSTANT_Fieldref_info CONSTANT_InterfaceMethodref_info;
|
|
|
|
typedef struct {
|
|
u2 string_index;
|
|
} CONSTANT_String_info;
|
|
|
|
typedef struct {
|
|
u4 bytes;
|
|
} CONSTANT_Integer_info;
|
|
typedef CONSTANT_Integer_info CONSTANT_Float_info;
|
|
|
|
typedef struct {
|
|
u4 high_bytes;
|
|
u4 low_bytes;
|
|
} CONSTANT_Long_info;
|
|
typedef CONSTANT_Long_info CONSTANT_Double_info;
|
|
|
|
typedef struct {
|
|
u2 name_index;
|
|
u2 descriptor_index;
|
|
} CONSTANT_NameAndType_info;
|
|
|
|
typedef struct {
|
|
u2 length;
|
|
u1* bytes;
|
|
} CONSTANT_Utf8_info;
|
|
|
|
typedef struct {
|
|
u1 reference_kind;
|
|
u2 reference_index;
|
|
} CONSTANT_MethodHandle_info;
|
|
|
|
typedef struct {
|
|
u2 descriptor_index;
|
|
} CONSTANT_MethodType_info;
|
|
|
|
typedef struct {
|
|
u2 bootstrap_method_attr_index;
|
|
u2 name_and_type_index;
|
|
} CONSTANT_Dynamic_info;
|
|
typedef CONSTANT_Dynamic_info CONSTANT_InvokeDynamic_info;
|
|
|
|
typedef struct {
|
|
u2 name_index;
|
|
} CONSTANT_Module_info;
|
|
|
|
typedef struct {
|
|
u2 name_index;
|
|
} CONSTANT_Package_info;
|
|
|
|
typedef struct {
|
|
u1 tag;
|
|
union {
|
|
CONSTANT_Class_info class_info;
|
|
CONSTANT_Fieldref_info fieldref_info;
|
|
CONSTANT_Methodref_info methodref_info;
|
|
CONSTANT_InterfaceMethodref_info interface_methodref_info;
|
|
CONSTANT_String_info string_info;
|
|
CONSTANT_Integer_info integer_info;
|
|
CONSTANT_Float_info float_info;
|
|
CONSTANT_Long_info long_info;
|
|
CONSTANT_Double_info double_info;
|
|
CONSTANT_NameAndType_info name_and_type_info;
|
|
CONSTANT_Utf8_info utf8_info;
|
|
CONSTANT_MethodHandle_info method_handle_info;
|
|
CONSTANT_MethodType_info method_type_info;
|
|
CONSTANT_Dynamic_info dynamic_info;
|
|
CONSTANT_InvokeDynamic_info invoke_dynamic_info;
|
|
CONSTANT_Module_info module_info;
|
|
CONSTANT_Package_info package_info;
|
|
} info;
|
|
} cp_info;
|
|
|
|
typedef struct {
|
|
u2 constantvalue_index;
|
|
} ConstantValue_attribute;
|
|
|
|
typedef struct {
|
|
u2 max_stack;
|
|
u2 max_locals;
|
|
u4 code_length;
|
|
u1* code;
|
|
u2 exception_table_length;
|
|
struct {
|
|
u2 start_pc;
|
|
u2 end_pc;
|
|
u2 handler_pc;
|
|
u2 catch_type;
|
|
} * exception_table;
|
|
u2 attributes_count;
|
|
void* attributes;
|
|
} Code_attribute;
|
|
|
|
typedef enum {
|
|
ITEM_Top = 0,
|
|
ITEM_Integer = 1,
|
|
ITEM_Float = 2,
|
|
ITEM_Double = 3,
|
|
ITEM_Long = 4,
|
|
ITEM_Null = 5,
|
|
ITEM_UninitializedThis = 6,
|
|
ITEM_Object = 7,
|
|
ITEM_Uninitialized = 8,
|
|
} VERIFICATION_TAG;
|
|
|
|
typedef struct {
|
|
u1 tag;
|
|
union {
|
|
struct {
|
|
} Top_variable_info;
|
|
struct {
|
|
} Integer_variable_info;
|
|
struct {
|
|
} Float_variable_info;
|
|
struct {
|
|
} Long_variable_info;
|
|
struct {
|
|
} Double_variable_info;
|
|
struct {
|
|
} Null_variable_info;
|
|
struct {
|
|
} UninitializedThis_variable_info;
|
|
struct {
|
|
u2 cpool_index;
|
|
} Object_variable_info;
|
|
struct {
|
|
u2 offset;
|
|
} Uninitialized_variable_info;
|
|
};
|
|
} verification_type_info;
|
|
|
|
typedef enum {
|
|
SAME,
|
|
SAME_LOCALS_1_STACK_ITEM_FRAME,
|
|
SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED,
|
|
CHOP,
|
|
SAME_FRAME_EXTENDED,
|
|
APPEND,
|
|
FULL_FRAME,
|
|
} stack_frame_type;
|
|
|
|
typedef struct {
|
|
u1 frame_type;
|
|
union {
|
|
struct {
|
|
} same_frame; // 0-63
|
|
struct {
|
|
verification_type_info stack[1];
|
|
} same_locals_1_stack_item_frame; // 64-127
|
|
struct {
|
|
u2 offset_delta;
|
|
verification_type_info stack[1];
|
|
} same_locals_1_stack_item_frame_extended; // 247
|
|
struct {
|
|
u2 offset_delta;
|
|
} chop_frame; // 248-250
|
|
struct {
|
|
u2 offset_delta;
|
|
} same_frame_extended; // 251
|
|
struct {
|
|
u2 offset_delta;
|
|
verification_type_info* locals; // [frame_type - 251]
|
|
} append_frame; // 252-254
|
|
struct {
|
|
u2 offset_delta;
|
|
u2 number_of_locals;
|
|
verification_type_info* locals;
|
|
u2 number_of_stack_items;
|
|
verification_type_info* stack;
|
|
} full_frame; // 255
|
|
};
|
|
} stack_map_frame;
|
|
|
|
typedef struct {
|
|
u2 number_of_entries;
|
|
stack_map_frame* entries;
|
|
} StackMapTable_attribute;
|
|
|
|
typedef struct {
|
|
u2 bootstrap_method_ref;
|
|
u2 num_bootstrap_arguments;
|
|
u2* bootstrap_arguments;
|
|
} BootstrapMethod;
|
|
|
|
typedef struct {
|
|
u2 num_bootstrap_methods;
|
|
BootstrapMethod* bootstrap_methods;
|
|
} BootstrapMethods_attribute;
|
|
|
|
typedef struct {
|
|
u2 host_class_index;
|
|
} NestHost_attribute;
|
|
|
|
typedef struct {
|
|
u2 number_of_classes;
|
|
u2* classes;
|
|
} NestMembers_attribute;
|
|
|
|
typedef struct {
|
|
u2 number_of_classes;
|
|
u2* classes;
|
|
} PermittedSubclasses_attribute;
|
|
|
|
typedef enum {
|
|
UNKNOWN,
|
|
CONSTANT_VALUE,
|
|
CODE,
|
|
STACK_MAP_TABLE,
|
|
BOOTSTRAP_METHODS,
|
|
NEST_HOST,
|
|
NEST_MEMBERS,
|
|
PERMITTED_SUBCLASSES,
|
|
ATTRIBUTE_TAGS_END
|
|
} ATTRIBUTE_TAGS;
|
|
|
|
static const char* ATTRIBUTE_TAGS_STRINGS[] = {
|
|
"ConstantValue", "Code", "StackMapTable", "BootstrapMethods", "NestHost", "NestMembers", "PermittedSubclasses",
|
|
};
|
|
|
|
typedef struct {
|
|
u2 attribute_name_index;
|
|
u4 attribute_length;
|
|
ATTRIBUTE_TAGS _tag;
|
|
union {
|
|
ConstantValue_attribute constant_value_attribute;
|
|
Code_attribute code_attribute;
|
|
StackMapTable_attribute stack_map_table_attribute;
|
|
BootstrapMethods_attribute bootstrap_methods_attribute;
|
|
NestHost_attribute nest_host_attribute;
|
|
NestMembers_attribute nest_members_attribute;
|
|
PermittedSubclasses_attribute permitted_subclasses_attribute;
|
|
} info;
|
|
} attribute_info;
|
|
|
|
typedef struct {
|
|
u2 access_flags;
|
|
u2 name_index;
|
|
u2 descriptor_index;
|
|
u2 attributes_count;
|
|
attribute_info* attributes;
|
|
} field_info;
|
|
|
|
typedef struct {
|
|
u2 access_flags;
|
|
u2 name_index;
|
|
u2 descriptor_index;
|
|
u2 attributes_count;
|
|
attribute_info* attributes;
|
|
} method_info;
|
|
|
|
typedef struct {
|
|
u4 magic;
|
|
u2 minor_version;
|
|
u2 major_version;
|
|
u2 constant_pool_count;
|
|
cp_info* constant_pool;
|
|
u2 access_flags;
|
|
u2 this_class;
|
|
u2 super_class;
|
|
u2 interfaces_count;
|
|
u2* interfaces;
|
|
u2 fields_count;
|
|
field_info* fields;
|
|
u2 methods_count;
|
|
method_info* methods;
|
|
u2 attributes_count;
|
|
attribute_info* attributes;
|
|
} ClassFile;
|
|
|
|
ClassFile* ClassFile_load(const char* path);
|
|
void ClassFile_info(const ClassFile* cf);
|
|
|
|
char* ClassFile_resolve_Fieldref_Methodref_InterfaceMethodref(const ClassFile* cf, CONSTANT_Fieldref_info info);
|
|
char* ClassFile_resolve_NameAnyType(const ClassFile* cf, CONSTANT_NameAndType_info info);
|
|
|
|
#pragma pack() |