gccarmsystem-callscortex-marmv6

Gcc naked attribute leaves some trailing function prologue asm instructions


I've the following implementation for a svc exception handler on a cortex-m0:

int  __attribute__((naked))  
sv_call_handler(uint32_t n, uint32_t arg1, uint32_t arg2, uint32_t arg3,  
                uint32_t arg4, uint32_t arg5)
 {
      irq_off();

When I built it for cortex-m0 it looks like this:

   0x7a50 <sv_call_handler>        movs   r4, r0                                                                    
   0x7a52 <sv_call_handler+2>      str    r1, [r7, #12]                                                             
   0x7a54 <sv_call_handler+4>      str    r2, [r7, #8]                                                              
   0x7a56 <sv_call_handler+6>      str    r3, [r7, #4]                                                              
   0x7a58 <sv_call_handler+8>      bl     0x3194 <irq_off> 

Resulting in a hard fault because of course, the value in R7 is 'undefined' and there is a high chance that it contains a value that isn't within the address range.

When I remove the naked attribute, the assembly makes much more sense:

   0x7a50 <sv_call_handler>        push   {r4, r5, r7, lr}                                                          
   0x7a52 <sv_call_handler+2>      sub    sp, #32                                                                   
   0x7a54 <sv_call_handler+4>      add    r7, sp, #8                                                                
   0x7a56 <sv_call_handler+6>      str    r0, [r7, #12]

I've used the naked attribute without issues before, so why does this happen now? Has it anything to do with the fact that the svc exception handler is a special case?


Solution

  • Don't use naked functions which take parameters. These parameters have to be handled by some prologue, which is highly likely not what you want.

    Better off writing it in assembly (IMO).