]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/host-darwin.c
Update copyright years.
[thirdparty/gcc.git] / gcc / config / rs6000 / host-darwin.c
CommitLineData
b197fbcf 1/* Darwin/powerpc host-specific hook definitions.
f1717362 2 Copyright (C) 2003-2016 Free Software Foundation, Inc.
b197fbcf 3
3a5a28e2 4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published
038d1e19 8 by the Free Software Foundation; either version 3, or (at your
3a5a28e2 9 option) any later version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
15
16 You should have received a copy of the GNU General Public License
038d1e19 17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
b197fbcf 19
20#include "config.h"
21#include "system.h"
22#include "coretypes.h"
c1eb80de 23#include "diagnostic.h"
b197fbcf 24#include <sys/ucontext.h>
25#include "hosthooks.h"
26#include "hosthooks-def.h"
388807ab 27#include "config/host-darwin.h"
b197fbcf 28
19e03a46 29static void segv_crash_handler (int);
30static void segv_handler (int, siginfo_t *, void *);
31static void darwin_rs6000_extra_signals (void);
b197fbcf 32
168c58e0 33#ifndef HAVE_DECL_SIGALTSTACK
19e03a46 34/* This doesn't have a prototype in signal.h in 10.2.x and earlier,
35 fixed in later releases. */
36extern int sigaltstack(const struct sigaltstack *, struct sigaltstack *);
168c58e0 37#endif
38
39/* The fields of the mcontext_t type have acquired underscores in later
40 OS versions. */
41#ifdef HAS_MCONTEXT_T_UNDERSCORES
42#define MC_FLD(x) __ ## x
43#else
44#define MC_FLD(x) x
45#endif
b197fbcf 46
47#undef HOST_HOOKS_EXTRA_SIGNALS
48#define HOST_HOOKS_EXTRA_SIGNALS darwin_rs6000_extra_signals
49
73e4dc72 50/* On Darwin/powerpc, hitting the stack limit turns into a SIGSEGV.
51 This code detects the difference between hitting the stack limit and
52 a true wild pointer dereference by looking at the instruction that
53 faulted; only a few kinds of instruction are used to access below
54 the previous bottom of the stack. */
b197fbcf 55
56static void
19e03a46 57segv_crash_handler (int sig ATTRIBUTE_UNUSED)
b197fbcf 58{
59 internal_error ("Segmentation Fault (code)");
60}
61
62static void
19e03a46 63segv_handler (int sig ATTRIBUTE_UNUSED,
64 siginfo_t *sip ATTRIBUTE_UNUSED,
65 void *scp)
b197fbcf 66{
67 ucontext_t *uc = (ucontext_t *)scp;
91732c81 68 sigset_t sigset;
b197fbcf 69 unsigned faulting_insn;
70
71 /* The fault might have happened when trying to run some instruction, in
72 which case the next line will segfault _again_. Handle this case. */
73 signal (SIGSEGV, segv_crash_handler);
91732c81 74 sigemptyset (&sigset);
75 sigaddset (&sigset, SIGSEGV);
76 sigprocmask (SIG_UNBLOCK, &sigset, NULL);
b197fbcf 77
168c58e0 78 faulting_insn = *(unsigned *)uc->uc_mcontext->MC_FLD(ss).MC_FLD(srr0);
b197fbcf 79
80 /* Note that this only has to work for GCC, so we don't have to deal
81 with all the possible cases (GCC has no AltiVec code, for
82 instance). It's complicated because Darwin allows stores to
83 below the stack pointer, and the prologue code takes advantage of
84 this. */
85
86 if ((faulting_insn & 0xFFFF8000) == 0x94218000 /* stwu %r1, -xxx(%r1) */
cc21cbe7 87 || (faulting_insn & 0xFC1F03FF) == 0x7C01016E /* stwux xxx, %r1, xxx */
b197fbcf 88 || (faulting_insn & 0xFC1F8000) == 0x90018000 /* stw xxx, -yyy(%r1) */
89 || (faulting_insn & 0xFC1F8000) == 0xD8018000 /* stfd xxx, -yyy(%r1) */
90 || (faulting_insn & 0xFC1F8000) == 0xBC018000 /* stmw xxx, -yyy(%r1) */)
91 {
92 char *shell_name;
93
94 fnotice (stderr, "Out of stack space.\n");
95 shell_name = getenv ("SHELL");
96 if (shell_name != NULL)
97 shell_name = strrchr (shell_name, '/');
98 if (shell_name != NULL)
99 {
100 static const char * shell_commands[][2] = {
101 { "sh", "ulimit -S -s unlimited" },
102 { "bash", "ulimit -S -s unlimited" },
103 { "tcsh", "limit stacksize unlimited" },
104 { "csh", "limit stacksize unlimited" },
105 /* zsh doesn't have "unlimited", this will work under the
106 default configuration. */
107 { "zsh", "limit stacksize 32m" }
108 };
109 size_t i;
110
111 for (i = 0; i < ARRAY_SIZE (shell_commands); i++)
112 if (strcmp (shell_commands[i][0], shell_name + 1) == 0)
113 {
114 fnotice (stderr,
1e5fcbe2 115 "Try running '%s' in the shell to raise its limit.\n",
b197fbcf 116 shell_commands[i][1]);
117 }
118 }
119
585fefa7 120 if (global_dc->abort_on_error)
27d2baef 121 fancy_abort (__FILE__, __LINE__, __FUNCTION__);
585fefa7 122
b197fbcf 123 exit (FATAL_EXIT_CODE);
124 }
125
126 fprintf (stderr, "[address=%08lx pc=%08x]\n",
168c58e0 127 uc->uc_mcontext->MC_FLD(es).MC_FLD(dar),
128 uc->uc_mcontext->MC_FLD(ss).MC_FLD(srr0));
b197fbcf 129 internal_error ("Segmentation Fault");
130 exit (FATAL_EXIT_CODE);
131}
132
133static void
19e03a46 134darwin_rs6000_extra_signals (void)
b197fbcf 135{
136 struct sigaction sact;
137 stack_t sigstk;
138
ede24ab1 139 sigstk.ss_sp = (char*)xmalloc (SIGSTKSZ);
b197fbcf 140 sigstk.ss_size = SIGSTKSZ;
141 sigstk.ss_flags = 0;
142 if (sigaltstack (&sigstk, NULL) < 0)
c05be867 143 fatal_error (input_location, "While setting up signal stack: %m");
b197fbcf 144
145 sigemptyset(&sact.sa_mask);
146 sact.sa_flags = SA_ONSTACK | SA_SIGINFO;
147 sact.sa_sigaction = segv_handler;
148 if (sigaction (SIGSEGV, &sact, 0) < 0)
c05be867 149 fatal_error (input_location, "While setting up signal handler: %m");
b197fbcf 150}
ddf4604f 151\f
b197fbcf 152
153const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;