--- /dev/null
+/**
+ @file libsof.c
+ @brief See header for details
+ $Revision$
+ $HeadURL$
+ */
+#include "libsof.h"
+#include <stdint.h>
+#include <stdbool.h>
+
+static void libsof_read_header(FILE* file, sof_file_t* obj);
+static void libsof_read_symbols(FILE* file, sof_file_t* obj);
+static void libsof_read_strings(FILE* file, sof_file_t* obj);
+static void libsof_read_data(FILE* file, sof_file_t* obj);
+static void libsof_read_code(FILE* file, sof_file_t* obj);
+static void libsof_write_header(FILE* file, sof_file_t* obj);
+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);
+
+/******************************************************************************
+ * Functions for Reading an SOF file
+ *****************************************************************************/
+sof_file_t* libsof_read(const char* fname)
+{
+ sof_file_t* obj = NULL;
+ /* Open the file for reading */
+ FILE* fhndl = fopen(fname,"rb");
+ /* read the files contents if valid */
+ if (fhndl)
+ {
+ /* Allocate space for the header and object structure */
+ obj = (sof_file_t*)calloc(1,sizeof(sof_file_t));
+ /* Read the contents of the file into memory */
+ libsof_read_header(fhndl, obj);
+ libsof_read_symbols(fhndl, obj);
+ libsof_read_strings(fhndl, obj);
+ libsof_read_data(fhndl, obj);
+ libsof_read_code(fhndl, obj);
+ }
+ /* close the file and return the read object */
+ fclose(fhndl);
+ return obj;
+}
+
+static void libsof_read_header(FILE* file, sof_file_t* obj)
+{
+ /* Read the object header out of the file */
+ obj->header = (sof_header_t*)malloc(sizeof(sof_header_t));
+ fread(obj->header, sizeof(sof_header_t), 1, file);
+}
+
+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, fhndl);
+ }
+}
+
+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, fhndl);
+ }
+}
+
+static void libsof_read_data(FILE* file, sof_file_t* obj)
+{
+ if (obj->header->data_sz)
+ {
+ obj->data = (uint8_t*)malloc( obj->header->data_sz );
+ fread( obj->data, sizeof(uint8_t), obj->header->data_sz, fhndl);
+ }
+}
+
+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 = (sof_st_entry_t*)malloc(sz);
+ fread(obj->code, sizeof(uint32_t), obj->header->code_sz, fhndl);
+ }
+}
+
+/******************************************************************************
+ * Functions for Writing an SOF file
+ *****************************************************************************/
+bool libsof_write(const char* fname, sof_file_t* obj)
+{
+ bool ret = false;
+ /* Open the file for reading */
+ FILE* fhndl = fopen(fname,"rb");
+ /* if the file was successfully opened */
+ if (fhndl)
+ {
+ /* Write the contents of the file in sequence */
+ libsof_write_header(fhndl,obj);
+ libsof_write_symbols(fhndl,obj);
+ libsof_write_strings(fhndl,obj);
+ libsof_write_data(fhndl,obj);
+ libsof_write_code(fhndl,obj);
+ }
+ /* close the file and return the read object */
+ fclose(fhndl);
+ return ret;
+}
+
+static void libsof_write_header(FILE* file, sof_file_t* obj)
+{
+ fwrite(obj->header, sizeof(sof_header_t), 1, file);
+}
+
+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, fhndl);
+ }
+}
+
+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, fhndl);
+ }
+}
+
+static void libsof_write_data(FILE* file, sof_file_t* obj)
+{
+ if (obj->header->data_sz)
+ {
+ fwrite( obj->data, sizeof(uint8_t), obj->header->data_sz, fhndl);
+ }
+}
+
+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, fhndl);
+ }
+}
+
+/******************************************************************************
+ * Static Helper Functions
+ *****************************************************************************/
+static bool is_big_endian(void)
+{
+ union {
+ uint32_t i;
+ uint8_t c[4];
+ } bint = { 0x01020304 };
+ return bint.c[0] == 1;
+}
+
--- /dev/null
+/**
+ @file sof.h
+ @brief TODO: Describe this file
+ $Revision$
+ $HeadURL$
+ */
+#ifndef SOF_H
+#define SOF_H
+
+#include <stdint.h>
+
+/*
+ SCLPL Object File Layout
+
+ -----------------------
+ | SOF Header |
+ -----------------------
+ | Symbol Table |
+ -----------------------
+ | Symbol String Table |
+ -----------------------
+ | Data Segment |
+ -----------------------
+ | Code Segment |
+ -----------------------
+
+*/
+
+/* Macro for generating a 32-bit date code based on year, month, and day */
+#define DATE_CODE(year,month,day) (year << 16) | (month << 8) | (day)
+
+/* The version of the SOF format supported by this library represented as a
+ * 32-bit date code */
+#define SOF_VERSION DATE_CODE(2013,9,10)
+
+/* Definition of the SOF file header. The header appears at the beginning of any
+ * SOF file and contains information about the SOF version of the file and the
+ * sizes of each section in the 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 */
+ 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). */
+ 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. */
+ 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 */
+ uint32_t name;
+ uint32_t value;
+ uint32_t size;
+ uint32_t info;
+} sof_st_entry_t;
+
+#endif /* SOF_H */