completed parsing

This commit is contained in:
BENEDEK 2024-04-12 23:19:43 +02:00
parent e72ae7bebb
commit 0c697627aa
3 changed files with 55 additions and 59 deletions

9
.clang-format Normal file
View File

@ -0,0 +1,9 @@
BasedOnStyle: Chromium
IndentWidth: 2
ColumnLimit: 160
SpaceAfterCStyleCast: false
UseTab: Never
AllowShortIfStatementsOnASingleLine: false
AlignTrailingComments: false
SpacesBeforeTrailingComments: 1
AlignConsecutiveMacros: Consecutive

View File

@ -11,17 +11,20 @@
void read_u2(void* ptr, size_t n, FILE* file) { void read_u2(void* ptr, size_t n, FILE* file) {
u2 buffer[n]; u2 buffer[n];
fread(&buffer, sizeof(u2), n, file); fread(&buffer, sizeof(u2), n, file);
#ifdef SWAP_ENDIANNESS #ifdef SWAP_ENDIANNESS
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
buffer[i] = (buffer[i] >> 8) | (buffer[i] << 8); buffer[i] = (buffer[i] >> 8) | (buffer[i] << 8);
} }
#endif #endif
memcpy(ptr, &buffer, n * sizeof(u2)); memcpy(ptr, &buffer, n * sizeof(u2));
} }
void read_u4(void* ptr, size_t n, FILE* file) { void read_u4(void* ptr, size_t n, FILE* file) {
u4 buffer[n]; u4 buffer[n];
fread(&buffer, sizeof(u4), n, file); fread(&buffer, sizeof(u4), n, file);
#ifdef SWAP_ENDIANNESS #ifdef SWAP_ENDIANNESS
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
buffer[i] = ((buffer[i] >> 24) & 0xff) | // move byte 3 to byte 0 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); ((buffer[i] << 24) & 0xff000000);
} }
#endif #endif
memcpy(ptr, &buffer, n * sizeof(u4)); 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) { 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; char* name = (char*)cf->constant_pool[base->attribute_name_index - 1].info.utf8_info.bytes;
printf("%s\n", name);
if (strcmp("ConstantValue", name) == 0) { if (strcmp("ConstantValue", name) == 0) {
read_u2(&(base->info.constant_value_attribute.constantvalue_index), 1, file); read_u2(&(base->info.constant_value_attribute.constantvalue_index), 1, file);
} else if (strcmp("Code", name) == 0) { } 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) { } else if (strcmp("NestHost", name) == 0) {
printf("NestHost not implemented.\n"); read_u2(&(base->info.nest_host_attribute.host_class_index), 1, file);
assert(0); } else if (strcmp("NestMembers", name) == 0) {
} else if (strcmp("NestMembers", name)) { read_u2(&(base->info.nest_members_attribute.number_of_classes), 1, file);
printf("NestMembers not implemented.\n"); base->info.nest_members_attribute.classes = malloc(sizeof(u2) * base->info.nest_members_attribute.number_of_classes);
assert(0); read_u2(base->info.nest_members_attribute.classes, base->info.nest_members_attribute.number_of_classes, file);
} else if (strcmp("PermittedSubclasses", name) == 0) { } else if (strcmp("PermittedSubclasses", name) == 0) {
printf("PermittedSubclasses not implemented.\n"); read_u2(&(base->info.permitted_subclasses_attribute.number_of_classes), 1, file);
assert(0); 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 { } 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 // cp_info.tag 2bytes
fread(&(cf->constant_pool[i].tag), 1, 1, file); fread(&(cf->constant_pool[i].tag), 1, 1, file);
size_t size; size_t size;
switch (cf->constant_pool[i].tag) { cp_info* cp = &(cf->constant_pool[i]);
switch (cp->tag) {
case CONSTANT_Class: 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; break;
case CONSTANT_Fieldref: case CONSTANT_Fieldref:
read_u2(&(cf->constant_pool[i].info.fieldref_info.class_index), 1, file); read_u2(&(cp->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.name_and_type_index), 1, file);
break; break;
case CONSTANT_Methodref: case CONSTANT_Methodref:
read_u2(&(cf->constant_pool[i].info.methodref_info.class_index), 1, file); read_u2(&(cp->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.name_and_type_index), 1, file);
break; break;
case CONSTANT_InterfaceMethodref: case CONSTANT_InterfaceMethodref:
read_u2(&(cf->constant_pool[i].info.interface_methodred_info.class_index), 1, file); read_u2(&(cp->info.interface_methodref_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.name_and_type_index), 1, file);
break; break;
case CONSTANT_String: 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; break;
case CONSTANT_Integer: 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; break;
case CONSTANT_Float: 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; break;
case CONSTANT_Long: case CONSTANT_Long:
read_u4(&(cf->constant_pool[i].info.long_info.high_bytes), 1, file); read_u4(&(cp->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.low_bytes), 1, file);
break; break;
case CONSTANT_Double: case CONSTANT_Double:
read_u4(&(cf->constant_pool[i].info.double_info.high_bytes), 1, file); read_u4(&(cp->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.low_bytes), 1, file);
break; break;
case CONSTANT_NameAndType: case CONSTANT_NameAndType:
read_u2(&(cf->constant_pool[i].info.name_and_type_info.name_index), 1, file); read_u2(&(cp->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.descriptor_index), 1, file);
break; break;
case CONSTANT_Utf8: case CONSTANT_Utf8:
read_u2(&(cf->constant_pool[i].info.utf8_info.length), 1, file); read_u2(&(cp->info.utf8_info.length), 1, file);
cf->constant_pool[i].info.utf8_info.bytes = (u1*)malloc(cf->constant_pool[i].info.utf8_info.length); cp->info.utf8_info.bytes = (u1*)malloc(cp->info.utf8_info.length);
fread(cf->constant_pool[i].info.utf8_info.bytes, cf->constant_pool[i].info.utf8_info.length, 1, file); fread(cp->info.utf8_info.bytes, cp->info.utf8_info.length, 1, file);
break; break;
case CONSTANT_MethodHandle: case CONSTANT_MethodHandle:
fread(&(cf->constant_pool[i].info.method_handle_info.reference_kind), 1, 1, file); fread(&(cp->info.method_handle_info.reference_kind), 1, 1, file);
read_u2(&(cf->constant_pool[i].info.method_handle_info.reference_index), 1, file); read_u2(&(cp->info.method_handle_info.reference_index), 1, file);
break; break;
case CONSTANT_MethodType: 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; break;
case CONSTANT_Dynamic: case CONSTANT_Dynamic:
read_u2(&(cf->constant_pool[i].info.dynamic_info.bootstrap_method_attr_index), 1, file); read_u2(&(cp->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.name_and_type_index), 1, file);
break; break;
case CONSTANT_InvokeDynamic: case CONSTANT_InvokeDynamic:
read_u2(&(cf->constant_pool[i].info.invoke_dynamic_info.bootstrap_method_attr_index), 1, file); read_u2(&(cp->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.name_and_type_index), 1, file);
break; break;
case CONSTANT_Module: 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; break;
case CONSTANT_Package: 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; break;
default: default:
printf("unknown constant tag: %hhu\n", cf->constant_pool[i].tag); printf("unknown constant tag: %hhu\n", cp->tag);
// assert(0); // assert(0);
} }
} }
@ -271,13 +277,6 @@ ClassFile* ClassFile_load(const char* path) {
// attribute_name_index 2bytes, attribute_length 4bytes // attribute_name_index 2bytes, attribute_length 4bytes
read_u2(&(cf->fields[i].attributes[j].attribute_name_index), 1, file); read_u2(&(cf->fields[i].attributes[j].attribute_name_index), 1, file);
read_u4(&(cf->fields[i].attributes[j].attribute_length), 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); 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 // attribute_name_index 2bytes, attribute_length 4bytes
read_u2(&(cf->methods[i].attributes[j].attribute_name_index), 1, file); read_u2(&(cf->methods[i].attributes[j].attribute_name_index), 1, file);
read_u4(&(cf->methods[i].attributes[j].attribute_length), 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); 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 // attribute_name_index 2bytes, attribute_length 4bytes
read_u2(&(cf->attributes[i].attribute_name_index), 1, file); read_u2(&(cf->attributes[i].attribute_name_index), 1, file);
read_u4(&(cf->attributes[i].attribute_length), 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); parse_attribute(cf, &(cf->attributes[i]), file);
} }

View File

@ -116,7 +116,7 @@ typedef struct {
CONSTANT_Class_info class_info; CONSTANT_Class_info class_info;
CONSTANT_Fieldref_info fieldref_info; CONSTANT_Fieldref_info fieldref_info;
CONSTANT_Methodref_info methodref_info; CONSTANT_Methodref_info methodref_info;
CONSTANT_InterfaceMethodref_info interface_methodred_info; CONSTANT_InterfaceMethodref_info interface_methodref_info;
CONSTANT_String_info string_info; CONSTANT_String_info string_info;
CONSTANT_Integer_info integer_info; CONSTANT_Integer_info integer_info;
CONSTANT_Float_info float_info; CONSTANT_Float_info float_info;