summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2002-11-07 06:00:07 +0000
committergeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2002-11-07 06:00:07 +0000
commita0c3f57468656239f0720772b25f80f98fec9386 (patch)
tree0a818627c9d2e5109f50615e83ad08d7572b1feb
parent3241194f8a468d69f4cfc4c6a8d78e5bc2c1736d (diff)
downloadgcc-a0c3f57468656239f0720772b25f80f98fec9386.tar.gz
Index: ChangeLog
2002-11-05 Geoffrey Keating <geoffk@apple.com> * config.gcc: Don't create crtbegin, crtend on Darwin; do create crt2.o. Rearrange t-darwin makefiles. * crtstuff.c [OBJECT_FORMAT_MACHO]: Delete. * unwind-dw2-fde-darwin.c: New. * unwind-dw2-fde-glibc.c: Correct comment. * unwind-dw2-fde.c (__register_frame_info_bases) [DWARF2_OBJECT_END_PTR_EXTENSION]: Clear fde_end. (classify_object_over_fdes): Use last_fde. (add_fdes): Likewise. (linear_search_fdes): Likewise. * unwind-dw2-fde.h (struct object) [DWARF2_OBJECT_END_PTR_EXTENSION]: Add fde_end field. (last_fde): New. * config/darwin.h (STARTFILE_SPEC): Include crt2.o not crtbegin.o. (ENDFILE_SPEC): No crtend.o. * config/t-darwin: New. * config/i386/t-darwin: Delete. * config/darwin-crt2.c: New. * config/rs6000/t-darwin: Delete contents duplicated in t-rs6000 or config/t-darwin. Index: testsuite/ChangeLog 2002-11-05 Geoffrey Keating <geoffk@apple.com> * g++.old-deja/g++.eh/badalloc1.C: XFAIL excess errors test on Darwin. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@58877 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog23
-rw-r--r--gcc/config.gcc8
-rw-r--r--gcc/config/darwin-crt2.c151
-rw-r--r--gcc/config/darwin.h11
-rw-r--r--gcc/config/rs6000/t-darwin34
-rw-r--r--gcc/config/t-darwin (renamed from gcc/config/i386/t-darwin)11
-rw-r--r--gcc/crtstuff.c82
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/badalloc1.C4
-rw-r--r--gcc/unwind-dw2-fde-darwin.c231
-rw-r--r--gcc/unwind-dw2-fde-glibc.c4
-rw-r--r--gcc/unwind-dw2-fde.c11
-rw-r--r--gcc/unwind-dw2-fde.h14
13 files changed, 457 insertions, 132 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c807cb6a201..f1ee875091f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,26 @@
+2002-11-05 Geoffrey Keating <geoffk@apple.com>
+
+ * config.gcc: Don't create crtbegin, crtend on Darwin; do create
+ crt2.o. Rearrange t-darwin makefiles.
+ * crtstuff.c [OBJECT_FORMAT_MACHO]: Delete.
+ * unwind-dw2-fde-darwin.c: New.
+ * unwind-dw2-fde-glibc.c: Correct comment.
+ * unwind-dw2-fde.c (__register_frame_info_bases)
+ [DWARF2_OBJECT_END_PTR_EXTENSION]: Clear fde_end.
+ (classify_object_over_fdes): Use last_fde.
+ (add_fdes): Likewise.
+ (linear_search_fdes): Likewise.
+ * unwind-dw2-fde.h (struct object)
+ [DWARF2_OBJECT_END_PTR_EXTENSION]: Add fde_end field.
+ (last_fde): New.
+ * config/darwin.h (STARTFILE_SPEC): Include crt2.o not crtbegin.o.
+ (ENDFILE_SPEC): No crtend.o.
+ * config/t-darwin: New.
+ * config/i386/t-darwin: Delete.
+ * config/darwin-crt2.c: New.
+ * config/rs6000/t-darwin: Delete contents duplicated in t-rs6000
+ or config/t-darwin.
+
2002-11-06 David Edelsohn <edelsohn@gnu.org>
PR target/8480
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 973a848ffd0..edfe51bfe46 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -985,12 +985,12 @@ i370-*-linux*)
i[34567]86-*-darwin*)
tm_file="${tm_file} darwin.h i386/darwin.h"
tm_p_file="${tm_p_file} darwin-protos.h"
- tmake_file=i386/t-darwin
+ tmake_file="t-darwin"
extra_objs="darwin.o"
target_gtfiles="\$(srcdir)/config/darwin.c"
c_target_objs="darwin-c.o"
cxx_target_objs="darwin-c.o"
- extra_parts="crtbegin.o crtend.o"
+ extra_parts="crt2.o"
# Darwin linker does collect2 functionality
use_collect2=no
;;
@@ -1956,12 +1956,12 @@ powerpc-*-beos*)
powerpc-*-darwin*)
tm_file="${tm_file} darwin.h rs6000/darwin.h"
tm_p_file="${tm_p_file} darwin-protos.h"
- tmake_file=rs6000/t-darwin
+ tmake_file="rs6000/t-rs6000 t-darwin rs6000/t-darwin"
extra_objs="darwin.o"
target_gtfiles="\$(srcdir)/config/darwin.c"
c_target_objs="darwin-c.o"
cxx_target_objs="darwin-c.o"
- extra_parts="crtbegin.o crtend.o"
+ extra_parts="crt2.o"
# Darwin linker does collect2 functionality
use_collect2=no
extra_headers=altivec.h
diff --git a/gcc/config/darwin-crt2.c b/gcc/config/darwin-crt2.c
new file mode 100644
index 00000000000..1ea2413c809
--- /dev/null
+++ b/gcc/config/darwin-crt2.c
@@ -0,0 +1,151 @@
+/* KeyMgr backwards-compatibility support for Darwin.
+ Copyright (C) 2001, 2002 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.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+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. */
+
+/* It is incorrect to include config.h here, because this file is being
+ compiled for the target, and hence definitions concerning only the host
+ do not apply. */
+
+#include "tconfig.h"
+#include "tsystem.h"
+
+/* Homemade decls substituting for getsect.h and dyld.h, so cross
+ compilation works. */
+struct mach_header;
+extern char *getsectdatafromheader (struct mach_header *, const char *,
+ const char *, unsigned long *);
+extern void _dyld_register_func_for_add_image
+ (void (*) (struct mach_header *, unsigned long));
+extern void _dyld_register_func_for_remove_image
+ (void (*) (struct mach_header *, unsigned long));
+
+extern void __darwin_gcc3_preregister_frame_info (void);
+
+/* These are from "keymgr.h". */
+extern void _init_keymgr (void);
+extern void *_keymgr_get_and_lock_processwide_ptr (unsigned key);
+extern void _keymgr_set_and_unlock_processwide_ptr (unsigned key, void *ptr);
+
+extern void *__keymgr_global[];
+typedef struct _Sinfo_Node {
+ unsigned int size ; /*size of this node*/
+ unsigned short major_version ; /*API major version.*/
+ unsigned short minor_version ; /*API minor version.*/
+ } _Tinfo_Node ;
+
+/* KeyMgr 3.x is the first one supporting GCC3 stuff natively. */
+#define KEYMGR_API_MAJOR_GCC3 3
+/* ... with these keys. */
+#define KEYMGR_GCC3_LIVE_IMAGE_LIST 301 /* loaded images */
+#define KEYMGR_GCC3_DW2_OBJ_LIST 302 /* Dwarf2 object list */
+
+/* Node of KEYMGR_GCC3_LIVE_IMAGE_LIST. Info about each resident image. */
+struct live_images {
+ unsigned long this_size; /* sizeof (live_images) */
+ struct mach_header *mh; /* the image info */
+ unsigned long vm_slide;
+ void (*destructor)(struct live_images *); /* destructor for this */
+ struct live_images *next;
+ unsigned int examined_p;
+ void *fde;
+ void *object_info;
+ unsigned long info[2]; /* Future use. */
+};
+
+
+/* These routines are used only on Darwin versions before 10.2.
+ Later versions have equivalent code in the system.
+ Eventually, they might go away, although it might be a long time... */
+
+static void darwin_unwind_dyld_remove_image_hook
+ (struct mach_header *m, unsigned long s);
+static void darwin_unwind_dyld_remove_image_hook
+ (struct mach_header *m, unsigned long s);
+extern void __darwin_gcc3_preregister_frame_info (void);
+
+static void
+darwin_unwind_dyld_add_image_hook (struct mach_header *mh, unsigned long slide)
+{
+ struct live_images *l = (struct live_images *)calloc (1, sizeof (*l));
+ l->mh = mh;
+ l->vm_slide = slide;
+ l->this_size = sizeof (*l);
+ l->next = (struct live_images *)
+ _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);
+ _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, l);
+}
+
+static void
+darwin_unwind_dyld_remove_image_hook (struct mach_header *m, unsigned long s)
+{
+ struct live_images *top, **lip, *destroy = NULL;
+
+ /* Look for it in the list of live images and delete it. */
+
+ top = (struct live_images *)
+ _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);
+ for (lip = &top; *lip != NULL; lip = &(*lip)->next)
+ {
+ if ((*lip)->mh == m && (*lip)->vm_slide == s)
+ {
+ destroy = *lip;
+ *lip = destroy->next; /* unlink DESTROY */
+
+ if (destroy->this_size != sizeof (*destroy)) /* sanity check */
+ abort ();
+
+ break;
+ }
+ }
+ _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST, top);
+
+ /* Now that we have unlinked this from the image list, toss it. */
+ if (destroy != NULL)
+ {
+ if (destroy->destructor != NULL)
+ (*destroy->destructor) (destroy);
+ free (destroy);
+ }
+}
+
+void
+__darwin_gcc3_preregister_frame_info (void)
+{
+ const _Tinfo_Node *info;
+ _init_keymgr ();
+ info = (_Tinfo_Node *)__keymgr_global[2];
+ if (info != NULL)
+ {
+ if (info->major_version >= KEYMGR_API_MAJOR_GCC3)
+ return;
+ /* Otherwise, use our own add_image_hooks. */
+ }
+
+ _dyld_register_func_for_add_image (darwin_unwind_dyld_add_image_hook);
+ _dyld_register_func_for_remove_image (darwin_unwind_dyld_remove_image_hook);
+}
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index f215a7567b4..27ce49f5d59 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -98,12 +98,13 @@ Boston, MA 02111-1307, USA. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
- "%{pg:%{static:-lgcrt0.o}%{!static:-lgcrt1.o -lcrtbegin.o}} \
- %{!pg:%{static:-lcrt0.o}%{!static:-lcrt1.o -lcrtbegin.o}}"
+ "%{pg:%{static:-lgcrt0.o}%{!static:-lgcrt1.o} -lcrt2.o} \
+ %{!pg:%{static:-lcrt0.o}%{!static:-lcrt1.o} -lcrt2.o}"
-#undef ENDFILE_SPEC
-#define ENDFILE_SPEC \
- "-lcrtend.o"
+/* The native Darwin linker doesn't necessarily place files in the order
+ that they're specified on the link line. Thus, it is pointless
+ to put anything in ENDFILE_SPEC. */
+/* #define ENDFILE_SPEC "" */
#undef DOLLARS_IN_IDENTIFIERS
#define DOLLARS_IN_IDENTIFIERS 2
diff --git a/gcc/config/rs6000/t-darwin b/gcc/config/rs6000/t-darwin
index 16295788a73..7aca023302f 100644
--- a/gcc/config/rs6000/t-darwin
+++ b/gcc/config/rs6000/t-darwin
@@ -1,34 +1,2 @@
-# Library code must include trampoline support
+# Library code must include trampoline support.
LIB2FUNCS_EXTRA = $(srcdir)/config/rs6000/darwin-tramp.asm
-
-# We want fine grained libraries, so use the new code to build the
-# floating point emulation libraries.
-FPBIT = fp-bit.c
-DPBIT = dp-bit.c
-
-dp-bit.c: $(srcdir)/config/fp-bit.c
- cat $(srcdir)/config/fp-bit.c > dp-bit.c
-
-fp-bit.c: $(srcdir)/config/fp-bit.c
- echo '#define FLOAT' > fp-bit.c
- cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-
-darwin.o: $(srcdir)/config/darwin.c $(CONFIG_H) $(SYSTEM_H) $(RTL_BASE_H) \
- $(REGS_H) hard-reg-set.h insn-config.h conditions.h output.h \
- insn-attr.h flags.h $(TREE_H) $(EXPR_H) reload.h \
- function.h $(GGC_H) $(TM_P_H) gt-darwin.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
-
-darwin-c.o: $(srcdir)/config/darwin-c.c $(CONFIG_H) $(SYSTEM_H) \
- $(TREE_H) $(C_TREE_H) c-pragma.h toplev.h cpplib.h $(TM_P_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
-
-gt-darwin.h : s-gtype ; @true
-
-# Build the libraries for both hard and soft floating point
-
-MULTILIB_OPTIONS = msoft-float
-MULTILIB_DIRNAMES = soft-float
-
-LIBGCC = stmp-multilib
-INSTALL_LIBGCC = install-multilib
diff --git a/gcc/config/i386/t-darwin b/gcc/config/t-darwin
index 51285570d68..aca59ba4f30 100644
--- a/gcc/config/i386/t-darwin
+++ b/gcc/config/t-darwin
@@ -9,3 +9,14 @@ darwin-c.o: $(srcdir)/config/darwin-c.c $(CONFIG_H) $(SYSTEM_H) \
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
gt-darwin.h : s-gtype ; @true
+
+# Explain how to build crt2.o
+$(T)crt2$(objext): $(srcdir)/config/darwin-crt2.c $(GCC_PASSES) \
+ $(TCONFIG_H) tsystem.h
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) \
+ -c $(srcdir)/config/darwin-crt2.c -o $(T)crt2$(objext)
+
+# Use unwind-dw2-fde-darwin
+LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-darwin.c \
+ $(srcdir)/unwind-sjlj.c
+LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c
diff --git a/gcc/crtstuff.c b/gcc/crtstuff.c
index 125e236ee9c..e5f5d78aeea 100644
--- a/gcc/crtstuff.c
+++ b/gcc/crtstuff.c
@@ -126,8 +126,6 @@ extern void *__deregister_frame_info_bases (void *)
/* Likewise for _Jv_RegisterClasses. */
extern void _Jv_RegisterClasses (void *) TARGET_ATTRIBUTE_WEAK;
-#ifndef OBJECT_FORMAT_MACHO
-
#ifdef OBJECT_FORMAT_ELF
/* Declare a pointer to void function type. */
@@ -542,83 +540,3 @@ __do_global_ctors (void)
#else /* ! CRT_BEGIN && ! CRT_END */
#error "One of CRT_BEGIN or CRT_END must be defined."
#endif
-
-#else /* OBJECT_FORMAT_MACHO */
-
-/* Crt stuff for Mach-O (NeXT and Darwin).
-
- The theory of this is that each dynamically-loadable module,
- including the main program itself, must have been positioned by
- dyld before any frame info can be registered. So we set up the
- registration functions as dyld hooks, using a "preregistration"
- function that is called directly from the system crt1.o. */
-
-#ifdef CRT_BEGIN
-
-/* Homemade decls substituting for getsect.h and dyld.h, so cross
- compilation works. */
-struct mach_header;
-extern char *getsectdatafromheader (struct mach_header *, const char *,
- const char *, unsigned long *);
-extern void _dyld_register_func_for_add_image
- (void (*) (struct mach_header *, unsigned long));
-extern void _dyld_register_func_for_remove_image
- (void (*) (struct mach_header *, unsigned long));
-
-extern void __darwin_gcc3_preregister_frame_info (void);
-
-static void
-unwind_dyld_add_image_hook (struct mach_header *mh,
- unsigned long vm_slide)
-{
- unsigned long sz;
- char *fde;
-
- fde = getsectdatafromheader (mh, "__TEXT", "__eh_frame", &sz);
- if (fde)
- {
- struct object *ob = (struct object *) malloc (sizeof (struct object));
-
- __register_frame_info (fde + vm_slide, ob);
- }
-}
-
-static void
-unwind_dyld_remove_image_hook (struct mach_header *mh,
- unsigned long vm_slide)
-{
- unsigned long sz;
- char *fde;
-
- fde = getsectdatafromheader (mh, "__TEXT", "__eh_frame", &sz);
-
- if (fde)
- __deregister_frame_info (fde + vm_slide);
-}
-
-/* Call this routine from the system crt1.o. The call is standard in
- Darwin 6.x (Mac OS X 10.2) and later; for earlier systems, you
- would need to modify crt.c in the Csu project. (This isn't great,
- but other alternatives run afoul of linker semantics. This
- function is declared as common and tested before being called, so
- that programs compiled by older GCCs still link and run.) */
-
-void
-__darwin_gcc3_preregister_frame_info ()
-{
- _dyld_register_func_for_add_image (unwind_dyld_add_image_hook);
- _dyld_register_func_for_remove_image (unwind_dyld_remove_image_hook);
-}
-
-#elif defined(CRT_END) /* ! CRT_BEGIN */
-
-/* Install a single zero word at the end of the __eh_frame section. */
-
-asm (".section __TEXT,__eh_frame");
-asm (".long 0");
-
-#else /* ! CRT_BEGIN && ! CRT_END */
-#error "One of CRT_BEGIN or CRT_END must be defined."
-#endif
-
-#endif /* OBJECT_FORMAT_MACHO */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c69b90418fc..38c0f8b813d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2002-11-05 Geoffrey Keating <geoffk@apple.com>
+
+ * g++.old-deja/g++.eh/badalloc1.C: XFAIL excess errors test on
+ Darwin.
+
2002-11-04 Adam Nemet <anemet@lnxw.com>
* gcc.c-torture/execute/941014-1.x: thumb-elf was deprecated, use
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/badalloc1.C b/gcc/testsuite/g++.old-deja/g++.eh/badalloc1.C
index 19ec3c1f0b6..d5722bde52f 100644
--- a/gcc/testsuite/g++.old-deja/g++.eh/badalloc1.C
+++ b/gcc/testsuite/g++.old-deja/g++.eh/badalloc1.C
@@ -1,5 +1,5 @@
-// excess errors test - XFAIL xstormy16-*-*
-// Copyright (C) 2000 Free Software Foundation, Inc.
+// excess errors test - XFAIL xstormy16-*-* *-*-darwin*
+// Copyright (C) 2000, 2002 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 6 June 2000 <nathan@codesourcery.com>
// Check we can throw a bad_alloc exception when malloc dies.
diff --git a/gcc/unwind-dw2-fde-darwin.c b/gcc/unwind-dw2-fde-darwin.c
new file mode 100644
index 00000000000..77e44e852ad
--- /dev/null
+++ b/gcc/unwind-dw2-fde-darwin.c
@@ -0,0 +1,231 @@
+/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+
+ This file is part of GNU CC.
+
+ GNU CC 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.
+
+ GNU CC 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 GNU CC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License. */
+
+/* Locate the FDE entry for a given address, using Darwin's keymgr support. */
+
+#include "tconfig.h"
+#include <string.h>
+#include <stdlib.h>
+#include "dwarf2.h"
+#include "unwind.h"
+#define NO_BASE_OF_ENCODED_VALUE
+#define DWARF2_OBJECT_END_PTR_EXTENSION
+#include "unwind-pe.h"
+#include "unwind-dw2-fde.h"
+/* Carefully don't include gthr.h. */
+
+typedef int __gthread_mutex_t;
+#define __gthread_mutex_lock(x) (void)(x)
+#define __gthread_mutex_unlock(x) (void)(x)
+
+static fde * _Unwind_Find_registered_FDE (void *pc,
+ struct dwarf_eh_bases *bases);
+
+#define _Unwind_Find_FDE _Unwind_Find_registered_FDE
+#include "unwind-dw2-fde.c"
+#undef _Unwind_Find_FDE
+
+/* KeyMgr stuff. */
+#define KEYMGR_GCC3_LIVE_IMAGE_LIST 301 /* loaded images */
+#define KEYMGR_GCC3_DW2_OBJ_LIST 302 /* Dwarf2 object list */
+
+extern void *_keymgr_get_and_lock_processwide_ptr (int);
+extern void _keymgr_set_and_unlock_processwide_ptr (int, void *);
+extern void _keymgr_unlock_processwide_ptr (int);
+
+struct mach_header;
+extern char *getsectdatafromheader (struct mach_header*, const char*,
+ const char *, unsigned long *);
+
+/* This is referenced from KEYMGR_GCC3_DW2_OBJ_LIST. */
+struct km_object_info {
+ struct object *seen_objects;
+ struct object *unseen_objects;
+ unsigned spare[2];
+};
+
+/* Node of KEYMGR_GCC3_LIVE_IMAGE_LIST. Info about each resident image. */
+struct live_images {
+ unsigned long this_size; /* sizeof (live_images) */
+ struct mach_header *mh; /* the image info */
+ unsigned long vm_slide;
+ void (*destructor)(struct live_images *); /* destructor for this */
+ struct live_images *next;
+ unsigned int examined_p;
+ void *fde;
+ void *object_info;
+ unsigned long info[2]; /* Future use. */
+};
+
+/* Bits in the examined_p field of struct live_images. */
+enum {
+ EXAMINED_IMAGE_MASK = 1, /* We've seen this one. */
+ ALLOCED_IMAGE_MASK = 2, /* The FDE entries were allocated by
+ malloc, and must be freed. This isn't
+ used by newer libgcc versions. */
+ IMAGE_IS_TEXT_MASK = 4 /* This image is in the TEXT segment. */
+};
+
+/* Delete any data we allocated on a live_images structure.
+ IMAGE has already been removed from the KEYMGR_GCC3_LIVE_IMAGE_LIST.
+ Called by KeyMgr (which will delete the struct after we return.) */
+
+static void
+live_image_destructor (struct live_images *image)
+{
+ if (image->object_info)
+ {
+ /* Free any sorted arrays. */
+ __deregister_frame_info_bases (image->fde);
+
+ free (image->object_info);
+ image->object_info = NULL;
+ if (image->examined_p & ALLOCED_IMAGE_MASK)
+ free (image->fde);
+ }
+}
+
+/* Run through the list of live images. If we can allocate memory,
+ give each unseen image a new `struct object'. Even if we can't,
+ check whether the PC is inside the FDE of each unseen image.
+ */
+
+static inline fde *
+examine_objects (void *pc, struct dwarf_eh_bases *bases, int dont_alloc)
+{
+ fde *result = NULL;
+ struct live_images *image;
+
+ image = _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);
+
+ for (; image != NULL; image = image->next)
+ if ((image->examined_p & EXAMINED_IMAGE_MASK) == 0)
+ {
+ char *fde;
+ unsigned long sz;
+
+ fde = getsectdatafromheader (image->mh, "__DATA", "__eh_frame", &sz);
+ if (fde == NULL)
+ {
+ fde = getsectdatafromheader (image->mh, "__TEXT",
+ "__eh_frame", &sz);
+ if (fde != NULL)
+ image->examined_p |= IMAGE_IS_TEXT_MASK;
+ }
+
+ /* If .eh_frame is empty, don't register at all. */
+ if (fde != NULL && sz > 0)
+ {
+ char *real_fde = (fde + image->vm_slide);
+ struct object *ob = NULL;
+ struct object panicob;
+
+ if (! dont_alloc)
+ ob = calloc (1, sizeof (struct object));
+ dont_alloc |= ob == NULL;
+ if (dont_alloc)
+ ob = &panicob;
+
+ ob->pc_begin = (void *)-1;
+ ob->tbase = 0;
+ ob->dbase = 0;
+ ob->u.single = (struct dwarf_fde *)real_fde;
+ ob->s.i = 0;
+ ob->s.b.encoding = DW_EH_PE_omit;
+ ob->fde_end = real_fde + sz;
+
+ if (! dont_alloc)
+ {
+ ob->next = unseen_objects;
+ unseen_objects = ob;
+
+ image->destructor = live_image_destructor;
+ image->object_info = ob;
+
+ image->examined_p |= EXAMINED_IMAGE_MASK;
+ }
+ image->fde = real_fde;
+
+ result = search_object (ob, pc);
+ if (result)
+ {
+ int encoding;
+
+ bases->tbase = ob->tbase;
+ bases->dbase = ob->dbase;
+
+ encoding = ob->s.b.encoding;
+ if (ob->s.b.mixed_encoding)
+ encoding = get_fde_encoding (result);
+ read_encoded_value_with_base (encoding,
+ base_from_object (encoding, ob),
+ result->pc_begin,
+ (_Unwind_Ptr *)&bases->func);
+ break;
+ }
+ }
+ else
+ image->examined_p |= EXAMINED_IMAGE_MASK;
+ }
+
+ _keymgr_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);
+
+ return result;
+}
+
+fde *
+_Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
+{
+ struct km_object_info *the_obj_info;
+ fde *ret = NULL;
+
+ the_obj_info =
+ _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST);
+ if (! the_obj_info)
+ the_obj_info = calloc (1, sizeof (*the_obj_info));
+
+ if (the_obj_info != NULL)
+ {
+ seen_objects = the_obj_info->seen_objects;
+ unseen_objects = the_obj_info->unseen_objects;
+
+ ret = _Unwind_Find_registered_FDE (pc, bases);
+ }
+
+ /* OK, didn't find it in the list of FDEs we've seen before,
+ so go through and look at the new ones. */
+ if (ret == NULL)
+ ret = examine_objects (pc, bases, the_obj_info == NULL);
+
+ if (the_obj_info != NULL)
+ {
+ the_obj_info->seen_objects = seen_objects;
+ the_obj_info->unseen_objects = unseen_objects;
+ _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST,
+ the_obj_info);
+ }
+ return ret;
+}
diff --git a/gcc/unwind-dw2-fde-glibc.c b/gcc/unwind-dw2-fde-glibc.c
index 463e3204483..21b3321ceb6 100644
--- a/gcc/unwind-dw2-fde-glibc.c
+++ b/gcc/unwind-dw2-fde-glibc.c
@@ -79,8 +79,8 @@ struct unw_eh_frame_hdr
unsigned char table_enc;
};
-/* Like base_of_encoded_value, but take the base from a struct object
- instead of an _Unwind_Context. */
+/* Like base_of_encoded_value, but take the base from a struct
+ unw_eh_callback_data instead of an _Unwind_Context. */
static _Unwind_Ptr
base_from_cb_data (unsigned char encoding, struct unw_eh_callback_data *data)
diff --git a/gcc/unwind-dw2-fde.c b/gcc/unwind-dw2-fde.c
index a06a5bed87b..f4cb4bb45e9 100644
--- a/gcc/unwind-dw2-fde.c
+++ b/gcc/unwind-dw2-fde.c
@@ -1,5 +1,5 @@
/* Subroutines needed for unwinding stack frames for exception handling. */
-/* Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Contributed by Jason Merrill <jason@cygnus.com>.
This file is part of GCC.
@@ -85,6 +85,9 @@ __register_frame_info_bases (void *begin, struct object *ob,
ob->u.single = begin;
ob->s.i = 0;
ob->s.b.encoding = DW_EH_PE_omit;
+#ifdef DWARF2_OBJECT_END_PTR_EXTENSION
+ ob->fde_end = NULL;
+#endif
init_object_mutex_once ();
__gthread_mutex_lock (&object_mutex);
@@ -602,7 +605,7 @@ classify_object_over_fdes (struct object *ob, fde *this_fde)
int encoding = DW_EH_PE_absptr;
_Unwind_Ptr base = 0;
- for (; this_fde->length != 0; this_fde = next_fde (this_fde))
+ for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
{
struct dwarf_cie *this_cie;
_Unwind_Ptr mask, pc_begin;
@@ -656,7 +659,7 @@ add_fdes (struct object *ob, struct fde_accumulator *accu, fde *this_fde)
int encoding = ob->s.b.encoding;
_Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
- for (; this_fde->length != 0; this_fde = next_fde (this_fde))
+ for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
{
struct dwarf_cie *this_cie;
@@ -773,7 +776,7 @@ linear_search_fdes (struct object *ob, fde *this_fde, void *pc)
int encoding = ob->s.b.encoding;
_Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
- for (; this_fde->length != 0; this_fde = next_fde (this_fde))
+ for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
{
struct dwarf_cie *this_cie;
_Unwind_Ptr pc_begin, pc_range;
diff --git a/gcc/unwind-dw2-fde.h b/gcc/unwind-dw2-fde.h
index 23f6f7e6ca9..b7d96cfe992 100644
--- a/gcc/unwind-dw2-fde.h
+++ b/gcc/unwind-dw2-fde.h
@@ -61,6 +61,10 @@ struct object
size_t i;
} s;
+#ifdef DWARF2_OBJECT_END_PTR_EXTENSION
+ char *fde_end;
+#endif
+
struct object *next;
};
@@ -160,3 +164,13 @@ next_fde (fde *f)
}
extern fde * _Unwind_Find_FDE (void *, struct dwarf_eh_bases *);
+
+static inline int
+last_fde (struct object *obj, fde *f)
+{
+#ifdef DWARF2_OBJECT_END_PTR_EXTENSION
+ return (char *)f == obj->fde_end || f->length == 0;
+#else
+ return f->length == 0;
+#endif
+}