Index | Thread | Search

From:
George Koehler <kernigh@gmail.com>
Subject:
macppc clang: add missing CFI for cr2, cr3, cr4
To:
tech@openbsd.org
Date:
Tue, 27 Feb 2024 13:09:57 -0500

Download raw body.

Thread
  • George Koehler:

    macppc clang: add missing CFI for cr2, cr3, cr4

clang and llvm miscompiled some code for OpenBSD/macppc, by forgetting
the CFI for fields cr2, cr3, cr4 in the condition register.  This diff
adds the CFI and fixes at least egdb from ports/devel/gdb.  The
miscompiled gdb crashed when I typed q to quit a disassembly,

$ egdb awk
...
(gdb) run
...
(gdb) disas malloc
...
   0xd11251f4 <+84>:    mflr    r30                                             
--Type <RET> for more, q to quit, c to continue without paging--q               

The q to quit threw a C++ exception, which ran some code with the
wrong value in cr2.  The code crashed on a null pointer; gdb caught
the SIGSEGV but called abort(3).  After I built clang with this diff
and rebuilt gdb, it stops crashing here.

This diff only affects 32-bit ELF, doesn't fix a different problem
where most C++ exceptions crash on powerpc64.

I have a small C++ example which reproduced the crash at
https://github.com/llvm/llvm-project/issues/83094

I have proposed this diff to upstream as
https://github.com/llvm/llvm-project/pull/83098

ok to commit?

Index: llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
===================================================================
RCS file: /cvs/src/gnu/llvm/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp,v
diff -u -p -r1.5 PPCFrameLowering.cpp
--- llvm/lib/Target/PowerPC/PPCFrameLowering.cpp	11 Nov 2023 18:14:32 -0000	1.5
+++ llvm/lib/Target/PowerPC/PPCFrameLowering.cpp	21 Feb 2024 01:12:24 -0000
@@ -1193,12 +1193,6 @@ void PPCFrameLowering::emitPrologue(Mach
       if ((Reg == PPC::X2 || Reg == PPC::R2) && MustSaveTOC)
         continue;
 
-      // For SVR4, don't emit a move for the CR spill slot if we haven't
-      // spilled CRs.
-      if (isSVR4ABI && (PPC::CR2 <= Reg && Reg <= PPC::CR4)
-          && !MustSaveCR)
-        continue;
-
       // For 64-bit SVR4 when we have spilled CRs, the spill location
       // is SP+8, not a frame-relative slot.
       if (isSVR4ABI && isPPC64 && (PPC::CR2 <= Reg && Reg <= PPC::CR4)) {