]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
Finished working version of libsof and readsof
authorMike D. Lowis <mike.lowis@gentex.com>
Mon, 16 Sep 2013 23:13:24 +0000 (19:13 -0400)
committerMike D. Lowis <mike.lowis@gentex.com>
Mon, 16 Sep 2013 23:13:24 +0000 (19:13 -0400)
source/libsof/libsof.c
source/libsof/libsof.h
source/libsof/sof.h
source/readsof/main.c [new file with mode: 0644]

index a822805ef2e81a0a875de695cd9385519f867488..775b8185087c7fb30aaee9e2005cd73f3f1a3b87 100644 (file)
@@ -8,6 +8,7 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 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;
+}
 
index a255e15625f119bc1843f8d8d522f1fa267669c8..cb20bcdd14cf3190482db822c7cd76fe450d15cf 100644 (file)
@@ -9,16 +9,34 @@
 
 #include "sof.h"
 #include <stdbool.h>
+#include <stdint.h>
+#include <stddef.h>
 
 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 */
index f8c712cc136630aebe3d4f39d18e17ce063357a8..6a93b02c06c82fd58f2e5fcdcc7cb7aaafc7fda2 100644 (file)
 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 (file)
index 0000000..77c6c0e
--- /dev/null
@@ -0,0 +1,94 @@
+#include <stdio.h>
+#include <libsof.h>
+
+#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);
+        }
+    }
+}
+