From 3e5ed624698fce79a1b053d05661c219d286c03f Mon Sep 17 00:00:00 2001 From: cuz Date: Mon, 19 Mar 2001 23:01:35 +0000 Subject: [PATCH] Added new option and pragma to generate calls to a stack checking routine git-svn-id: svn://svn.cc65.org/cc65/trunk@631 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/codegen.c | 14 +++++++++++--- src/cc65/codegen.h | 3 +++ src/cc65/global.c | 2 ++ src/cc65/global.h | 1 + src/cc65/locals.c | 10 ++++++++++ src/cc65/main.c | 20 +++++++++++++++----- src/cc65/pragma.c | 6 ++++++ 7 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 3afcc25b2..b04ac4b38 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -525,7 +525,7 @@ void g_leave (int flags, int val) strcat (buf, "y"); } else { /* Y register no longer used */ - AddCodeHint ("y:-"); + AddCodeHint ("y:-"); } if (flags & CF_CONST) { if ((flags & CF_TYPE) != CF_LONG) { @@ -2507,14 +2507,22 @@ void g_space (int space) /* Create or drop space on the stack */ { if (space < 0) { - mod_internal (-space, "inc", "addy"); + mod_internal (-space, "inc", "addy"); } else if (space > 0) { - mod_internal (space, "dec", "suby"); + mod_internal (space, "dec", "suby"); } } +void g_stackcheck (void) +/* Check for a stack overflow */ +{ + AddCodeLine ("\tjsr\tstkchk"); +} + + + void g_add (unsigned flags, unsigned long val) /* Primary = TOS + Primary */ { diff --git a/src/cc65/codegen.h b/src/cc65/codegen.h index 394a550b5..f568e8152 100644 --- a/src/cc65/codegen.h +++ b/src/cc65/codegen.h @@ -371,6 +371,9 @@ void g_falsejump (unsigned flags, unsigned label); void g_space (int space); /* Create or drop space on the stack */ +void g_stackcheck (void); +/* Check for a stack overflow */ + void g_add (unsigned flags, unsigned long val); void g_sub (unsigned flags, unsigned long val); void g_rsub (unsigned flags, unsigned long val); diff --git a/src/cc65/global.c b/src/cc65/global.c index 97beb8ab5..3aa3f22fa 100644 --- a/src/cc65/global.c +++ b/src/cc65/global.c @@ -58,6 +58,8 @@ unsigned char AddSource = 0; /* Add source lines as comments */ unsigned char DebugInfo = 0; /* Add debug info to the obj */ unsigned char Debug = 0; /* Debug mode */ unsigned char CreateDep = 0; /* Create a dependency file */ +unsigned char CheckStack = 0; /* Generate stack overflow checks */ + diff --git a/src/cc65/global.h b/src/cc65/global.h index 593e2f0f2..bd3a4865b 100644 --- a/src/cc65/global.h +++ b/src/cc65/global.h @@ -59,6 +59,7 @@ extern unsigned char AddSource; /* Add source lines as comments */ extern unsigned char DebugInfo; /* Add debug info to the obj */ extern unsigned char Debug; /* Debug mode */ extern unsigned char CreateDep; /* Create a dependency file */ +extern unsigned char CheckStack; /* Generate stack overflow checks */ /* End of global.h */ diff --git a/src/cc65/locals.c b/src/cc65/locals.c index af3d169f3..c0083ac28 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -322,6 +322,9 @@ static void ParseOneDecl (const DeclSpec* Spec) void DeclareLocals (void) /* Declare local variables and types. */ { + /* Remember the current stack pointer */ + int InitialStack = oursp; + /* Loop until we don't find any more variables */ while (1) { @@ -370,6 +373,13 @@ void DeclareLocals (void) /* In case we switched away from code segment, switch back now */ g_usecode (); + + /* In case we've allocated local variables in this block, emit a call to + * the stack checking routine if stack checks are enabled. + */ + if (CheckStack && InitialStack != oursp) { + g_stackcheck (); + } } diff --git a/src/cc65/main.c b/src/cc65/main.c index 73f8382c9..460d55e33 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -97,6 +97,7 @@ static void Usage (void) "Long options:\n" " --ansi\t\tStrict ANSI mode\n" " --bss-name seg\tSet the name of the BSS segment\n" + " --check-stack\tGenerate stack overflow checks\n" " --code-name seg\tSet the name of the CODE segment\n" " --cpu type\t\tSet cpu type\n" " --data-name seg\tSet the name of the DATA segment\n" @@ -293,6 +294,14 @@ static void OptBssName (const char* Opt, const char* Arg) +static void OptCheckStack (const char* Opt, const char* Arg) +/* Handle the --check-stack option */ +{ + CheckStack = 1; +} + + + static void OptCodeName (const char* Opt, const char* Arg) /* Handle the --code-name option */ { @@ -433,6 +442,7 @@ int main (int argc, char* argv[]) { "--add-source", 0, OptAddSource }, { "--ansi", 0, OptAnsi }, { "--bss-name", 1, OptBssName }, + { "--check-stack", 0, OptCheckStack }, { "--code-name", 1, OptCodeName }, { "--create-dep", 0, OptCreateDep }, { "--cpu", 1, OptCPU }, @@ -442,11 +452,11 @@ int main (int argc, char* argv[]) { "--help", 0, OptHelp }, { "--include-dir", 1, OptIncludeDir }, { "--rodata-name", 1, OptRodataName }, - { "--signed-chars", 0, OptSignedChars }, - { "--static-locals", 0, OptStaticLocals }, - { "--target", 1, OptTarget }, - { "--verbose", 0, OptVerbose }, - { "--version", 0, OptVersion }, + { "--signed-chars", 0, OptSignedChars }, + { "--static-locals", 0, OptStaticLocals }, + { "--target", 1, OptTarget }, + { "--verbose", 0, OptVerbose }, + { "--version", 0, OptVersion }, }; int I; diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index b4b9bae16..0ef31083d 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -58,6 +58,7 @@ /* Tokens for the #pragmas */ typedef enum { PR_BSSSEG, + PR_CHECKSTACK, PR_CODESEG, PR_DATASEG, PR_REGVARADDR, @@ -74,6 +75,7 @@ static const struct Pragma { pragma_t Tok; /* Token */ } Pragmas[] = { { "bssseg", PR_BSSSEG }, + { "checkstack", PR_CHECKSTACK }, { "codeseg", PR_CODESEG }, { "dataseg", PR_DATASEG }, { "regvaraddr", PR_REGVARADDR }, @@ -217,6 +219,10 @@ void DoPragma (void) SegNamePragma (g_bssname); break; + case PR_CHECKSTACK: + FlagPragma (&CheckStack); + break; + case PR_CODESEG: SegNamePragma (g_codename); break; -- 2.39.5