completed parsing
This commit is contained in:
parent
e72ae7bebb
commit
0c697627aa
9
.clang-format
Normal file
9
.clang-format
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
BasedOnStyle: Chromium
|
||||||
|
IndentWidth: 2
|
||||||
|
ColumnLimit: 160
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
UseTab: Never
|
||||||
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
|
AlignTrailingComments: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
AlignConsecutiveMacros: Consecutive
|
103
classfile.c
103
classfile.c
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user