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 + + * 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 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 = ⊤ *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 similarity index 55% rename from gcc/config/i386/t-darwin rename to 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 + + * g++.old-deja/g++.eh/badalloc1.C: XFAIL excess errors test on + Darwin. + 2002-11-04 Adam Nemet * 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 // 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 +#include +#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 . 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 +}