From: George Koehler Subject: macppc clang: add missing CFI for cr2, cr3, cr4 To: tech@openbsd.org Date: Tue, 27 Feb 2024 13:09:57 -0500 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 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)) {