#include "header.h" #include #include #include #include void header_destroy(Header* header) { for (size_t i = 0; i < header->global_syms_size; ++i) { free(header->global_syms[i].ident); } free(header->global_syms); for (size_t i = 0; i < header->extern_syms_size; ++i) { free(header->extern_syms[i].ident); } free(header->extern_syms); free(header->extern_refs); } int header_read_from(Header* header, FILE* fp, const char* filename) { int res = 0; uint16_t ident[6] = { 0 }; if (fread(ident, sizeof(uint16_t), 5, fp) != 5) { res = 1; goto leave_1; } if (strcmp((char*)ident, "vc3-object") != 0) { res = 2; goto leave_1; } uint16_t header_size; if (fread(&header_size, sizeof(uint16_t), 1, fp) != 1) { res = 3; goto leave_1; } // We want header size in words, not bytes. header_size /= 2; fseek(fp, 0, SEEK_SET); uint16_t* data = malloc(sizeof(uint16_t) * header_size); if (fread(data, sizeof(uint16_t), header_size, fp) != header_size) { res = 4; goto leave_2; } size_t dc = 6; uint16_t global_syms_size = data[dc++]; HeaderGlobalSym* global_syms = malloc(sizeof(HeaderGlobalSym) * global_syms_size); for (size_t i = 0; i < global_syms_size; ++i) { uint16_t offset = data[dc++]; uint16_t ident_len = data[dc++]; char* ident = calloc(ident_len + 1, sizeof(char)); strncpy(ident, (char*)&data[dc], ident_len); dc += (size_t)(ident_len + 1) / 2; global_syms[i] = (HeaderGlobalSym) { offset, ident }; } uint16_t extern_syms_size = data[dc++]; HeaderExternSym* extern_syms = malloc(sizeof(HeaderExternSym) * extern_syms_size); for (size_t i = 0; i < extern_syms_size; ++i) { uint16_t id = data[dc++]; uint16_t ident_len = data[dc++]; char* ident = calloc(ident_len + 1, sizeof(char)); strncpy(ident, (char*)&data[dc], ident_len); dc += (size_t)(ident_len + 1) / 2; extern_syms[i] = (HeaderExternSym) { id, ident }; } uint16_t extern_refs_size = data[dc++]; HeaderExternRef* extern_refs = malloc(sizeof(HeaderExternRef) * extern_refs_size); for (size_t i = 0; i < extern_refs_size; ++i) { uint16_t id = data[dc++]; uint16_t offset = data[dc++]; extern_refs[i] = (HeaderExternRef) { id, offset }; } uint16_t program_size = data[dc++]; // We want program size in words too. program_size /= 2; *header = (Header) { header_size, global_syms_size, global_syms, extern_syms_size, extern_syms, extern_refs_size, extern_refs, program_size, }; res = 0; leave_2: free(data); leave_1: if (res != 0) { fprintf(stderr, "error: malformed object file '%s'\n", filename); printf("res = %d\n", res); } return res; } void header_print(const Header* header) { printf("globals:\n"); printf("address symbol\n"); printf("-----------------------\n"); for (size_t i = 0; i < header->global_syms_size; ++i) { HeaderGlobalSym* sym = &header->global_syms[i]; printf("%04x, %s\n", sym->offset, sym->ident); } printf("\nexterns:\n"); printf("id symbol\n"); printf("--------------------\n"); for (size_t i = 0; i < header->extern_syms_size; ++i) { HeaderExternSym* sym = &header->extern_syms[i]; printf("%-3d %s\n", sym->id, sym->ident); } printf("\nextern uses:\n"); printf("id address\n"); printf("-----------\n"); for (size_t i = 0; i < header->extern_refs_size; ++i) { HeaderExternRef* ref = &header->extern_refs[i]; printf("%3d %04x\n", ref->id, ref->offset); } }