[llvm] r181010 - [SystemZ] Support System Z as host architecture

Ulrich Weigand ulrich.weigand at de.ibm.com
Fri May 3 05:22:12 PDT 2013


Author: uweigand
Date: Fri May  3 07:22:11 2013
New Revision: 181010

URL: http://llvm.org/viewvc/llvm-project?rev=181010&view=rev
Log:

[SystemZ] Support System Z as host architecture

The llvm::sys::AddSignalHandler function (as well as related routines) in
lib/Support/Unix/Signals.inc currently registers a signal handler routine
via "sigaction".  When this handler is called due to a SIGSEGV, SIGILL or
similar signal, it will show a stack backtrace, deactivate the handler,
and then simply return to the operating system.  The intent is that the
OS will now retry execution at the same location as before, which ought
to again trigger the same error condition and cause the same signal to be
delivered again.  Since the hander is now deactivated, the OS will take
its default action (usually, terminate the program and possibly create
a core dump).

However, this method doesn't work reliably on System Z:  With certain
signals (namely SIGILL, SIGFPE, and SIGTRAP), the program counter stored
by the kernel on the signal stack frame (which is the location where
execution will resume) is not the instruction that triggered the fault,
but then instruction *after it*.  When the LLVM signal handler simply
returns to the kernel, execution will then resume at *that* address,
which will not trigger the problem again, but simply go on and execute
potentially unrelated code leading to random errors afterwards.

To fix this, the patch simply goes and re-raises the signal in question
directly from the handler instead of returning from it.  This is done
only on System Z and only for those signals that have this particular
problem.


Modified:
    llvm/trunk/lib/Support/Unix/Signals.inc

Modified: llvm/trunk/lib/Support/Unix/Signals.inc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/Signals.inc?rev=181010&r1=181009&r2=181010&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Unix/Signals.inc (original)
+++ llvm/trunk/lib/Support/Unix/Signals.inc Fri May  3 07:22:11 2013
@@ -186,6 +186,15 @@ static RETSIGTYPE SignalHandler(int Sig)
   // Otherwise if it is a fault (like SEGV) run any handler.
   for (unsigned i = 0, e = CallBacksToRun.size(); i != e; ++i)
     CallBacksToRun[i].first(CallBacksToRun[i].second);
+
+#ifdef __s390__
+  // On S/390, certain signals are delivered with PSW Address pointing to
+  // *after* the faulting instruction.  Simply returning from the signal
+  // handler would continue execution after that point, instead of
+  // re-raising the signal.  Raise the signal manually in those cases.
+  if (Sig == SIGILL || Sig == SIGFPE || Sig == SIGTRAP)
+    raise(Sig);
+#endif
 }
 
 void llvm::sys::RunInterruptHandlers() {





More information about the llvm-commits mailing list