Commit 747b9f55 by Geoffrey Keating Committed by Geoffrey Keating

config.gcc (*-*-darwin*): Don't build crt2.o for all Darwin ports.

2006-03-15  Geoffrey Keating  <geoffk@apple.com>

	* config.gcc (*-*-darwin*): Don't build crt2.o for all Darwin ports.
	Do switch on default_use_cxa_atexit.
	(powerpc*-*-darwin*): Build crt2.o on powerpc.
	* config/darwin-crt3.o: New.
	* config/darwin.h (LINK_SPEC): If -shared-libgcc, make linker default
	to 10.3.  Pass '-multiply_defined suppress' if crt3.o is in use.
	(STARTFILE_SPEC): Add crt3.o when -shared-libgcc and appropriate
	OS version.
	* config/rs6000/t-darwin: Move crt2.o building to here.
	* config/rs6000/darwin.h (C_COMMON_OVERRIDE_OPTIONS): Update
	Mac OS version for using __cxa_get_exception_ptr.  Don't test versions
	of __cxa_atexit.

2006-03-15  Geoffrey Keating  <geoffk@apple.com>

	* g++.old-deja/g++.other/init18.C: New.
	* g++.old-deja/g++.other/init5.C: Remove xfail.

From-SVN: r112121
parent 289e97d2
2006-03-15 Geoffrey Keating <geoffk@apple.com>
* config.gcc (*-*-darwin*): Don't build crt2.o for all Darwin ports.
Do switch on default_use_cxa_atexit.
(powerpc*-*-darwin*): Build crt2.o on powerpc.
* config/darwin-crt3.o: New.
* config/darwin.h (LINK_SPEC): If -shared-libgcc, make linker default
to 10.3. Pass '-multiply_defined suppress' if crt3.o is in use.
(STARTFILE_SPEC): Add crt3.o when -shared-libgcc and appropriate
OS version.
* config/rs6000/t-darwin: Move crt2.o building to here.
* config/rs6000/darwin.h (C_COMMON_OVERRIDE_OPTIONS): Update
Mac OS version for using __cxa_get_exception_ptr. Don't test versions
of __cxa_atexit.
2006-03-15 Jan-Benedict Glaw <jbglaw@lug-owl.de>
* config/vax/vax.c (nonindexed_address_p): Change logical negation
......
......@@ -368,8 +368,8 @@ case ${target} in
extra_options="${extra_options} darwin.opt"
c_target_objs="darwin-c.o"
cxx_target_objs="darwin-c.o"
extra_parts="crt2.o"
extra_objs="darwin.o"
default_use_cxa_atexit=yes
case ${enable_threads} in
"" | yes | posix) thread_file='posix' ;;
esac
......@@ -1664,6 +1664,7 @@ powerpc-*-beos*)
;;
powerpc-*-darwin*)
extra_options="${extra_options} rs6000/darwin.opt"
extra_parts="crt2.o"
case ${target} in
*-darwin1[0-9]* | *-darwin[8-9]*)
tmake_file="${tmake_file} rs6000/t-darwin8"
......
/* __cxa_atexit backwards-compatibility support for Darwin.
Copyright (C) 2006 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, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, 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"
#include <dlfcn.h>
#include <stdbool.h>
#include <stdlib.h>
/* This file works around two different problems.
The first problem is that there is no __cxa_atexit on Mac OS versions
before 10.4. It fixes this by providing one, and having it called from
a destructor. This is not quite as good as having a real __cxa_atexit,
but it's good enough to imitate the behaviour that you'd get if
you didn't have one.
The second problem is that on 10.4 Mac OS versions, __cxa_finalize
doesn't work right: it doesn't run routines that were registered
while other atexit routines are running. This is worked around by
installing our own handler so that it runs last, and repeatedly
running __cxa_finalize until no new calls to __cxa_atexit are made. */
typedef int (*cxa_atexit_p)(void (*func) (void*), void* arg, void* dso);
#ifdef __ppc__
void __cxa_finalize (void* dso) __attribute__((weak));
#else
void __cxa_finalize (void* dso);
#endif
/* new_atexit_routines is set if __cxa_finalize exists in the system C
library and our copy of __cxa_atexit has been called. */
static bool new_atexit_routines;
/* first_atexit_handler is called after all other atexit routines
that were registered before __cxa_finalize is called.
It may be called more than once, but is not re-entered. */
static void
first_atexit_handler(void* dso)
{
/* Keep running __cxa_finalize until no new atexit routines are
registered.
Note that this means __cxa_finalize will be called at least twice,
even if the first call didn't register any new routines. */
while (new_atexit_routines) {
new_atexit_routines = false;
__cxa_finalize (dso);
};
}
/* This is our wrapper around __cxa_atexit that's called if __cxa_finalize
exists in the system library. All it does is, on its first call,
install first_atexit_handler; and on every call, set new_atexit_routines
and pass control to the system __cxa_atexit.
This proves to be somewhat more complicated than you might expect,
because it may be called in a multithreaded environment. Fortunately
it turns out to be possible to do what's needed without resorting
to locking. */
static int
cxa_atexit_wrapper (void (*func) (void*), void* arg, void* dso)
{
static volatile cxa_atexit_p real_cxa_atexit;
cxa_atexit_p auto_cxa_atexit = real_cxa_atexit;
if (! auto_cxa_atexit)
{
void* handle = dlopen ("/usr/lib/libSystem.B.dylib", RTLD_NOLOAD);
if (! handle)
return -1;
auto_cxa_atexit = (cxa_atexit_p)dlsym (handle, "__cxa_atexit");
if (! auto_cxa_atexit)
return -1;
}
/* At this point, auto_cxa_atexit contains the address of
the system __cxa_atexit. */
if (! real_cxa_atexit)
{
/* Install our handler above before any other handlers
for this image, so it will be called last. */
int result = (*auto_cxa_atexit)(first_atexit_handler, dso, dso);
if (result != 0)
return result;
/* Now set the global real_cxa_atexit to prevent further
installations of first_atexit_handler. Do this after
the installation so that if another thread sees it is set,
it can be sure that first_atexit_handler really has been
installed. */
real_cxa_atexit = auto_cxa_atexit;
}
/* At this point, we know that first_atexit_handler has been
installed at least once, and real_cxa_atexit is not NULL. */
/* It's not necessary to mark new_atexit_routines as volatile, so long
as this write eventually happens before this shared object is
unloaded. */
new_atexit_routines = true;
/* Call the original __cxa_atexit for this function. */
return (*auto_cxa_atexit)(func, arg, dso);
}
#ifdef __ppc__
/* This code is used while running on 10.3.9, when __cxa_atexit doesn't
exist in the system library. 10.3.9 only supported regular PowerPC,
so this code isn't necessary on x86 or ppc64. */
/* This structure holds a routine to call. */
struct atexit_routine
{
struct atexit_routine * next;
void (*func)(void *);
void * arg;
};
static struct atexit_routine * volatile atexit_routines_list;
/* If __cxa_atexit doesn't exist at all in the system library, this
routine is used; it completely emulates __cxa_atexit.
This routine has to be thread-safe, but fortunately this just means
that it has to do atomic list insertion. */
static int
cxa_atexit_substitute (void (*func) (void*), void* arg,
/* The 'dso' value will always be equal to this
object's __dso_handle. */
void* dso __attribute__((unused)))
{
struct atexit_routine * s = malloc (sizeof (struct atexit_routine));
struct atexit_routine * next, * old_next;
if (!s)
return -1;
s->func = func;
s->arg = arg;
next = atexit_routines_list;
do {
s->next = old_next = next;
next = __sync_val_compare_and_swap (&atexit_routines_list, old_next, s);
} while (next != old_next);
return 0;
}
/* The routines added in cxa_atexit_substitute get run here, in a destructor.
This routine doesn't have to be thread-safe. */
static void cxa_dtor (void) __attribute__((destructor));
static void
cxa_dtor (void)
{
while (atexit_routines_list)
{
struct atexit_routine * working_list = atexit_routines_list;
atexit_routines_list = NULL;
while (working_list)
{
struct atexit_routine * called_routine = working_list;
working_list->func (working_list->arg);
working_list = working_list->next;
free (called_routine);
}
}
}
#endif
int __cxa_atexit (void (*func) (void*), void* arg,
void* dso) __attribute__((visibility("hidden")));
int
__cxa_atexit (void (*func) (void*), void* arg, void* dso)
{
#ifdef __ppc__
if (! __cxa_finalize)
return cxa_atexit_substitute (func, arg, dso);
#endif
return cxa_atexit_wrapper (func, arg, dso);
}
......@@ -262,9 +262,13 @@ Boston, MA 02110-1301, USA. */
%{Zimage_base*:-image_base %*} \
%{Zinit*:-init %*} \
%{mmacosx-version-min=*:-macosx_version_min %*} \
%{!mmacosx-version-min=*:%{shared-libgcc:-macosx_version_min 10.3}} \
%{nomultidefs} \
%{Zmulti_module:-multi_module} %{Zsingle_module:-single_module} \
%{Zmultiply_defined*:-multiply_defined %*} \
%{!Zmultiply_defined*:%{shared-libgcc: \
%:version-compare(< 10.5 mmacosx-version-min= -multiply_defined) \
%:version-compare(< 10.5 mmacosx-version-min= suppress)}} \
%{Zmultiplydefinedunused*:-multiply_defined_unused %*} \
%{prebind} %{noprebind} %{nofixprebinding} %{prebind_all_twolevel_modules} \
%{read_only_relocs} \
......@@ -319,19 +323,25 @@ Boston, MA 02110-1301, USA. */
%:version-compare(>= 10.5 mmacosx-version-min= -lgcc_s.10.5) \
-lgcc}"
/* We specify crt0.o as -lcrt0.o so that ld will search the library path. */
/* We specify crt0.o as -lcrt0.o so that ld will search the library path.
crt3.o provides __cxa_atexit on systems that don't have it. Since
it's only used with C++, which requires passing -shared-libgcc, key
off that to avoid unnecessarily adding a destructor to every
powerpc program built. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
"%{!Zdynamiclib:%{Zbundle:%{!static:-lbundle1.o}} \
%{!Zbundle:%{pg:%{static:-lgcrt0.o} \
%{!static:%{object:-lgcrt0.o} \
%{!object:%{preload:-lgcrt0.o} \
%{!preload:-lgcrt1.o %(darwin_crt2)}}}} \
%{!pg:%{static:-lcrt0.o} \
%{!static:%{object:-lcrt0.o} \
%{!object:%{preload:-lcrt0.o} \
%{!preload:-lcrt1.o %(darwin_crt2)}}}}}}"
#define STARTFILE_SPEC \
"%{!Zdynamiclib:%{Zbundle:%{!static:-lbundle1.o}} \
%{!Zbundle:%{pg:%{static:-lgcrt0.o} \
%{!static:%{object:-lgcrt0.o} \
%{!object:%{preload:-lgcrt0.o} \
%{!preload:-lgcrt1.o %(darwin_crt2)}}}} \
%{!pg:%{static:-lcrt0.o} \
%{!static:%{object:-lcrt0.o} \
%{!object:%{preload:-lcrt0.o} \
%{!preload:-lcrt1.o %(darwin_crt2)}}}}}} \
%{shared-libgcc:%:version-compare(< 10.5 mmacosx-version-min= -lcrt3.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
......
......@@ -97,17 +97,11 @@ do { \
#define C_COMMON_OVERRIDE_OPTIONS do { \
/* On powerpc, __cxa_get_exception_ptr is available starting in the \
10.5 libstdc++.dylib. */ \
10.4.6 libstdc++.dylib. */ \
if ((! darwin_macosx_version_min \
|| strverscmp (darwin_macosx_version_min, "10.5") < 0) \
|| strverscmp (darwin_macosx_version_min, "10.4.6") < 0) \
&& flag_use_cxa_get_exception_ptr == 2) \
flag_use_cxa_get_exception_ptr = 0; \
/* On powerpc, __cxa_atexit is available starting in the 10.4 \
libSystem.dylib. */ \
if ((! darwin_macosx_version_min \
|| strverscmp (darwin_macosx_version_min, "10.4") < 0) \
&& flag_use_cxa_atexit == 2) \
flag_use_cxa_atexit = 0; \
} while (0)
/* Darwin has 128-bit long double support in libc in 10.4 and later.
......
......@@ -25,3 +25,9 @@ LIB2ADDEH += $(srcdir)/config/rs6000/darwin-fallback.c
darwin-fpsave.o: $(srcdir)/config/rs6000/darwin-asm.h
darwin-tramp.o: $(srcdir)/config/rs6000/darwin-asm.h
# Explain how to build crt2.o
$(T)crt2$(objext): $(srcdir)/config/darwin-crt2.c $(GCC_PASSES) \
$(TCONFIG_H) stmp-int-hdrs tsystem.h
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) \
-c $(srcdir)/config/darwin-crt2.c -o $(T)crt2$(objext)
......@@ -12,11 +12,12 @@ darwin-c.o: $(srcdir)/config/darwin-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
gt-darwin.h : s-gtype ; @true
# Explain how to build crt2.o
$(T)crt2$(objext): $(srcdir)/config/darwin-crt2.c $(GCC_PASSES) \
# How to build crt3.o
EXTRA_MULTILIB_PARTS=crt3.o
$(T)crt3$(objext): $(srcdir)/config/darwin-crt3.c $(GCC_PASSES) \
$(TCONFIG_H) stmp-int-hdrs tsystem.h
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) \
-c $(srcdir)/config/darwin-crt2.c -o $(T)crt2$(objext)
-c $(srcdir)/config/darwin-crt3.c -o $(T)crt3$(objext)
# Use unwind-dw2-fde-darwin
LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-darwin.c \
......
2006-03-15 Geoffrey Keating <geoffk@apple.com>
* g++.old-deja/g++.other/init18.C: New.
* g++.old-deja/g++.other/init5.C: Remove xfail.
2006-03-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* g++.dg/opt/pr15551.C: Cleanup temp file.
// { dg-do run }
#include <stdlib.h>
static int cnt = 0;
class Foo2
{
public:
Foo2() {};
~Foo2() { if (++cnt == 2) _Exit (0); };
};
static Foo2& GetFoo2()
{
static Foo2 foo2;
return foo2;
}
class Foo1
{
public:
Foo1() {}
~Foo1() { if (++cnt != 1) abort(); GetFoo2(); };
};
int main( int argc, const char* argv[] )
{
static Foo1 anotherFoo;
exit (1);
}
// { dg-do run { xfail { ! "powerpc*-*-linux*" } } }
// { dg-do run }
// Objects must be destructed in decreasing cnt order
// Original test attributed to James Kanze <jkanze@otelo.ibmmail.com>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment