public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libgcc/97754] New: arm/lib1funcs.S (RETLDM): CFI may be incorrect
@ 2020-11-08  0:53 martingalvan at sourceware dot org
  0 siblings, 0 replies; only message in thread
From: martingalvan at sourceware dot org @ 2020-11-08  0:53 UTC (permalink / raw)
  To: gcc-bugs

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.

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-11-08  0:53 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-08  0:53 [Bug libgcc/97754] New: arm/lib1funcs.S (RETLDM): CFI may be incorrect martingalvan at sourceware dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).