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
This commit is contained in:
cuz 2001-03-19 23:01:35 +00:00
parent 01ffedd363
commit 3e5ed62469
7 changed files with 48 additions and 8 deletions

View file

@ -2507,14 +2507,22 @@ void g_space (int space)
/* Create or drop space on the stack */ /* Create or drop space on the stack */
{ {
if (space < 0) { if (space < 0) {
mod_internal (-space, "inc", "addy"); mod_internal (-space, "inc", "addy");
} else if (space > 0) { } 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) void g_add (unsigned flags, unsigned long val)
/* Primary = TOS + Primary */ /* Primary = TOS + Primary */
{ {

View file

@ -371,6 +371,9 @@ void g_falsejump (unsigned flags, unsigned label);
void g_space (int space); void g_space (int space);
/* Create or drop space on the stack */ /* 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_add (unsigned flags, unsigned long val);
void g_sub (unsigned flags, unsigned long val); void g_sub (unsigned flags, unsigned long val);
void g_rsub (unsigned flags, unsigned long val); void g_rsub (unsigned flags, unsigned long val);

View file

@ -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 DebugInfo = 0; /* Add debug info to the obj */
unsigned char Debug = 0; /* Debug mode */ unsigned char Debug = 0; /* Debug mode */
unsigned char CreateDep = 0; /* Create a dependency file */ unsigned char CreateDep = 0; /* Create a dependency file */
unsigned char CheckStack = 0; /* Generate stack overflow checks */

View file

@ -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 DebugInfo; /* Add debug info to the obj */
extern unsigned char Debug; /* Debug mode */ extern unsigned char Debug; /* Debug mode */
extern unsigned char CreateDep; /* Create a dependency file */ extern unsigned char CreateDep; /* Create a dependency file */
extern unsigned char CheckStack; /* Generate stack overflow checks */
/* End of global.h */ /* End of global.h */

View file

@ -322,6 +322,9 @@ static void ParseOneDecl (const DeclSpec* Spec)
void DeclareLocals (void) void DeclareLocals (void)
/* Declare local variables and types. */ /* Declare local variables and types. */
{ {
/* Remember the current stack pointer */
int InitialStack = oursp;
/* Loop until we don't find any more variables */ /* Loop until we don't find any more variables */
while (1) { while (1) {
@ -370,6 +373,13 @@ void DeclareLocals (void)
/* In case we switched away from code segment, switch back now */ /* In case we switched away from code segment, switch back now */
g_usecode (); 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 ();
}
} }

View file

@ -97,6 +97,7 @@ static void Usage (void)
"Long options:\n" "Long options:\n"
" --ansi\t\tStrict ANSI mode\n" " --ansi\t\tStrict ANSI mode\n"
" --bss-name seg\tSet the name of the BSS segment\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" " --code-name seg\tSet the name of the CODE segment\n"
" --cpu type\t\tSet cpu type\n" " --cpu type\t\tSet cpu type\n"
" --data-name seg\tSet the name of the DATA segment\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) static void OptCodeName (const char* Opt, const char* Arg)
/* Handle the --code-name option */ /* Handle the --code-name option */
{ {
@ -433,6 +442,7 @@ int main (int argc, char* argv[])
{ "--add-source", 0, OptAddSource }, { "--add-source", 0, OptAddSource },
{ "--ansi", 0, OptAnsi }, { "--ansi", 0, OptAnsi },
{ "--bss-name", 1, OptBssName }, { "--bss-name", 1, OptBssName },
{ "--check-stack", 0, OptCheckStack },
{ "--code-name", 1, OptCodeName }, { "--code-name", 1, OptCodeName },
{ "--create-dep", 0, OptCreateDep }, { "--create-dep", 0, OptCreateDep },
{ "--cpu", 1, OptCPU }, { "--cpu", 1, OptCPU },
@ -442,11 +452,11 @@ int main (int argc, char* argv[])
{ "--help", 0, OptHelp }, { "--help", 0, OptHelp },
{ "--include-dir", 1, OptIncludeDir }, { "--include-dir", 1, OptIncludeDir },
{ "--rodata-name", 1, OptRodataName }, { "--rodata-name", 1, OptRodataName },
{ "--signed-chars", 0, OptSignedChars }, { "--signed-chars", 0, OptSignedChars },
{ "--static-locals", 0, OptStaticLocals }, { "--static-locals", 0, OptStaticLocals },
{ "--target", 1, OptTarget }, { "--target", 1, OptTarget },
{ "--verbose", 0, OptVerbose }, { "--verbose", 0, OptVerbose },
{ "--version", 0, OptVersion }, { "--version", 0, OptVersion },
}; };
int I; int I;

View file

@ -58,6 +58,7 @@
/* Tokens for the #pragmas */ /* Tokens for the #pragmas */
typedef enum { typedef enum {
PR_BSSSEG, PR_BSSSEG,
PR_CHECKSTACK,
PR_CODESEG, PR_CODESEG,
PR_DATASEG, PR_DATASEG,
PR_REGVARADDR, PR_REGVARADDR,
@ -74,6 +75,7 @@ static const struct Pragma {
pragma_t Tok; /* Token */ pragma_t Tok; /* Token */
} Pragmas[] = { } Pragmas[] = {
{ "bssseg", PR_BSSSEG }, { "bssseg", PR_BSSSEG },
{ "checkstack", PR_CHECKSTACK },
{ "codeseg", PR_CODESEG }, { "codeseg", PR_CODESEG },
{ "dataseg", PR_DATASEG }, { "dataseg", PR_DATASEG },
{ "regvaraddr", PR_REGVARADDR }, { "regvaraddr", PR_REGVARADDR },
@ -217,6 +219,10 @@ void DoPragma (void)
SegNamePragma (g_bssname); SegNamePragma (g_bssname);
break; break;
case PR_CHECKSTACK:
FlagPragma (&CheckStack);
break;
case PR_CODESEG: case PR_CODESEG:
SegNamePragma (g_codename); SegNamePragma (g_codename);
break; break;