// types for Java's Classfile structure // https://docs.oracle.com/javase/specs/jvms/se22/html/jvms-4.html #include #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; 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 num_bootstrap_methods; struct { u2 bootstrap_method_ref; u2 num_bootstrap_arguments; u2* bootstrap_arguments; } * 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 struct { u2 attribute_name_index; u4 attribute_length; 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); #pragma pack()