java-llvm/classfile.h

361 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 uint64_t u8;
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()