Everything

-stack_protector/-stack_protector_all [Professional Edition only] [V2.04.00 or later]


< Compile Options / Object Options >

[Format]

-stack_protector[=<numeric value>]
-stack_protector_all[=<numeric value>]

[Description]

-

This option generates a code for detection of stack smashing at the entry and the end of a function. A code for detection of stack smashing consists of instructions executing the three processes shown below.

(1) A 4-byte area is allocated just before (in the direction towards address 0xFFFFFFFF) the local variable area at the entry to a function, and the value specified by <number> is stored in the allocated area.

(2) At the end of the function, whether the 4-byte area in which <number> was stored has been rewritten is checked.

(3) If the 4-byte area has been rewritten in (2), the __stack_chk_fail function is called as the stack has been smashed.

-

A decimal number from 0 to 4294967295 should be specified in <number>. If the specification of <number> is omitted, the compiler automatically select the number.

-

The __stack_chk_fail function needs to be defined by the user. It should contain postprocesses for the detected stack smashing.

-

Note the following items when defining the __stack_chk_fail function.

-

The only possible type of return value is void and any formal parameters not allowed.

-

It is prohibited to call the __stack_chk_fail function as a normal function.

-

The __stack_chk_fail function is not subject to generating a code for detection of stack smashing due to the -stack_protector and -stack_protector_all options and #pragma stack_protector.

-

In a C++ program, add extern "C" to the definition or the declaration for __stack_chk_fail function.

-

Prevent returning to the caller (the function where stack smashing was detected) by taking measures such as calling abort() in __stack_chk_fail function and terminating the program.

-

Do not define the function as static.

-

If -stack_protector is specified, this option generates a code for detection of stack smashing for only functions having a structure, union, or array that exceeds eight bytes as a local variable. If -stack_protector_all is specified, this option generates a code for detection of stack smashing for all functions.

-

If these options are used simultaneously with #pragma stack_protector, the specification by #pragma stack_protector becomes valid.

-

Even though these options are specified, a code for detection of stack smashing is not generated for a functions for which one of the following #pragma directives is specified.

#pragma inline, #pragma inline_asm, #pragma entry, #pragma no_stack_protector

[Example]

-

<C source file>

#include <stdio.h>
#include <stdlib.h>
 
void f1()   // Sample program in which the stack is smashed
{
    volatile char str[10];
    int i;
    for (i = 0; i <= 10; i++){
       str[i] = i; // Stack is smashed when i=10
    }
}
 
#ifdef __cplusplus
extern "C" {
#endif
void __stack_chk_fail(void)
{
    printf("stack is broken!");
    abort();
}
#ifdef __cplusplus
}
#endif

-

<Output code>

When compilation is performed with -stack_protector=0 specified

    .glb    _test
    .glb    ___stack_chk_fail
    .glb    _printf
    .glb    _abort
    .SECTION        P,CODE
_test:
    .STACK  _test=20
    MOV.L #00000000H, R14   ; The specified <number> 0 is stored in the stack area.
    PUSH.L R14
    SUB #0CH, R0
    MOV.L #00000000H, R14
    MOV.L #0000000BH, R15
    ADD #02H, R0, R5
L12:    ; parse_bb
    MOV.B R14, [R5+]
    ADD #01H, R14
    SUB #01H, R15
    BNE L12
L13:    ; return
    MOV.L 0CH[R0], R14      ; Data is loaded from the location where <number> was
    CMP #00H, R14           ; stored at the entry to a function and it is compared 
                            ; with the specified <number> 0.
    BNE L15                 ; If they do not match, the program branches to L15.
L14:    ; return
    RTSD #10H
L15:    ; return
    BRA ___stack_chk_fail   ; __stack_chk_fail is called.
 
___stack_chk_fail:
    .STACK  ___stack_chk_fail=8
    SUB #04H, R0
    MOV.L #_L10, R14
    MOV.L R14, [R0]
    BSR _printf
    ADD #04H, R0
    BRA _abort
 
.SECTION            L,ROMDATA,ALIGN=4
_L10:
    .byte   "stack is broken!"
    .byte   00H
    .END