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:
parent
01ffedd363
commit
3e5ed62469
7 changed files with 48 additions and 8 deletions
|
@ -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 */
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue