Ping. Is anything else needed? On 26-06-17 12:27:35, Manjunath Matti wrote: > This looks good to me, I cannot approve it though. > > Adding the port maintainer to the list! > > Thanks, > > Manjunath S Matti. > > > On 16/06/26 11:15 am, 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, 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. > > > > Signed-off-by: Piotr Kubaj <[email protected]> > > --- > > Moved the macro to file scope as suggested. > > > > Changes since v1: > > * Move the TOC_SAVE_SLOT definition out of frob_update_context to file > > scope, alongside the other #defines, as suggested by Manjunath Matti. > > > > Tested on powerpc64le-unknown-freebsd15.1: a minimal throw/catch > > reproducer and a real "octave-cli pkg install" both succeed where they > > previously SIGSEGV'd. freebsd-unwind.h is not exercised by the usual > > bootstrap/regtest on Linux, so no on-target regtest line is offered. > > Inert on ELFv1. > > > > libgcc/config/rs6000/freebsd-unwind.h | 20 ++++++++++++++------ > > 1 file changed, 14 insertions(+), 6 deletions(-) > > > > diff --git a/libgcc/config/rs6000/freebsd-unwind.h > > b/libgcc/config/rs6000/freebsd-unwind.h > > index d97ed0c..6f9efd8 100644 > > --- a/libgcc/config/rs6000/freebsd-unwind.h > > +++ b/libgcc/config/rs6000/freebsd-unwind.h > > @@ -24,6 +24,14 @@ > > > > #define R_LR 65 > > > > +#ifdef __powerpc64__ > > +#if _CALL_ELF == 2 > > +#define TOC_SAVE_SLOT 24 > > +#else > > +#define TOC_SAVE_SLOT 40 > > +#endif > > +#endif > > + > > #define MD_FROB_UPDATE_CONTEXT frob_update_context > > > > static void > > @@ -40,9 +48,9 @@ frob_update_context (struct _Unwind_Context *context, > > figure out if it was saved. The big problem here is that the > > code that does the save/restore is generated by the linker, so > > we have no good way to determine at compile time what to do. */ > > - if (pc[0] == 0xF8410028 > > + if (pc[0] == 0xF8410000 + TOC_SAVE_SLOT > > || ((pc[0] & 0xFFFF0000) == 0x3D820000 > > - && pc[1] == 0xF8410028)) > > + && pc[1] == 0xF8410000 + TOC_SAVE_SLOT)) > > { > > /* We are in a plt call stub or r2 adjusting long branch stub, > > before r2 has been saved. Keep REG_UNSAVED. */ > > @@ -51,17 +59,17 @@ frob_update_context (struct _Unwind_Context *context, > > { > > unsigned int *insn > > = (unsigned int *) _Unwind_GetGR (context, R_LR); > > - if (insn && *insn == 0xE8410028) > > - _Unwind_SetGRPtr (context, 2, context->cfa + 40); > > + if (insn && *insn == 0xE8410000 + TOC_SAVE_SLOT) > > + _Unwind_SetGRPtr (context, 2, context->cfa + TOC_SAVE_SLOT); > > else if (pc[0] == 0x4E800421 > > - && pc[1] == 0xE8410028) > > + && pc[1] == 0xE8410000 + TOC_SAVE_SLOT) > > { > > /* We are at the bctrl instruction in a call via function > > pointer. gcc always emits the load of the new R2 just > > before the bctrl so this is the first and only place > > we need to use the stored R2. */ > > _Unwind_Word sp = _Unwind_GetGR (context, 1); > > - _Unwind_SetGRPtr (context, 2, (void *)(sp + 40)); > > + _Unwind_SetGRPtr (context, 2, (void *)(sp + TOC_SAVE_SLOT)); > > } > > } > > }
signature.asc
Description: PGP signature
