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. From-SVN: r58877
This commit is contained in:
parent
12f256d42e
commit
3cfe49dab8
13 changed files with 457 additions and 132 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
151
gcc/config/darwin-crt2.c
Normal file
151
gcc/config/darwin-crt2.c
Normal file
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
231
gcc/unwind-dw2-fde-darwin.c
Normal file
231
gcc/unwind-dw2-fde-darwin.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue