Hi Everyone,

I'm working on an issue with László Böszörményi, who is our Debian
package maintainer. We have it narrowed down to Debian, GCC 10.2.1 and
POWER8. Also https://github.com/weidai11/cryptopp/issues/986 and
https://buildd.debian.org/status/fetch.php?pkg=libcrypto%2B%2B&arch=ppc64el&ver=8.3.0-1&stamp=1608488187&raw=0.

It appears GCC 10.2.1 is having trouble restarting a signal handler
after a signal has fired. Here is the code with the cruft trimmed (and
error checking trimmed)
(https://github.com/weidai11/cryptopp/blob/master/ppc_power9.cpp#L42):

bool CPU_ProbePower9()
{
    volatile int result = true;
    volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler);
    volatile sigset_t oldMask = sigprocmask(0, NULLPTR, (sigset_t*)&oldMask);

    if (setjmp(s_jmpSIGILL))
        result = false;
    else
    {
        // This is "darn r3, 0".
#if CRYPTOPP_BIG_ENDIAN
        __asm__ __volatile__ (".byte 0x7c, 0x60, 0x05, 0xe6  \n" : : : "r3");
#else
        __asm__ __volatile__ (".byte 0xe6, 0x05, 0x60, 0x7c  \n" : : : "r3");
#endif
        result = true;
    }

    sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR);
    signal(SIGILL, oldHandler);
    return result;
}

On POWER8, the darn insn causes a SIGILL. That is expected, and we
have a handler installed for it (the static jump buff called
s_jmpSIGILL).

However, when we re-enter at setjmp() to set the feature flag to
false, the code SIGILL's on the assignment 'result = false;'

The code has worked well for years (and decades in some instances).

I found a few reports in GCC Bugzilla but they are antique.
https://gcc.gnu.org/bugzilla/buglist.cgi?bug_status=__open__&content=POWER8%20setjmp%20SIGILL&list_id=287518&order=Importance&query_format=specific.

Is anyone aware of problems with Debian POWER8 , GCC 10.2.1 and use of setjmp?

Thanks in advance.

Reply via email to