From: Mike D. Lowis Date: Wed, 11 Sep 2013 17:34:58 +0000 (-0400) Subject: Initial commit of libsof X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=74af6b4aeee1fac5e9af60853f8ded128d88b641;p=proto%2Fsclpl.git Initial commit of libsof --- diff --git a/SConstruct b/SConstruct index e45edaf..5d76812 100644 --- a/SConstruct +++ b/SConstruct @@ -45,13 +45,20 @@ env = Environment( LDFLAGS = [], BUILDERS = { 'SchemeProgram': scheme_linker, - 'SchemeTestRunner': scheme_tester } + 'SchemeTestRunner': scheme_tester }, + tools = [ 'mingw' ] ) #------------------------------------------------------------------------------ # SCLPL Targets #------------------------------------------------------------------------------ +# libSOF Shared Library +env.SharedLibrary( + target = 'sof', + source = find_files('source/libsof/','*.scm') + ) + # SCLPL Compiler src_files = find_files('source/compiler/','*.scm') env.SchemeProgram( diff --git a/source/libsof/libsof.c b/source/libsof/libsof.c new file mode 100644 index 0000000..869e82e --- /dev/null +++ b/source/libsof/libsof.c @@ -0,0 +1,164 @@ +/** + @file libsof.c + @brief See header for details + $Revision$ + $HeadURL$ + */ +#include "libsof.h" +#include +#include + +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; +} + diff --git a/source/libsof/libsof.h b/source/libsof/libsof.h new file mode 100644 index 0000000..fe879d6 --- /dev/null +++ b/source/libsof/libsof.h @@ -0,0 +1,23 @@ +/** + @file libsof.h + @brief TODO: Describe this file + $Revision$ + $HeadURL$ + */ +#ifndef LIBSOF_H +#define LIBSOF_H + +#include "sof.h" + +typedef struct { + sof_header_t* header; + sof_st_entry_t* symbols; + uint8_t* str_tbl; + 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); + +#endif /* LIBSOF_H */ diff --git a/source/libsof/sof.h b/source/libsof/sof.h new file mode 100644 index 0000000..f8c712c --- /dev/null +++ b/source/libsof/sof.h @@ -0,0 +1,69 @@ +/** + @file sof.h + @brief TODO: Describe this file + $Revision$ + $HeadURL$ + */ +#ifndef SOF_H +#define SOF_H + +#include + +/* + 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 */