summaryrefslogtreecommitdiff
path: root/contrib/gcc/config/rs6000/host-darwin.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/config/rs6000/host-darwin.c')
-rw-r--r--contrib/gcc/config/rs6000/host-darwin.c93
1 files changed, 24 insertions, 69 deletions
diff --git a/contrib/gcc/config/rs6000/host-darwin.c b/contrib/gcc/config/rs6000/host-darwin.c
index d04270c3675bf..be0c55f312a06 100644
--- a/contrib/gcc/config/rs6000/host-darwin.c
+++ b/contrib/gcc/config/rs6000/host-darwin.c
@@ -1,5 +1,5 @@
/* Darwin/powerpc host-specific hook definitions.
- Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GCC.
@@ -15,27 +15,37 @@
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. */
+ Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include <signal.h>
#include <sys/ucontext.h>
-#include <sys/mman.h>
#include "hosthooks.h"
#include "hosthooks-def.h"
#include "toplev.h"
#include "diagnostic.h"
+#include "config/host-darwin.h"
static void segv_crash_handler (int);
static void segv_handler (int, siginfo_t *, void *);
static void darwin_rs6000_extra_signals (void);
+#ifndef HAVE_DECL_SIGALTSTACK
/* This doesn't have a prototype in signal.h in 10.2.x and earlier,
fixed in later releases. */
extern int sigaltstack(const struct sigaltstack *, struct sigaltstack *);
+#endif
+
+/* The fields of the mcontext_t type have acquired underscores in later
+ OS versions. */
+#ifdef HAS_MCONTEXT_T_UNDERSCORES
+#define MC_FLD(x) __ ## x
+#else
+#define MC_FLD(x) x
+#endif
#undef HOST_HOOKS_EXTRA_SIGNALS
#define HOST_HOOKS_EXTRA_SIGNALS darwin_rs6000_extra_signals
@@ -58,13 +68,17 @@ segv_handler (int sig ATTRIBUTE_UNUSED,
void *scp)
{
ucontext_t *uc = (ucontext_t *)scp;
+ sigset_t sigset;
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);
+ sigemptyset (&sigset);
+ sigaddset (&sigset, SIGSEGV);
+ sigprocmask (SIG_UNBLOCK, &sigset, NULL);
- faulting_insn = *(unsigned *)uc->uc_mcontext->ss.srr0;
+ faulting_insn = *(unsigned *)uc->uc_mcontext->MC_FLD(ss).MC_FLD(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
@@ -73,7 +87,7 @@ segv_handler (int sig ATTRIBUTE_UNUSED,
this. */
if ((faulting_insn & 0xFFFF8000) == 0x94218000 /* stwu %r1, -xxx(%r1) */
- || (faulting_insn & 0xFFFF03FF) == 0x7C21016E /* stwux %r1, xxx, %r1 */
+ || (faulting_insn & 0xFC1F03FF) == 0x7C01016E /* stwux xxx, %r1, xxx */
|| (faulting_insn & 0xFC1F8000) == 0x90018000 /* stw xxx, -yyy(%r1) */
|| (faulting_insn & 0xFC1F8000) == 0xD8018000 /* stfd xxx, -yyy(%r1) */
|| (faulting_insn & 0xFC1F8000) == 0xBC018000 /* stmw xxx, -yyy(%r1) */)
@@ -101,19 +115,20 @@ segv_handler (int sig ATTRIBUTE_UNUSED,
if (strcmp (shell_commands[i][0], shell_name + 1) == 0)
{
fnotice (stderr,
- "Try running `%s' in the shell to raise its limit.\n",
+ "Try running '%s' in the shell to raise its limit.\n",
shell_commands[i][1]);
}
}
if (global_dc->abort_on_error)
- abort ();
+ fancy_abort (__FILE__, __LINE__, __FUNCTION__);
exit (FATAL_EXIT_CODE);
}
fprintf (stderr, "[address=%08lx pc=%08x]\n",
- uc->uc_mcontext->es.dar, uc->uc_mcontext->ss.srr0);
+ uc->uc_mcontext->MC_FLD(es).MC_FLD(dar),
+ uc->uc_mcontext->MC_FLD(ss).MC_FLD(srr0));
internal_error ("Segmentation Fault");
exit (FATAL_EXIT_CODE);
}
@@ -137,65 +152,5 @@ darwin_rs6000_extra_signals (void)
fatal_error ("While setting up signal handler: %m");
}
-#undef HOST_HOOKS_GT_PCH_GET_ADDRESS
-#define HOST_HOOKS_GT_PCH_GET_ADDRESS darwin_rs6000_gt_pch_get_address
-#undef HOST_HOOKS_GT_PCH_USE_ADDRESS
-#define HOST_HOOKS_GT_PCH_USE_ADDRESS darwin_rs6000_gt_pch_use_address
-
-/* Yes, this is really supposed to work. */
-static char pch_address_space[1024*1024*1024] __attribute__((aligned (4096)));
-
-/* Return the address of the PCH address space, if the PCH will fit in it. */
-
-static void *
-darwin_rs6000_gt_pch_get_address (size_t sz, int fd ATTRIBUTE_UNUSED)
-{
- if (sz <= sizeof (pch_address_space))
- return pch_address_space;
- else
- return NULL;
-}
-
-/* Check ADDR and SZ for validity, and deallocate (using munmap) that part of
- pch_address_space beyond SZ. */
-
-static int
-darwin_rs6000_gt_pch_use_address (void *addr, size_t sz, int fd, size_t off)
-{
- const size_t pagesize = getpagesize();
- void *mmap_result;
- int ret;
-
- if ((size_t)pch_address_space % pagesize != 0
- || sizeof (pch_address_space) % pagesize != 0)
- abort ();
-
- ret = (addr == pch_address_space && sz <= sizeof (pch_address_space));
- if (! ret)
- sz = 0;
-
- /* Round the size to a whole page size. Normally this is a no-op. */
- sz = (sz + pagesize - 1) / pagesize * pagesize;
-
- if (munmap (pch_address_space + sz, sizeof (pch_address_space) - sz) != 0)
- fatal_error ("couldn't unmap pch_address_space: %m\n");
-
- if (ret)
- {
- mmap_result = mmap (addr, sz,
- PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED,
- fd, off);
-
- /* The file might not be mmap-able. */
- ret = mmap_result != (void *) MAP_FAILED;
-
- /* Sanity check for broken MAP_FIXED. */
- if (ret && mmap_result != addr)
- abort ();
- }
-
- return ret;
-}
-
const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;