-
Notifications
You must be signed in to change notification settings - Fork 49
Description
If we use stack variables in function (and if frame pointer is enabled) we address to the stack variables using access relative to FP register (instead of SP). The advantages of such FP usage are not clear and there is one big issue with it - the ARC HW stack checking checks the instructions, which use SP as the base register - so if we use FP the illegal access to stack are not caught by HW.
The simplest way to reproduce such behavior is to build code without optimization, i.e.:
0000007c <stack_smasher>:
7c: c3e2 enter_s [r13,fp,blink]
7e: c1a2 sub_s sp,sp,0x8
80: 1bf8 b000 st r0,[fp,-8] // <<----
84: 13f8 b002 ld r2,[fp,-8] // <<----
88: 1bfc b080 st r2,[fp,-4] // <<----
8c: 13fc b002 ld r2,[fp,-4] // <<----
90: 6a51 asl_s r2,r2,0x1
92: 4040 mov_s r0,r2
94: 0fea ffcf bl -24 ;7c <stack_smasher>
98: 4508 mov_s r13,r0
.....It's not clear why we use FP instead of SP here and if there is a way to avoid it (without just disabling frame pointer for the build).
Note that we can easily replace FP by SP here without making code bigger, etc.. Here is an example:
original asm:
0000007c <stack_smasher>:
7c: c3e2 enter_s [r13,fp,blink]
7e: c1a2 sub_s sp,sp,0x8
80: 1bf8 b000 st r0,[fp,-8]
84: 13f8 b002 ld r2,[fp,-8]
88: 1bfc b080 st r2,[fp,-4]
8c: 13fc b002 ld r2,[fp,-4]
90: 6a51 asl_s r2,r2,0x1
92: 4040 mov_s r0,r2
.....alternative asm:
0000007c <stack_smasher>:
7c: c3e2 enter_s [r13,fp,blink]
7e: c1a2 sub_s sp,sp,0x8
80: 1bf8 b000 st r0,[sp]
84: 13f8 b002 ld r2,[sp]
88: 1bfc b080 st r2,[sp, 4]
8c: 13fc b002 ld r2,[sp, 4]
90: 6a51 asl_s r2,r2,0x1
92: 4040 mov_s r0,r2
.....NOTE: the MWDT toolchain generates access to the stack variables with SP used as a base (so HW stack checking works correctly) and the issue exists only with GNU toolchain.