From 0c697627aa666bda654184aa158180cf82355f55 Mon Sep 17 00:00:00 2001 From: BENEDEK Date: Fri, 12 Apr 2024 23:19:43 +0200 Subject: [PATCH] completed parsing --- .clang-format | 9 +++++ classfile.c | 103 ++++++++++++++++++++++---------------------------- classfile.h | 2 +- 3 files changed, 55 insertions(+), 59 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..f89ba5b --- /dev/null +++ b/.clang-format @@ -0,0 +1,9 @@ +BasedOnStyle: Chromium +IndentWidth: 2 +ColumnLimit: 160 +SpaceAfterCStyleCast: false +UseTab: Never +AllowShortIfStatementsOnASingleLine: false +AlignTrailingComments: false +SpacesBeforeTrailingComments: 1 +AlignConsecutiveMacros: Consecutive \ No newline at end of file diff --git a/classfile.c b/classfile.c index 5049f3c..9c46468 100644 --- a/classfile.c +++ b/classfile.c @@ -11,17 +11,20 @@ void read_u2(void* ptr, size_t n, FILE* file) { u2 buffer[n]; fread(&buffer, sizeof(u2), n, file); + #ifdef SWAP_ENDIANNESS for (size_t i = 0; i < n; i++) { buffer[i] = (buffer[i] >> 8) | (buffer[i] << 8); } #endif + memcpy(ptr, &buffer, n * sizeof(u2)); } void read_u4(void* ptr, size_t n, FILE* file) { u4 buffer[n]; fread(&buffer, sizeof(u4), n, file); + #ifdef SWAP_ENDIANNESS for (size_t i = 0; i < n; i++) { buffer[i] = ((buffer[i] >> 24) & 0xff) | // move byte 3 to byte 0 @@ -30,6 +33,7 @@ void read_u4(void* ptr, size_t n, FILE* file) { ((buffer[i] << 24) & 0xff000000); } #endif + memcpy(ptr, &buffer, n * sizeof(u4)); } @@ -56,7 +60,6 @@ stack_frame_type stack_frame_type_enum(u2 frame_type) { void parse_attribute(ClassFile* cf, attribute_info* base, FILE* file) { char* name = (char*)cf->constant_pool[base->attribute_name_index - 1].info.utf8_info.bytes; - printf("%s\n", name); if (strcmp("ConstantValue", name) == 0) { read_u2(&(base->info.constant_value_attribute.constantvalue_index), 1, file); } else if (strcmp("Code", name) == 0) { @@ -149,16 +152,18 @@ void parse_attribute(ClassFile* cf, attribute_info* base, FILE* file) { } } } else if (strcmp("NestHost", name) == 0) { - printf("NestHost not implemented.\n"); - assert(0); - } else if (strcmp("NestMembers", name)) { - printf("NestMembers not implemented.\n"); - assert(0); + read_u2(&(base->info.nest_host_attribute.host_class_index), 1, file); + } else if (strcmp("NestMembers", name) == 0) { + read_u2(&(base->info.nest_members_attribute.number_of_classes), 1, file); + base->info.nest_members_attribute.classes = malloc(sizeof(u2) * base->info.nest_members_attribute.number_of_classes); + read_u2(base->info.nest_members_attribute.classes, base->info.nest_members_attribute.number_of_classes, file); } else if (strcmp("PermittedSubclasses", name) == 0) { - printf("PermittedSubclasses not implemented.\n"); - assert(0); + read_u2(&(base->info.permitted_subclasses_attribute.number_of_classes), 1, file); + base->info.permitted_subclasses_attribute.classes = malloc(sizeof(u2) * base->info.permitted_subclasses_attribute.number_of_classes); + read_u2(base->info.permitted_subclasses_attribute.classes, base->info.permitted_subclasses_attribute.number_of_classes, file); } else { - printf("unhandled attribute type: %s", name); + printf("unhandled attribute type: %s\n", name); + fseek(file, base->attribute_length, SEEK_CUR); } } @@ -180,71 +185,72 @@ ClassFile* ClassFile_load(const char* path) { // cp_info.tag 2bytes fread(&(cf->constant_pool[i].tag), 1, 1, file); size_t size; - switch (cf->constant_pool[i].tag) { + cp_info* cp = &(cf->constant_pool[i]); + switch (cp->tag) { case CONSTANT_Class: - read_u2(&(cf->constant_pool[i].info.class_info.name_index), 1, file); + read_u2(&(cp->info.class_info.name_index), 1, file); break; case CONSTANT_Fieldref: - read_u2(&(cf->constant_pool[i].info.fieldref_info.class_index), 1, file); - read_u2(&(cf->constant_pool[i].info.fieldref_info.name_and_type_index), 1, file); + read_u2(&(cp->info.fieldref_info.class_index), 1, file); + read_u2(&(cp->info.fieldref_info.name_and_type_index), 1, file); break; case CONSTANT_Methodref: - read_u2(&(cf->constant_pool[i].info.methodref_info.class_index), 1, file); - read_u2(&(cf->constant_pool[i].info.methodref_info.name_and_type_index), 1, file); + read_u2(&(cp->info.methodref_info.class_index), 1, file); + read_u2(&(cp->info.methodref_info.name_and_type_index), 1, file); break; case CONSTANT_InterfaceMethodref: - read_u2(&(cf->constant_pool[i].info.interface_methodred_info.class_index), 1, file); - read_u2(&(cf->constant_pool[i].info.interface_methodred_info.name_and_type_index), 1, file); + read_u2(&(cp->info.interface_methodref_info.class_index), 1, file); + read_u2(&(cp->info.interface_methodref_info.name_and_type_index), 1, file); break; case CONSTANT_String: - read_u2(&(cf->constant_pool[i].info.string_info.string_index), 1, file); + read_u2(&(cp->info.string_info.string_index), 1, file); break; case CONSTANT_Integer: - read_u4(&(cf->constant_pool[i].info.integer_info.bytes), 1, file); + read_u4(&(cp->info.integer_info.bytes), 1, file); break; case CONSTANT_Float: - read_u4(&(cf->constant_pool[i].info.float_info.bytes), 1, file); + read_u4(&(cp->info.float_info.bytes), 1, file); break; case CONSTANT_Long: - read_u4(&(cf->constant_pool[i].info.long_info.high_bytes), 1, file); - read_u4(&(cf->constant_pool[i].info.long_info.low_bytes), 1, file); + read_u4(&(cp->info.long_info.high_bytes), 1, file); + read_u4(&(cp->info.long_info.low_bytes), 1, file); break; case CONSTANT_Double: - read_u4(&(cf->constant_pool[i].info.double_info.high_bytes), 1, file); - read_u4(&(cf->constant_pool[i].info.double_info.low_bytes), 1, file); + read_u4(&(cp->info.double_info.high_bytes), 1, file); + read_u4(&(cp->info.double_info.low_bytes), 1, file); break; case CONSTANT_NameAndType: - read_u2(&(cf->constant_pool[i].info.name_and_type_info.name_index), 1, file); - read_u2(&(cf->constant_pool[i].info.name_and_type_info.descriptor_index), 1, file); + read_u2(&(cp->info.name_and_type_info.name_index), 1, file); + read_u2(&(cp->info.name_and_type_info.descriptor_index), 1, file); break; case CONSTANT_Utf8: - read_u2(&(cf->constant_pool[i].info.utf8_info.length), 1, file); - cf->constant_pool[i].info.utf8_info.bytes = (u1*)malloc(cf->constant_pool[i].info.utf8_info.length); - fread(cf->constant_pool[i].info.utf8_info.bytes, cf->constant_pool[i].info.utf8_info.length, 1, file); + read_u2(&(cp->info.utf8_info.length), 1, file); + cp->info.utf8_info.bytes = (u1*)malloc(cp->info.utf8_info.length); + fread(cp->info.utf8_info.bytes, cp->info.utf8_info.length, 1, file); break; case CONSTANT_MethodHandle: - fread(&(cf->constant_pool[i].info.method_handle_info.reference_kind), 1, 1, file); - read_u2(&(cf->constant_pool[i].info.method_handle_info.reference_index), 1, file); + fread(&(cp->info.method_handle_info.reference_kind), 1, 1, file); + read_u2(&(cp->info.method_handle_info.reference_index), 1, file); break; case CONSTANT_MethodType: - read_u2(&(cf->constant_pool[i].info.method_type_info.descriptor_index), 1, file); + read_u2(&(cp->info.method_type_info.descriptor_index), 1, file); break; case CONSTANT_Dynamic: - read_u2(&(cf->constant_pool[i].info.dynamic_info.bootstrap_method_attr_index), 1, file); - read_u2(&(cf->constant_pool[i].info.dynamic_info.name_and_type_index), 1, file); + read_u2(&(cp->info.dynamic_info.bootstrap_method_attr_index), 1, file); + read_u2(&(cp->info.dynamic_info.name_and_type_index), 1, file); break; case CONSTANT_InvokeDynamic: - read_u2(&(cf->constant_pool[i].info.invoke_dynamic_info.bootstrap_method_attr_index), 1, file); - read_u2(&(cf->constant_pool[i].info.invoke_dynamic_info.name_and_type_index), 1, file); + read_u2(&(cp->info.invoke_dynamic_info.bootstrap_method_attr_index), 1, file); + read_u2(&(cp->info.invoke_dynamic_info.name_and_type_index), 1, file); break; case CONSTANT_Module: - read_u2(&(cf->constant_pool[i].info.module_info.name_index), 1, file); + read_u2(&(cp->info.module_info.name_index), 1, file); break; case CONSTANT_Package: - read_u2(&(cf->constant_pool[i].info.package_info.name_index), 1, file); + read_u2(&(cp->info.package_info.name_index), 1, file); break; default: - printf("unknown constant tag: %hhu\n", cf->constant_pool[i].tag); + printf("unknown constant tag: %hhu\n", cp->tag); // assert(0); } } @@ -271,13 +277,6 @@ ClassFile* ClassFile_load(const char* path) { // attribute_name_index 2bytes, attribute_length 4bytes read_u2(&(cf->fields[i].attributes[j].attribute_name_index), 1, file); read_u4(&(cf->fields[i].attributes[j].attribute_length), 1, file); - // TODO: parse attributes by tag - // this has an unknown amount of layers, should be moved out to a function - // cf->fields[i].attributes[j].info = - // (u1 *)malloc(cf->fields[i].attributes[j].attribute_length); - // fread(cf->fields[i].attributes[j].info, - // cf->fields[i].attributes[j].attribute_length, 1, file); - parse_attribute(cf, &(cf->fields[i].attributes[j]), file); } } @@ -296,12 +295,6 @@ ClassFile* ClassFile_load(const char* path) { // attribute_name_index 2bytes, attribute_length 4bytes read_u2(&(cf->methods[i].attributes[j].attribute_name_index), 1, file); read_u4(&(cf->methods[i].attributes[j].attribute_length), 1, file); - // TODO: parse attributes by tag - // this has an unknown amount of layers, should be moved out to a function - // cf->methods[i].attributes[j].info = - // (u1 *)malloc(cf->methods[i].attributes[j].attribute_length); - // fread(cf->methods[i].attributes[j].info, - // cf->methods[i].attributes[j].attribute_length, 1, file); parse_attribute(cf, &(cf->methods[i].attributes[j]), file); } } @@ -315,12 +308,6 @@ ClassFile* ClassFile_load(const char* path) { // attribute_name_index 2bytes, attribute_length 4bytes read_u2(&(cf->attributes[i].attribute_name_index), 1, file); read_u4(&(cf->attributes[i].attribute_length), 1, file); - // cf->attributes[i].info = (u1 - // *)malloc(cf->attributes[i].attribute_length); - // TODO: parse attributes by tag - // this has an unknown amount of layers, should be moved out to a function - // fread(cf->attributes[i].info, cf->attributes[i].attribute_length, 1, - // file); parse_attribute(cf, &(cf->attributes[i]), file); } diff --git a/classfile.h b/classfile.h index 8a52516..413e469 100644 --- a/classfile.h +++ b/classfile.h @@ -116,7 +116,7 @@ typedef struct { CONSTANT_Class_info class_info; CONSTANT_Fieldref_info fieldref_info; CONSTANT_Methodref_info methodref_info; - CONSTANT_InterfaceMethodref_info interface_methodred_info; + CONSTANT_InterfaceMethodref_info interface_methodref_info; CONSTANT_String_info string_info; CONSTANT_Integer_info integer_info; CONSTANT_Float_info float_info;