aboutsummaryrefslogtreecommitdiff
path: root/libgo/runtime/go-signal.c
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2010-12-03 04:34:57 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2010-12-03 04:34:57 +0000
commit7a9389330e91acc3ed05deac2d198af25d13cf3c (patch)
tree38fe54a4f38ede5d949c915d66191f24a6fe5153 /libgo/runtime/go-signal.c
parent1aa6700378e5188a853c018256113ce6e1fb5c05 (diff)
downloadgcc-7a9389330e91acc3ed05deac2d198af25d13cf3c.zip
gcc-7a9389330e91acc3ed05deac2d198af25d13cf3c.tar.gz
gcc-7a9389330e91acc3ed05deac2d198af25d13cf3c.tar.bz2
Add Go frontend, libgo library, and Go testsuite.
gcc/: * gcc.c (default_compilers): Add entry for ".go". * common.opt: Add -static-libgo as a driver option. * doc/install.texi (Configuration): Mention libgo as an option for --enable-shared. Mention go as an option for --enable-languages. * doc/invoke.texi (Overall Options): Mention .go as a file name suffix. Mention go as a -x option. * doc/frontends.texi (G++ and GCC): Mention Go as a supported language. * doc/sourcebuild.texi (Top Level): Mention libgo. * doc/standards.texi (Standards): Add section on Go language. Move references for other languages into their own section. * doc/contrib.texi (Contributors): Mention that I contributed the Go frontend. gcc/testsuite/: * lib/go.exp: New file. * lib/go-dg.exp: New file. * lib/go-torture.exp: New file. * lib/target-supports.exp (check_compile): Match // Go. From-SVN: r167407
Diffstat (limited to 'libgo/runtime/go-signal.c')
-rw-r--r--libgo/runtime/go-signal.c194
1 files changed, 194 insertions, 0 deletions
diff --git a/libgo/runtime/go-signal.c b/libgo/runtime/go-signal.c
new file mode 100644
index 0000000..8f44970
--- /dev/null
+++ b/libgo/runtime/go-signal.c
@@ -0,0 +1,194 @@
+/* go-signal.c -- signal handling for Go.
+
+ Copyright 2009 The Go Authors. All rights reserved.
+ Use of this source code is governed by a BSD-style
+ license that can be found in the LICENSE file. */
+
+#include <signal.h>
+#include <stdlib.h>
+
+#include "go-assert.h"
+#include "go-panic.h"
+#include "go-signal.h"
+
+#include "runtime.h"
+
+#undef int
+
+#ifndef SA_ONSTACK
+#define SA_ONSTACK 0
+#endif
+
+/* What to do for a signal. */
+
+struct sigtab
+{
+ /* Signal number. */
+ int sig;
+ /* Nonzero if the signal should be ignored. */
+ _Bool ignore;
+};
+
+/* What to do for signals. */
+
+static struct sigtab signals[] =
+{
+ { SIGHUP, 0 },
+ { SIGINT, 0 },
+ { SIGALRM, 1 },
+ { SIGTERM, 0 },
+#ifdef SIGBUS
+ { SIGBUS, 0 },
+#endif
+#ifdef SIGFPE
+ { SIGFPE, 0 },
+#endif
+#ifdef SIGUSR1
+ { SIGUSR1, 1 },
+#endif
+#ifdef SIGSEGV
+ { SIGSEGV, 0 },
+#endif
+#ifdef SIGUSR2
+ { SIGUSR2, 1 },
+#endif
+#ifdef SIGPIPE
+ { SIGPIPE, 1 },
+#endif
+#ifdef SIGCHLD
+ { SIGCHLD, 1 },
+#endif
+#ifdef SIGTSTP
+ { SIGTSTP, 1 },
+#endif
+#ifdef SIGTTIN
+ { SIGTTIN, 1 },
+#endif
+#ifdef SIGTTOU
+ { SIGTTOU, 1 },
+#endif
+#ifdef SIGURG
+ { SIGURG, 1 },
+#endif
+#ifdef SIGXCPU
+ { SIGXCPU, 1 },
+#endif
+#ifdef SIGXFSZ
+ { SIGXFSZ, 1 },
+#endif
+#ifdef SIGVTARLM
+ { SIGVTALRM, 1 },
+#endif
+#ifdef SIGPROF
+ { SIGPROF, 1 },
+#endif
+#ifdef SIGWINCH
+ { SIGWINCH, 1 },
+#endif
+#ifdef SIGIO
+ { SIGIO, 1 },
+#endif
+#ifdef SIGPWR
+ { SIGPWR, 1 },
+#endif
+ { -1, 0 }
+};
+
+/* The Go signal handler. */
+
+static void
+sighandler (int sig)
+{
+ const char *msg;
+ int i;
+
+ /* FIXME: Should check siginfo for more information when
+ available. */
+ msg = NULL;
+ switch (sig)
+ {
+#ifdef SIGBUS
+ case SIGBUS:
+ msg = "invalid memory address or nil pointer dereference";
+ break;
+#endif
+
+#ifdef SIGFPE
+ case SIGFPE:
+ msg = "integer divide by zero or floating point error";
+ break;
+#endif
+
+#ifdef SIGSEGV
+ case SIGSEGV:
+ msg = "invalid memory address or nil pointer dereference";
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ if (msg != NULL)
+ {
+ sigset_t clear;
+
+ /* The signal handler blocked signals; unblock them. */
+ i = sigfillset (&clear);
+ __go_assert (i == 0);
+ i = sigprocmask (SIG_UNBLOCK, &clear, NULL);
+ __go_assert (i == 0);
+
+ __go_panic_msg (msg);
+ }
+
+ if (__go_sigsend (sig))
+ return;
+ for (i = 0; signals[i].sig != -1; ++i)
+ {
+ if (signals[i].sig == sig)
+ {
+ struct sigaction sa;
+
+ if (signals[i].ignore)
+ return;
+
+ memset (&sa, 0, sizeof sa);
+
+ sa.sa_handler = SIG_DFL;
+
+ i = sigemptyset (&sa.sa_mask);
+ __go_assert (i == 0);
+
+ if (sigaction (sig, &sa, NULL) != 0)
+ abort ();
+
+ raise (sig);
+ exit (2);
+ }
+ }
+ abort ();
+}
+
+/* Initialize signal handling for Go. This is called when the program
+ starts. */
+
+void
+__initsig ()
+{
+ struct sigaction sa;
+ int i;
+
+ siginit ();
+
+ memset (&sa, 0, sizeof sa);
+
+ sa.sa_handler = sighandler;
+
+ i = sigfillset (&sa.sa_mask);
+ __go_assert (i == 0);
+
+ for (i = 0; signals[i].sig != -1; ++i)
+ if (sigaction (signals[i].sig, &sa, NULL) != 0)
+ __go_assert (0);
+}