From: Michael D. Lowis Date: Fri, 14 Nov 2014 02:19:41 +0000 (-0500) Subject: added underflow and overflow checking to arg and return stacks X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=78251c5d142a1c20f85ff83026cee216ed6225cc;p=projs%2Fonward.git added underflow and overflow checking to arg and return stacks --- diff --git a/Gemfile.lock b/Gemfile.lock index 203fff5..ba072f9 100755 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -20,6 +20,7 @@ GEM rspec-support (3.1.2) PLATFORMS + ruby x86-mingw32 DEPENDENCIES diff --git a/build.rb b/build.rb old mode 100644 new mode 100755 index a719734..802db8d --- a/build.rb +++ b/build.rb @@ -6,6 +6,7 @@ require './modules/build-system/setup' #------------------------------------------------------------------------------ # Define the default compiler environment base_env = BuildEnv.new do |env| + env.build_root = 'build/' # Compiler options env["CFLAGS"] += ['-DLEAK_DETECT_LEVEL=1', '--std=c99', '-Wall', '-Wextra']#, '-Werror'] env["CPPPATH"] += Dir['source/**/'] @@ -13,11 +14,13 @@ end # Define the release environment main_env = base_env.clone do |env| + env.build_root = 'build/release/' env["CFLAGS"] += ['-O3'] end # Define the test environment test_env = base_env.clone do |env| + env.build_root = 'build/test/' env["CPPPATH"] += Dir['modules/atf/source/**/'] env['CFLAGS'] += ['-O0'] if Opts[:profile].include? "coverage" diff --git a/source/onward/onward.c b/source/onward/onward.c index 4e4a5c6..f31b92e 100755 --- a/source/onward/onward.c +++ b/source/onward/onward.c @@ -2,6 +2,7 @@ #include static value_t char_oneof(char ch, char* chs); +static void abort_on_error(value_t cond, value_t errcode); /** Version number of the implementation */ defconst("VERSION", VERSION, 0, 0u); @@ -27,6 +28,7 @@ defvar("pc", pc, 0, &F_IMMEDIATE_word); /** The address of the base of the argument stack */ defvar("asb", asb, 0, &pc_word); +/** The size of the argument stack in bytes */ defvar("assz", assz, 0, &asb_word); /** The address of the top of the argument stack */ @@ -35,6 +37,7 @@ defvar("asp", asp, 0, &assz_word); /** The address of the base of the return stack */ defvar("rsb", rsb, 0, &asp_word); +/** The size of the return stack in bytes */ defvar("rssz", rssz, 0, &rsb_word); /** The address of the top of the return stack */ @@ -145,8 +148,14 @@ defcode("find", find, &lit, 0u) { onward_aspush((value_t)curr); } +defcode("abort", _abort, &find, 0u) { + asp = asb; + rsp = rsb; + pc = 0u; +} + /** Execute a word */ -defcode("exec", exec, &find, 0u) { +defcode("exec", exec, &_abort, 0u) { /* Load up the word to be executed, saving off the current state */ value_t start = rsp; word_t* to_exec[] = { (word_t*)onward_aspop(), 0u }; @@ -167,7 +176,7 @@ defcode("exec", exec, &find, 0u) { onward_rspush(pc); pc = (value_t)current->code; } - } while(rsp != start); + } while(pc && rsp != start); } /** Create a new word definition with default attributes */ @@ -259,7 +268,7 @@ defcode("interp", interp, &zbr, 0u) { comma_code(); } } else { - errno = 1; + errno = ERR_UNKNOWN_WORD; (void)onward_aspop(); } } @@ -457,8 +466,10 @@ defcode("~", bnot, &bxor, 0u) { void onward_init(onward_init_t* init_data) { asb = (value_t)(init_data->arg_stack - 1); asp = (value_t)(init_data->arg_stack - 1); + assz = (value_t)(init_data->arg_stack_sz * sizeof(value_t)); rsb = (value_t)(init_data->ret_stack - 1); rsp = (value_t)(init_data->ret_stack - 1); + rssz = (value_t)(init_data->ret_stack_sz * sizeof(value_t)); here = (value_t)(init_data->word_buf); latest = (value_t)(init_data->latest); } @@ -471,28 +482,46 @@ value_t onward_pcfetch(void) { } void onward_aspush(value_t val) { - asp += sizeof(value_t); - *((value_t*)asp) = val; + #ifndef UNSAFE_MODE + if ((asp-asb) <= assz) { + #endif + asp += sizeof(value_t); + *((value_t*)asp) = val; + #ifndef UNSAFE_MODE + } else { + abort_on_error(1, ERR_ARG_STACK_OVRFLW); + } + #endif } value_t onward_aspeek(value_t val) { - return *((value_t*)(asp + (val* sizeof(value_t)))); + return *((value_t*)(asp + (val * sizeof(value_t)))); } value_t onward_aspop(void) { value_t val = *((value_t*)asp); asp -= sizeof(value_t); + abort_on_error(asp < asb, ERR_ARG_STACK_UNDRFLW); return val; } void onward_rspush(value_t val) { - rsp += sizeof(value_t); - *((value_t*)rsp) = val; + #ifndef UNSAFE_MODE + if ((rsp-rsb) <= rssz) { + #endif + rsp += sizeof(value_t); + *((value_t*)rsp) = val; + #ifndef UNSAFE_MODE + } else { + abort_on_error(1, ERR_RET_STACK_OVRFLW); + } + #endif } value_t onward_rspop(void) { value_t val = *((value_t*)rsp); rsp -= sizeof(value_t); + abort_on_error(rsp < rsb, ERR_RET_STACK_UNDRFLW); return val; } @@ -508,3 +537,11 @@ static value_t char_oneof(char ch, char* chs) { return ret; } +static void abort_on_error(value_t cond, value_t errcode) { + #ifndef UNSAFE_MODE + if(cond) { + errno = errcode; + _abort_code(); + } + #endif +} diff --git a/source/onward/onward.h b/source/onward/onward.h index b630b11..a08c151 100755 --- a/source/onward/onward.h +++ b/source/onward/onward.h @@ -98,6 +98,13 @@ typedef struct { onward_aspush(c_name); \ } +#define ERR_NONE (0x00) +#define ERR_UNKNOWN_WORD (0x01) +#define ERR_ARG_STACK_OVRFLW (0x02) +#define ERR_ARG_STACK_UNDRFLW (0x03) +#define ERR_RET_STACK_OVRFLW (0x04) +#define ERR_RET_STACK_UNDRFLW (0x05) + /** The number of bits that make up a stack cell */ #define SYS_BITCOUNT ((value_t)(sizeof(value_t) * 8u))