From c50d37d45ce6bd7f04b599bda6aa33994cf9f185 Mon Sep 17 00:00:00 2001 From: "Mike D. Lowis" Date: Mon, 16 Sep 2013 19:13:24 -0400 Subject: [PATCH] Finished working version of libsof and readsof --- source/libsof/libsof.c | 150 ++++++++++++++++++++++++++++++++++------- source/libsof/libsof.h | 24 ++++++- source/libsof/sof.h | 21 +++--- source/readsof/main.c | 94 ++++++++++++++++++++++++++ 4 files changed, 252 insertions(+), 37 deletions(-) create mode 100644 source/readsof/main.c diff --git a/source/libsof/libsof.c b/source/libsof/libsof.c index a822805..775b818 100644 --- a/source/libsof/libsof.c +++ b/source/libsof/libsof.c @@ -8,6 +8,7 @@ #include #include #include +#include static void libsof_read_header(FILE* file, sof_file_t* obj); static void libsof_read_symbols(FILE* file, sof_file_t* obj); @@ -19,12 +20,13 @@ static void libsof_write_symbols(FILE* file, sof_file_t* obj); static void libsof_write_strings(FILE* file, sof_file_t* obj); static void libsof_write_data(FILE* file, sof_file_t* obj); static void libsof_write_code(FILE* file, sof_file_t* obj); -//static bool is_big_endian(void); +static void* libsof_get_segment_addr(void* segment, size_t seg_size, size_t el_size, size_t offset); +static size_t libsof_add_to_segment(void** segment, size_t* seg_size, void const* data, size_t length); /****************************************************************************** * Functions for Reading an SOF file *****************************************************************************/ -sof_file_t* libsof_read(const char* fname) +sof_file_t* libsof_read_obj(char const* fname) { sof_file_t* obj = NULL; /* Open the file for reading */ @@ -57,9 +59,8 @@ static void libsof_read_symbols(FILE* file, sof_file_t* obj) { if (obj->header->sym_tbl_sz) { - size_t sz = obj->header->sym_tbl_sz * sizeof(sof_st_entry_t); - obj->symbols = (sof_st_entry_t*)malloc(sz); - fread(obj->symbols, sizeof(sof_st_entry_t), obj->header->sym_tbl_sz, file); + obj->symbols = (sof_st_entry_t*)malloc( obj->header->sym_tbl_sz ); + fread(obj->symbols, sizeof(uint8_t), obj->header->sym_tbl_sz, file); } } @@ -67,8 +68,8 @@ static void libsof_read_strings(FILE* file, sof_file_t* obj) { if (obj->header->sym_str_tbl_sz) { - obj->str_tbl = (uint8_t*)malloc( obj->header->sym_str_tbl_sz ); - fread( obj->str_tbl, sizeof(uint8_t), obj->header->sym_str_tbl_sz, file); + obj->strings = (char*)malloc( obj->header->sym_str_tbl_sz ); + fread( obj->strings, sizeof(uint8_t), obj->header->sym_str_tbl_sz, file); } } @@ -85,20 +86,19 @@ static void libsof_read_code(FILE* file, sof_file_t* obj) { if (obj->header->code_sz) { - size_t sz = obj->header->code_sz * sizeof(uint32_t); - obj->code = (uint32_t*)malloc(sz); - fread(obj->code, sizeof(uint32_t), obj->header->code_sz, file); + obj->code = (uint32_t*)malloc( obj->header->code_sz ); + fread(obj->code, sizeof(uint8_t), obj->header->code_sz, file); } } /****************************************************************************** * Functions for Writing an SOF file *****************************************************************************/ -bool libsof_write(const char* fname, sof_file_t* obj) +bool libsof_write_obj(sof_file_t* obj, char const* fname) { bool ret = false; /* Open the file for reading */ - FILE* fhndl = fopen(fname,"rb"); + FILE* fhndl = fopen(fname,"wb"); /* if the file was successfully opened */ if (fhndl) { @@ -123,7 +123,7 @@ static void libsof_write_symbols(FILE* file, sof_file_t* obj) { if (obj->header->sym_tbl_sz) { - fwrite(obj->symbols, sizeof(sof_st_entry_t), obj->header->sym_tbl_sz, file); + fwrite(obj->symbols, sizeof(sof_st_entry_t), obj->header->sym_tbl_sz / sizeof(sof_st_entry_t), file); } } @@ -131,7 +131,7 @@ static void libsof_write_strings(FILE* file, sof_file_t* obj) { if (obj->header->sym_str_tbl_sz) { - fwrite( obj->str_tbl, sizeof(uint8_t), obj->header->sym_str_tbl_sz, file); + fwrite( obj->strings, sizeof(uint8_t), obj->header->sym_str_tbl_sz, file); } } @@ -147,19 +147,123 @@ static void libsof_write_code(FILE* file, sof_file_t* obj) { if (obj->header->code_sz) { - fwrite(obj->code, sizeof(uint32_t), obj->header->code_sz, file); + fwrite(obj->code, sizeof(uint32_t), obj->header->code_sz / sizeof(uint32_t), file); } } +/****************************************************************************** + * Functions for Creating and Modifying SOF files + *****************************************************************************/ +sof_file_t* libsof_new_obj(void) +{ + sof_file_t* obj = (sof_file_t*)calloc(1,sizeof(sof_file_t)); + obj->header = (sof_header_t*)calloc(1,sizeof(sof_header_t)); + obj->header->version = SOF_VERSION; + return obj; +} + +void libsof_free_obj(sof_file_t* obj) +{ + free(obj->header); + free(obj->symbols); + free(obj->strings); + free(obj->data); + free(obj->code); + free(obj); +} + +size_t libsof_get_symbol_table_size(sof_file_t* obj) +{ + return obj->header->sym_tbl_sz; +} + +size_t libsof_get_string_table_size(sof_file_t* obj) +{ + return obj->header->sym_str_tbl_sz; +} + +size_t libsof_get_data_segment_size(sof_file_t* obj) +{ + return obj->header->data_sz; +} + +size_t libsof_get_code_segment_size(sof_file_t* obj) +{ + return obj->header->code_sz; +} + +size_t libsof_get_num_symbols(sof_file_t* obj) +{ + return obj->header->sym_tbl_sz / sizeof(sof_st_entry_t); +} + +size_t libsof_add_symbol(sof_file_t* obj, const char* name, uint32_t value, uint32_t size, uint32_t info) +{ + size_t str_idx = libsof_add_string(obj, name); + return libsof_add_st_entry(obj, str_idx, value, size, info); +} + +size_t libsof_add_st_entry(sof_file_t* obj, uint32_t name, uint32_t value, uint32_t size, uint32_t info) +{ + sof_st_entry_t new_sym = { name, value, size, info }; + return libsof_add_to_segment( (void**)&(obj->symbols), &(obj->header->sym_tbl_sz), &new_sym, sizeof(sof_st_entry_t) ); +} + +sof_st_entry_t const* libsof_get_st_entry(sof_file_t* obj, size_t offset) +{ + return libsof_get_segment_addr( obj->symbols, obj->header->sym_tbl_sz, sizeof(sof_st_entry_t), offset); +} + +size_t libsof_add_string(sof_file_t* obj, char const* name) +{ + return libsof_add_to_segment( (void**)&(obj->strings), &(obj->header->sym_str_tbl_sz), name, strlen(name) + 1 ); +} + +char const* libsof_get_string(sof_file_t* obj, size_t offset) +{ + return libsof_get_segment_addr( obj->strings, obj->header->sym_str_tbl_sz, sizeof(char), offset); +} + +size_t libsof_add_data(sof_file_t* obj, uint8_t const* data, size_t length) +{ + return libsof_add_to_segment( (void**)&(obj->data), &(obj->header->data_sz), data, length ); +} + +uint8_t const* libsof_get_data(sof_file_t* obj, size_t offset) +{ + return libsof_get_segment_addr( obj->data, obj->header->data_sz, sizeof(uint8_t), offset); +} + +size_t libsof_add_code(sof_file_t* obj, uint32_t const* code, size_t length) +{ + return libsof_add_to_segment( (void**)&(obj->code), &(obj->header->code_sz), code, length * sizeof(uint32_t) ); +} + +uint32_t const* libsof_get_code(sof_file_t* obj, size_t offset) +{ + return libsof_get_segment_addr( obj->code, obj->header->code_sz, sizeof(uint32_t), offset); +} + /****************************************************************************** * Static Helper Functions *****************************************************************************/ -//static bool is_big_endian(void) -//{ -// union { -// uint32_t i; -// uint8_t c[4]; -// } bint = { 0x01020304 }; -// return bint.c[0] == 1; -//} +static void* libsof_get_segment_addr(void* segment, size_t seg_size, size_t el_size, size_t offset) +{ + void* addr = NULL; + size_t addr_offset = offset * el_size; + if (addr_offset < seg_size) + { + addr = segment + addr_offset; + } + return addr; +} + +static size_t libsof_add_to_segment(void** segment, size_t* seg_size, void const* data, size_t length) +{ + size_t offset = *(seg_size); + *(seg_size) = offset + length; + *(segment) = realloc(*(segment), *(seg_size)); + memcpy( *(segment) + offset, data, length ); + return offset; +} diff --git a/source/libsof/libsof.h b/source/libsof/libsof.h index a255e15..cb20bcd 100644 --- a/source/libsof/libsof.h +++ b/source/libsof/libsof.h @@ -9,16 +9,34 @@ #include "sof.h" #include +#include +#include typedef struct { sof_header_t* header; sof_st_entry_t* symbols; - uint8_t* str_tbl; + char* strings; uint8_t* data; uint32_t* code; } sof_file_t; -sof_file_t* libsof_read(const char* fname); -bool libsof_write(const char* fname, sof_file_t* obj); +sof_file_t* libsof_read_obj(char const* fname); +bool libsof_write_obj(sof_file_t* obj, char const* fname); +sof_file_t* libsof_new_obj(void); +void libsof_free_obj(sof_file_t* obj); +size_t libsof_get_symbol_table_size(sof_file_t* obj); +size_t libsof_get_string_table_size(sof_file_t* obj); +size_t libsof_get_data_segment_size(sof_file_t* obj); +size_t libsof_get_code_segment_size(sof_file_t* obj); +size_t libsof_get_num_symbols(sof_file_t* obj); +size_t libsof_add_symbol(sof_file_t* obj, const char* name, uint32_t value, uint32_t size, uint32_t info); +size_t libsof_add_st_entry(sof_file_t* obj, uint32_t name, uint32_t value, uint32_t size, uint32_t info); +sof_st_entry_t const* libsof_get_st_entry(sof_file_t* obj, size_t offset); +size_t libsof_add_string(sof_file_t* obj, char const* name); +char const* libsof_get_string(sof_file_t* obj, size_t offset); +size_t libsof_add_data(sof_file_t* obj, uint8_t const* data, size_t length); +uint8_t const* libsof_get_data(sof_file_t* obj, size_t offset); +size_t libsof_add_code(sof_file_t* obj, uint32_t const* code, size_t length); +uint32_t const* libsof_get_code(sof_file_t* obj, size_t offset); #endif /* LIBSOF_H */ diff --git a/source/libsof/sof.h b/source/libsof/sof.h index f8c712c..6a93b02 100644 --- a/source/libsof/sof.h +++ b/source/libsof/sof.h @@ -39,27 +39,26 @@ typedef struct { /* 32-bit date code representing the version of SOF format used by the file */ uint32_t version; - /* The number of entries in the symbol table segment. Each entry consists - * of a single SOF_ST_Entry_T. A value of 0 indicates that the symbol table - * segment has been omitted from the file */ + /* This size of the symbol table in bytes. A value of 0 indicates that the + * symbol table segment has been omitted from the file */ uint32_t sym_tbl_sz; - /* The size in bytes of the symbol string table segment in the SOF file. - * Each entry in the symbol string table consists of an array of bytes - * terminated by a NULL byte (0x00). */ + /* The size of the symbol string table segment in bytes. Each entry in the + * symbol string table consists of an array of bytes terminated by a NULL + * byte (0x00). */ uint32_t sym_str_tbl_sz; /* The size in bytes of the constant data segment. This segment contains * constant data that is referenced by the code segment. */ uint32_t data_sz; - /* The number of instructions contained in the code segment. Each - * instruction is represented by a 32-bit value and represents a single - * action to be performed by the bytecode interpreter. */ + /* The size of the code segment in bytes. Each instruction is represented by + * a 32-bit value and represents a single action to be performed by the + * bytecode interpreter. */ uint32_t code_sz; } sof_header_t; /* Definition of the SOF symbol table entry */ typedef struct { - /* Index of the string in the symbol string table containing the name of - * this symbol */ + /* Offset into the string section where the string for the symbol is + * located */ uint32_t name; uint32_t value; uint32_t size; diff --git a/source/readsof/main.c b/source/readsof/main.c new file mode 100644 index 0000000..77c6c0e --- /dev/null +++ b/source/readsof/main.c @@ -0,0 +1,94 @@ +#include +#include + +#define GET_VERSION_YEAR(version) (version >> 16) +#define GET_VERSION_MONTH(version) ((version >> 8) & 0xFF) +#define GET_VERSION_DAY(version) (version & 0xFF) + +void print_obj(sof_file_t* obj); +void print_hex(char const* header, uint8_t const* buffer, size_t length); + +void create_obj_file(char* fname) +{ + sof_file_t* obj = libsof_new_obj(); + + libsof_add_symbol(obj, "foo", 0x11223344, 0x22222222, 0x33333333); + + uint8_t data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; + libsof_add_data(obj, data, 16); + libsof_add_data(obj, data, 16); + libsof_add_data(obj, data, 16); + + uint32_t code[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; + libsof_add_code(obj, code, 16); + libsof_add_code(obj, code, 16); + libsof_add_code(obj, code, 16); + + libsof_write_obj(obj,fname); + libsof_free_obj(obj); +} + +void print_obj(sof_file_t* obj) +{ + /* print header metadata */ + printf("SOF Version:\t%#x (%d/%d/%d)\n", + obj->header->version, + GET_VERSION_DAY(obj->header->version), + GET_VERSION_MONTH(obj->header->version), + GET_VERSION_YEAR(obj->header->version)); + printf("Symbol Table:\t%d bytes\n", obj->header->sym_tbl_sz); + printf("String Table:\t%d bytes\n", obj->header->sym_str_tbl_sz); + printf("Data Size:\t%d bytes\n", obj->header->data_sz); + printf("Code Size:\t%d bytes\n", obj->header->code_sz); + + /* print symbol table */ + printf("\nIndex\tValue\t\tSize\t\tInfo\t\tName\n"); + for(size_t i = 0; i < libsof_get_num_symbols(obj); i++) + { + sof_st_entry_t const* symbol = libsof_get_st_entry(obj,i); + char const* name = libsof_get_string(obj,symbol->name); + printf("[%d]\t%#x\t%#x\t%#x\t%s\n", i, symbol->value, symbol->size, symbol->info, name); + } + + /* print segments as hex listing */ + print_hex("Data Segment", (uint8_t const *)libsof_get_data(obj,0), libsof_get_data_segment_size(obj)); + print_hex("Code Segment", (uint8_t const *)libsof_get_code(obj,0), libsof_get_code_segment_size(obj)); +} + +void print_hex(char const* header, uint8_t const* buffer, size_t length) +{ + printf("\n\n%s\n",header); + printf("----------------------------------------------------------"); + for(size_t i = 0; i < length; i++) + { + if ((i%16) == 0) + { + printf("\n0x%04x\t", i); + } + else if ((i%4) == 0) + { + printf(" "); + } + printf("%02x ", buffer[i]); + } +} + +int main(int argc, char** argv) +{ + if (argc == 1) + { + printf("%s: no input files.\n", argv[0]); + } + else + { + create_obj_file(argv[1]); + for (uint32_t i = 1; i < argc; i++) + { + printf("\nFilename:\t%s\n", argv[i]); + sof_file_t* obj = libsof_read_obj(argv[i]); + print_obj(obj); + libsof_free_obj(obj); + } + } +} + -- 2.52.0