summaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/host-darwin.c
diff options
context:
space:
mode:
authorgeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2003-02-06 01:47:56 +0000
committergeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2003-02-06 01:47:56 +0000
commitb197fbcf9fff937f22cfe62dfad1a2e48dafb21c (patch)
tree2afad0ecf8b6e8b262fccd46b90578858d21ab7a /gcc/config/rs6000/host-darwin.c
parent0cea7f1f3e001b19c39d678054af18b3e2608e65 (diff)
downloadgcc-b197fbcf9fff937f22cfe62dfad1a2e48dafb21c.tar.gz
* Makefile.in (host_hook_obj): New.
(OBJS): Add $(host_hook_obj). (host_default.o): New rule. * config.gcc (host_hook_obj): New, default to host-default.o. (powerpc-*-darwin*): Use host-darwin.o. (out_host_hook_obj): New. * configure: Regenerate. * configure.in: Print information about out_host_hook_obj, substitute into output files. * host-default.c: New file. * hosthooks.h: New file. * toplev.c (general_init): Call host_hooks.extra_signals. * config/rs6000/host-darwin.c: New file. * config/rs6000/x-darwin: New file. * doc/hostconfig.texi: Add documentation for new host hook. Rearrange existing documentation. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@62470 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/rs6000/host-darwin.c')
-rw-r--r--gcc/config/rs6000/host-darwin.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/gcc/config/rs6000/host-darwin.c b/gcc/config/rs6000/host-darwin.c
new file mode 100644
index 00000000000..874d691cf3c
--- /dev/null
+++ b/gcc/config/rs6000/host-darwin.c
@@ -0,0 +1,137 @@
+/* Darwin/powerpc host-specific hook definitions.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include <signal.h>
+#include <sys/ucontext.h>
+#include "hosthooks.h"
+#include "hosthooks-def.h"
+#include "toplev.h"
+
+static void segv_crash_handler PARAMS ((int));
+static void segv_handler PARAMS ((int, siginfo_t *, void *));
+static void darwin_rs6000_extra_signals PARAMS ((void));
+
+/* No prototype for this, filed as Radar 3150910. */
+extern int sigaltstack(const stack_t *, stack_t *);
+
+#undef HOST_HOOKS_EXTRA_SIGNALS
+#define HOST_HOOKS_EXTRA_SIGNALS darwin_rs6000_extra_signals
+
+/* On Darwin/powerpc, a stack fault can be detected as a SIGSEGV that
+ faulted on an instruction that's either
+ or
+ stwux %r1,xxx,%r1
+*/
+
+static void
+segv_crash_handler (sig)
+ int sig ATTRIBUTE_UNUSED;
+{
+ internal_error ("Segmentation Fault (code)");
+}
+
+static void
+segv_handler (sig, sip, scp)
+ int sig ATTRIBUTE_UNUSED;
+ siginfo_t *sip ATTRIBUTE_UNUSED;
+ void *scp;
+{
+ ucontext_t *uc = (ucontext_t *)scp;
+ unsigned faulting_insn;
+
+ /* The fault might have happened when trying to run some instruction, in
+ which case the next line will segfault _again_. Handle this case. */
+ signal (SIGSEGV, segv_crash_handler);
+
+ faulting_insn = *(unsigned *)uc->uc_mcontext->ss.srr0;
+
+ /* Note that this only has to work for GCC, so we don't have to deal
+ with all the possible cases (GCC has no AltiVec code, for
+ instance). It's complicated because Darwin allows stores to
+ below the stack pointer, and the prologue code takes advantage of
+ this. */
+
+ if ((faulting_insn & 0xFFFF8000) == 0x94218000 /* stwu %r1, -xxx(%r1) */
+ || (faulting_insn & 0xFFFF03FF) == 0x7C21016E /* stwux %r1, xxx, %r1 */
+ || (faulting_insn & 0xFC1F8000) == 0x90018000 /* stw xxx, -yyy(%r1) */
+ || (faulting_insn & 0xFC1F8000) == 0xD8018000 /* stfd xxx, -yyy(%r1) */
+ || (faulting_insn & 0xFC1F8000) == 0xBC018000 /* stmw xxx, -yyy(%r1) */)
+ {
+ char *shell_name;
+
+ fnotice (stderr, "Out of stack space.\n");
+ shell_name = getenv ("SHELL");
+ if (shell_name != NULL)
+ shell_name = strrchr (shell_name, '/');
+ if (shell_name != NULL)
+ {
+ static const char * shell_commands[][2] = {
+ { "sh", "ulimit -S -s unlimited" },
+ { "bash", "ulimit -S -s unlimited" },
+ { "tcsh", "limit stacksize unlimited" },
+ { "csh", "limit stacksize unlimited" },
+ /* zsh doesn't have "unlimited", this will work under the
+ default configuration. */
+ { "zsh", "limit stacksize 32m" }
+ };
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE (shell_commands); i++)
+ if (strcmp (shell_commands[i][0], shell_name + 1) == 0)
+ {
+ fnotice (stderr,
+ "Try running `%s' in the shell to raise its limit.\n",
+ shell_commands[i][1]);
+ }
+ }
+
+ exit (FATAL_EXIT_CODE);
+ }
+
+ fprintf (stderr, "[address=%08lx pc=%08x]\n",
+ uc->uc_mcontext->es.dar, uc->uc_mcontext->ss.srr0);
+ internal_error ("Segmentation Fault");
+ exit (FATAL_EXIT_CODE);
+}
+
+static void
+darwin_rs6000_extra_signals ()
+{
+ struct sigaction sact;
+ stack_t sigstk;
+
+ sigstk.ss_sp = xmalloc (SIGSTKSZ);
+ sigstk.ss_size = SIGSTKSZ;
+ sigstk.ss_flags = 0;
+ if (sigaltstack (&sigstk, NULL) < 0)
+ fatal_io_error ("While setting up signal stack");
+
+ sigemptyset(&sact.sa_mask);
+ sact.sa_flags = SA_ONSTACK | SA_SIGINFO;
+ sact.sa_sigaction = segv_handler;
+ if (sigaction (SIGSEGV, &sact, 0) < 0)
+ fatal_io_error ("While setting up signal handler");
+}
+
+const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;