https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97754
Bug ID: 97754 Summary: arm/lib1funcs.S (RETLDM): CFI may be incorrect Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libgcc Assignee: unassigned at gcc dot gnu.org Reporter: martingalvan at sourceware dot org Target Milestone: --- Hi all, I'm looking at the RETLDM macro for the ARM libgcc code: .macro RETLDM regs=, cond=, unwind=, dirn=ia #if defined (__INTERWORKING__) .ifc "\regs","" ldr\cond lr, [sp], #8 .else # if defined(__thumb2__) pop\cond {\regs, lr} # else ldm\cond\dirn sp!, {\regs, lr} # endif .endif .ifnc "\unwind", "" /* Mark LR as restored. */ 97: cfi_pop 97b - \unwind, 0xe, 0x0 .endif bx\cond lr #else <...> .endm Here we can see that for the __INTERWORKING__ case, some CFI data is emitted if we have an 'unwind' argument. However, I believe this may be wrong if a RETLDM macro appears in the middle of another function. For the __INTERWORKING__ case, the resulting output would be e.g: pop {r4, r5, lr} cfi_pop <...> bx lr <rest of the function> Here, 'cfi_pop' would affect the rest of the function unless the caller is careful enough to restore the CFI status for lr after doing RETLDM. This can happen e.g. if we pass a 'cond' argument, which means the branch may not be taken. Unless I'm mistaken, the way to fix this would be to introduce a couple of .cfi_remember/restore_state directives: .ifnc "\unwind", "" /* Mark LR as restored. */ .cfi_remember_state 97: cfi_pop 97b - \unwind, 0xe, 0x0 .endif bx\cond lr .ifnc "\unwind", "" .cfi_restore_state .endif If this is correct, I'll send in a patch to add this change. Speaking of this file, I have a couple more questions: 1. The file is defining macros like cfi_start, cfi_push, etc which insert the CFI data directly in binary form. Why can't we use gas' .cfi_* directives as we do elsewhere? If we can, I'll send a separate patch to add this change as well. 2. Why is the __INTERWORKING__ macro only defined for ARMv4t? I'm not saying that this is wrong, just curious. Thanks.