On Wed, Jul 22, 2026 at 03:45:04PM +0200, Piotr Kubaj wrote:
> From: Piotr Kubaj <[email protected]>
> 
> On powerpc64, when the unwind info for a frame does not explicitly
> describe how r2 (the TOC pointer) was saved -- which is the normal case
> for the linker-generated PLT call stubs -- frob_update_context inspects
> the code stream to locate the saved TOC and arranges for r2 to be
> restored from it.
> 
> The FreeBSD version of this hook hard-coded the ELFv1 TOC save slot
> offset of 40 bytes, matching "std r2,40(r1)" (0xF8410028) and
> "ld r2,40(r1)" (0xE8410028).  FreeBSD/powerpc64 (both big-endian and
> powerpc64le) uses ELFv2, where the TOC is saved at offset 24
> ("std r2,24(r1)" / "ld r2,24(r1)").  As a result the checks never
> matched, r2 was left unrestored, and code reached by unwinding -- e.g. a
> C++ catch handler in a different module than libgcc_s -- ran with the
> wrong TOC.  Any global or PLT access from such a handler then computed a
> bogus address, typically crashing.  This made C++ exceptions unusable on
> FreeBSD/powerpc64le whenever gcc's shared libgcc_s provided the unwinder
> (for instance any clang-built C++ program that pulls in libgfortran).
> 
> Define TOC_SAVE_SLOT based on _CALL_ELF (24 for ELFv2, 40 otherwise) and
> use it throughout, and guard the ELFv1-only code-reading cases (the old
> PLT stub form and the function pointer call sequence) with
> _CALL_ELF != 2, mirroring linux-unwind.h.
> 
> libgcc/ChangeLog:
> 
>       PR target/125803
>       * config/rs6000/freebsd-unwind.h (TOC_SAVE_SLOT): New macro,
>       defined according to _CALL_ELF.
>       (frob_update_context): Use TOC_SAVE_SLOT instead of the
>       hard-coded ELFv1 offset 40 when checking for and locating the
>       saved TOC, so that r2 is restored correctly under ELFv2.  Guard
>       the ELFv1-only PLT stub and function pointer call sequences
>       with _CALL_ELF != 2, mirroring linux-unwind.h.
> 
> Signed-off-by: Piotr Kubaj <[email protected]>
> ---
> Changes since v2:
>  * Guard the ELFv1-only old PLT stub form and the function pointer
>    call sequence with _CALL_ELF != 2, mirroring linux-unwind.h, as
>    suggested by Avinash Jayakar.
> 
> Changes since v1:
>  * Move the TOC_SAVE_SLOT definition to file scope, as suggested by
>    Manjunath Matti.

I approve this to be applied to the master branch and back ported to
GCC 16 if it is needed.  I assume you will fix any freebsd errors that
come up to this patch if it is needed.

-- 
Michael Meissner, IBM
PO Box 98, Ayer, Massachusetts, USA, 01432
email: [email protected]

Reply via email to