f9989b51a9
toplevel: * Makefile.tpl (EXTRA_GCC_FLAGS): Remove LIBGCC2_CFLAGS, LIBGCC2_DEBUG_CFLAGS, LIBGCC2_INCLUDES. * Makefile.in: Regenerate. config: * mh-interix (LIBGCC2_DEBUG_CFLAGS): Remove. gcc: * Makefile.in (LIBGCC2_DEBUG_CFLAGS LIBGCC2_CFLAGS) (LIBGCC2_INCLUDES, TARGET_LIBGCC2_CFLAGS, LIB2FUNCS_EXTRA) (LIB2FUNCS_STATIC_EXTRA, LIB2FUNCS_EXCLUDE, T, T_TARGET) (INCLUDES_FOR_TARGET): Remove. (LIBGCC2_CFLAGS): Don't export. (LIB2FUNCS_ST, LIB2_DIVMOD_FUNCS, LIB2ADD, LIB2ADD_ST, srcdirify): Remove. (libgcc-support): Remove $(LIB2ADD), $(LIB2ADD_ST) dependencies. (libgcc.mvars): Likewise. Don't emit LIB2FUNCS_ST, LIB2FUNCS_EXCLUDE, LIB2ADD, LIB2ADD_ST, LIB2_SIDITI_CONV_FUNCS, LIB2_DIVMOD_FUNCS, LIBGCC2_CFLAGS, TARGET_LIBGCC2_CFLAGS. Emit GTHREAD_FLAGS. * libgcc2.c, libgcc2.h, gbl-ctors.h, longlong.h: Move to ../libgcc. * config/darwin-64.c: Move to ../libgcc/config. * config/divmod.c, config/floatunsidf.c, config/floatunsisf.c, config/floatunsitf.c, config/floatunsixf.c, config/udivmod.c, config/udivmodsi4.c: Move to ../libgcc/config. * config/gthr-posix.c: Move to ../libgcc/config/alpha. * config/memcmp.c, config/memcpy.c, config/memmove.c, config/memset.c: Move to ../libgcc/config. * config/t-darwin (TARGET_LIBGCC2_CFLAGS): Remove. * config/t-freebsd: Remove. * config/t-freebsd-thread: Move to ../libgcc/config. * config/t-libgcc-pic: Move to ../libgcc/config. * config/t-libunwind (TARGET_LIBGCC2_CFLAGS): Remove. * config/t-linux: Remove. * config/t-lynx (TARGET_LIBGCC2_CFLAGS, LIBGCC, INSTALL_LIBGCC): Remove * config/t-openbsd-thread: Move to ../libgcc/config. * config/t-rtems (LIBGCC2_INCLUDES): Remove. * config/t-sol2 (TARGET_LIBGCC2_CFLAGS): Remove. * config/t-svr4: Remove. * config/t-vxworks (LIBGCC, INSTALL_LIBGCC, TARGET_LIBGCC2_CFLAGS) (LIBGCC2_DEBUG_CFLAGS, LIB2FUNCS_EXTRA, LIBGCC2_INCLUDES): Remove. * config/vxlib.c, config/vxlib-tls.c: Move to ../libgcc/config. * config/alpha/qrnnd.asm: Move to ../libgcc/config/alpha/qrnnd.S. * config/alpha/t-alpha, config/alpha/t-ieee: Remove. * config/alpha/t-vms (LIB2FUNCS_EXTRA, LIBGCC, INSTALL_LIBGCC): Remove. * config/alpha/vms-gcc_shell_handler.c: Move to ../libgcc/config/alpha. * config/arm/bpabi.c, config/arm/unaligned-funcs.c, config/arm/fp16.c, config/arm/linux-atomic.c, config/arm/linux-atomic-64bit.c: Move to ../libgcc/config/arm. * config/arm/t-arm-elf (LIBGCC, INSTALL_LIBGCC) (TARGET_LIBGCC2_CFLAGS): Remove. * config/arm/t-bpabi, config/arm/t-linux: Remove. * config/arm/t-linux-eabi (TARGET_LIBGCC2_CFLAGS) (LIB2FUNCS_STATIC_EXTRA): Remove. * config/arm/t-netbsd: Remove. * config/arm/t-strongarm-elf (LIBGCC, INSTALL_LIBGCC) (TARGET_LIBGCC2_CFLAGS): Remove. * config/arm/t-symbian (LIB2FUNCS_STATIC_EXTRA): Remove. * config/arm/t-wince-pe (LIBGCC, INSTALL_LIBGCC) (TARGET_LIBGCC2_CFLAGS): Remove. * config/avr/t-avr (LIB2FUNCS_EXCLUDE, TARGET_LIBGCC2_CFLAGS) (LIBGCC, INSTALL_LIBGCC): Remove. * config/bfin/t-bfin-elf (TARGET_LIBGCC2_CFLAGS): Remove. * config/bfin/t-bfin-linux: Likewise. * config/bfin/t-bfin-uclinux: Likewise. * config/c6x/eqd.c, config/c6x/eqf.c, config/c6x/ged.c, config/c6x/gef.c, config/c6x/gtd.c, config/c6x/gtf.c, config/c6x/led.c, config/c6x/lef.c, config/c6x/ltd.c, config/c6x/ltf.c: Move to ../libgcc/config/c6x. * config/c6x/t-c6x-elf (LIB2FUNCS_EXCLUDE, LIB2FUNCS_EXTRA): Remove. * config/c6x/t-c6x-uclinux (TARGET_LIBGCC2_CFLAGS): Remove. * config/cris/arit.c: Move to ../libgcc/config/cris. * config/cris/cris_abi_symbol.c: Remove. * config/cris/cris.h: Remove obsolete comment. * config/cris/mulsi3.asm: Move to ../libgcc/config/cris/mulsi3.S. * config/cris/t-cris (LIB2FUNCS_EXTRA, CRIS_LIB1CSRC) ($(LIB2FUNCS_EXTRA)): Remove. * config/cris/t-elfmulti (LIB2FUNCS_STATIC_EXTRA, INSTALL_LIBGCC) (LIBGCC): Remove. * config/cris/t-linux (TARGET_LIBGCC2_CFLAGS): Remove. * config/fr30/t-fr30: Remove. * config/frv/cmovd.c, config/frv/cmovh.c, config/frv/cmovw.c, config/frv/modi.c, config/frv/uitod.c, config/frv/uitof.c, config/frv/ulltod.c, config/frv/ulltof.c, config/frv/umodi.c: Move to ../libgcc/config/frv. * config/frv/t-frv (LIB2FUNCS_EXTRA, TARGET_LIBGCC2_CFLAGS) (cmovh.c, cmovw.c, cmovd.c, modi.c, umodi.c, uitof.c, uitod.c) (ulltof.c, LIBGCC, INSTALL_LIBGCC): Remove. * config/frv/t-linux (TARGET_LIBGCC2_CFLAGS): Remove. * config/h8300/clzhi2.c, config/h8300/ctzhi2.c, config/h8300/fixunssfsi.c, config/h8300/parityhi2.c, config/h8300/popcounthi2.c: Move to ../libgcc/config/h8300. * config/h8300/t-h8300 (LIB2FUNCS_EXTRA, TARGET_LIBGCC2_CFLAGS) (LIBGCC, INSTALL_LIBGCC): Remove. * config/i386/gthr-win32.c: Move to ../libgcc/config/i386. * config/i386/t-cygming (LIBGCC2_INCLUDES): Remove. * config/i386/t-cygwin: Remove. * config/i386/t-darwin (LIB2_SIDITI_CONV_FUNCS, LIB2FUNCS_EXTRA) (LIB2FUNCS_EXCLUDE): Remove. * config/i386/t-darwin64 (LIB2_SIDITI_CONV_FUNCS, LIB2FUNCS_EXTRA) (LIBGCC, INSTALL_LIBGCC): Remove. * config/i386/t-gthr-win32: Move to ../libgcc/config/i386. * config/i386/t-linux64 (LIBGCC, INSTALL_LIBGCC): Remove. * config/i386/t-mingw-w32: Likewise. * config/i386/t-mingw-w64: Likewise. * config/i386/t-openbsd: Likewise. * config/i386/t-nto: Remove. * config/ia64/quadlib.c: Move to ../libgcc/config/ia64. * config/ia64/t-hpux (LIBGCC, INSTALL_LIBGCC, LIB2FUNCS_EXTRA) (quadlib.c): Remove. * config/ia64/t-ia64: Remove comment. * config/iq2000/lib2extra-funcs.c: Move to ../libgcc/config/iq2000/lib2funcs.c. * config/iq2000/t-iq2000: Remove. * config/m32c/m32c-lib2.c: Move to ../libgcc/config/m32c/lib2funcs.c. * config/m32c/m32c-lib2-trapv.c: Move to ../libgcc/config/m32c/trapv.c. * config/m32r/t-linux (TARGET_LIBGCC2_CFLAGS): Remove. * config/m32c/t-m32c (LIB2FUNCS_EXTRA): Remove. * config/m32r/t-m32r (TARGET_LIBGCC2_CFLAGS, LIBGCC) (INSTALL_LIBGCC): Remove. * config/m68k/fpgnulib.c: Move to ../libgcc/config/m68k. * config/m68k/t-floatlib: Remove. * config/m68k/t-mlibs (LIBGCC, INSTALL_LIBGCC): Remove. * config/mcore/t-mcore (TARGET_LIBGCC2_CFLAGS): Remove. Fix typo. (LIBGCC, INSTALL_LIBGCC): Remove. * config/mep/mep-lib2.c: Move to ../libgcc/config/mep/lib2funcs.c. * config/mep/mep-tramp.c: Move to ../libgcc/config/mep/tramp.c. * config/mep/t-mep (LIB2FUNCS_EXTRA): Remove. * config/mips/t-elf (TARGET_LIBGCC2_CFLAGS, LIBGCC) (INSTALL_LIBGCC): Remove. * config/mips/t-isa3264: Likewise. * config/mips/t-mips (LIB2_SIDITI_CONV_FUNCS): Remove. * config/mips/t-r3900 (TARGET_LIBGCC2_CFLAGS, LIBGCC) (INSTALL_LIBGCC): Remove. * config/mips/t-sde (LIBGCC, INSTALL_LIBGCC): Remove. * config/mips/t-sr71k (TARGET_LIBGCC2_CFLAGS, LIBGCC) (INSTALL_LIBGCC): Remove. * config/mips/t-vr (TARGET_LIBGCC2_CFLAGS) (LIB2FUNCS_STATIC_EXTRA): Remove. * config/mips/vr4120-div.S: Move to ../libgcc/config/mips. * config/mmix/t-mmix (TARGET_LIBGCC2_CFLAGS): Remove. * config/mn10300/t-mn10300 (LIBGCC, INSTALL_LIBGCC): Remove. * config/pa/fptr.c, config/pa/linux-atomic.c: Move to ../libgcc/config/pa. * config/pa/lib2funcs.asm: Move to ../libgcc/config/pa/lib2funcs.S. * config/pa/quadlib.c: Move to ../libgcc/config/pa. * config/pa/t-dce-thr (LIBGCC, INSTALL_LIBGCC): Remove. * config/pa/t-linux, config/pa/t-linux64: Remove. * config/pa/t-pa-hpux, config/pa/t-pa-hpux10, config/pa/t-pa-hpux11, config/pa/t-pa64: Remove. * config/pdp11/t-pdp11 (TARGET_LIBGCC2_CFLAGS, LIB2FUNCS_EXTRA): Remove. * config/picochip/libgccExtras: Move to ../libgcc/config/picochip. * config/picochip/t-picochip (LIB2FUNCS_EXTRA, RANLIB_FOR_TARGET) (TARGET_LIBGCC2_CFLAGS, LIBGCC2_DEBUG_CFLAGS): Remove. * config/rs6000/crtresfpr.asm: Move to ../libgcc/config/rs6000/crtresfpr.S. * config/rs6000/crtresgpr.asm: Move to ../libgcc/config/rs6000/crtresgpr.S. * config/rs6000/crtresxfpr.asm: Move to ../libgcc/config/rs6000/crtresxfpr.S. * config/rs6000/crtresxgpr.asm: Move to ../libgcc/config/rs6000/crtresxgpr.S. * config/rs6000/crtsavfpr.asm: Move to ../libgcc/config/rs6000/crtsavfpr.S. * config/rs6000/crtsavgpr.asm: Move to ../libgcc/config/rs6000/crtsavgpr.S. * config/rs6000/darwin-asm.h: Move to ../libgcc/config/rs6000. * config/rs6000/darwin-fpsave.asm: Move to ../libgcc/config/rs6000/darwin-fpsave.S. * config/rs6000/darwin-gpsave.asm: Move to ../libgcc/config/rs6000/darwin-gpsave.S. * config/rs6000/darwin-tramp.asm: Move to ../libgcc/config/rs6000/darwin-tramp.S. * config/rs6000/darwin-vecsave.asm: Move to ../libgcc/config/rs6000/darwin-vecsave.S. * config/rs6000/darwin-world.asm: Move to ../libgcc/config/rs6000/darwin-world.S. * config/rs6000/e500crtres32gpr.asm: Move to ../libgcc/config/rs6000/e500crtres32gpr.S. * config/rs6000/e500crtres64gpr.asm: Move to ../libgcc/config/rs6000/e500crtres64gpr.S. * config/rs6000/e500crtres64gprctr.asm: Move to ../libgcc/config/rs6000/e500crtres64gprctr.S. * config/rs6000/e500crtrest32gpr.asm: Move to ../libgcc/config/rs6000/e500crtrest32gpr.S. * config/rs6000/e500crtrest64gpr.asm: Move to ../libgcc/config/rs6000/e500crtrest64gpr.S. * config/rs6000/e500crtresx32gpr.asm: Move to ../libgcc/config/rs6000/e500crtresx32gpr.S. * config/rs6000/e500crtresx64gpr.asm: Move to ../libgcc/config/rs6000/e500crtresx64gpr.S. * config/rs6000/e500crtsav32gpr.asm: Move to ../libgcc/config/rs6000/e500crtsav32gpr.S. * config/rs6000/e500crtsav64gpr.asm: Move to ../libgcc/config/rs6000/e500crtsav64gpr.S. * config/rs6000/e500crtsav64gprctr.asm: Move to ../libgcc/config/rs6000/e500crtsav64gprctr.S. * config/rs6000/e500crtsavg32gpr.asm: Move to ../libgcc/config/rs6000/e500crtsavg32gpr.S. * config/rs6000/e500crtsavg64gpr.asm: Move to ../libgcc/config/rs6000/e500crtsavg64gpr.S. * config/rs6000/e500crtsavg64gprctr.asm: Move to ../libgcc/config/rs6000/e500crtsavg64gprctr.S. * config/rs6000/eabi.asm: Move to ../libgcc/config/rs6000/eabi.S. * config/rs6000/t-aix43 (LIBGCC, INSTALL_LIBGCC, LIB2FUNCS_EXTRA) (TARGET_LIBGCC2_CFLAGS): Remove. * config/rs6000/t-aix52: Likewise. * config/rs6000/t-darwin: Remove. * config/rs6000/t-darwin64 (LIB2_SIDITI_CONV_FUNCS) (LIB2FUNCS_EXTRA): Remove. * config/rs6000/t-fprules (LIBGCC, INSTALL_LIBGCC): Remove. * config/rs6000/t-linux64 (TARGET_LIBGCC2_CFLAGS): Remove. * config/rs6000/t-lynx (LIB2FUNCS_EXTRA, tramp.S, LIBGCC) (INSTALL_LIBGCC): Remove. * config/rs6000/t-netbsd (LIB2FUNCS_EXTRA) (LIB2FUNCS_STATIC_EXTRA, tramp.S, crtsavfpr.S, crtresfpr.S) (crtsavgpr.S, crtresgpr.S, crtresxfpr.S, crtresxgpr.S, LIBGCC) (INSTALL_LIBGCC, $(T)crtsavfpr$(objext), $(T)crtresfpr$(objext)) (($(T)crtsavgpr$(objext), $(T)crtresgpr$(objext), $(T)crtresxfpr$(objext), $(T)crtresxgpr$(objext)): Remove. * config/rs6000/t-ppccomm (LIB2FUNCS_EXTRA) (LIB2FUNCS_STATIC_EXTRA, eabi.S, tramp.S): Remove. * config/rs6000/t-spe (LIBGCC, INSTALL_LIBGCC): Remove. * config/rs6000/t-vxworks: Remove comment. * config/rs6000/tramp.asm: Move to ../libgcc/config/rs6000/tramp.S. * config/rx/t-rx (LIBGCC, INSTALL_LIBGCC): Remove. * config/sh/linux-atomic.asm: Move to ../libgcc/config/sh/linux-atomic.S. * config/sh/t-linux (LIB2FUNCS_EXTRA): Remove. * config/sh/t-netbsd: Remove. * config/sh/t-sh (TARGET_LIBGCC2_CFLAGS, LIBGCC, INSTALL_LIBGCC): Remove. * config/sparc/t-elf (LIBGCC, INSTALL_LIBGCC): Remove. * config/sparc/t-leon: Likewise. * config/sparc/t-leon3: Likewise. * config/sparc/t-linux64: Likewise. * config/sparc/t-netbsd64: Fix typo. Remove comment. * config/spu/divmodti4.c, config/spu/divv2df3.c, config/spu/float_disf.c, config/spu/float_unsdidf.c, config/spu/float_unsdisf.c, config/spu/float_unssidf.c, config/spu/mfc_multi_tag_release.c, config/spu/mfc_multi_tag_reserve.c, config/spu/mfc_tag_release.c, config/spu/mfc_tag_reserve.c, config/spu/mfc_tag_table.c, config/spu/multi3.c: Move to ../libgcc/config/spu. * config/spu/t-spu-elf (TARGET_LIBGCC2_CFLAGS, LIB2FUNCS_EXCLUDE) (LIB2FUNCS_STATIC_EXTRA, LIB2_SIDITI_CONV_FUNCS, LIBGCC) (INSTALL_LIBGCC): Remove. * config/stormy16/stormy16-lib2.c: Move to ../libgcc/config/stormy16/lib2.c. * config/stormy16/stormy16-lib2-ashlsi3.c: Move to ../libgcc/config/stormy16/ashlsi3.c. * config/stormy16/stormy16-lib2-ashrsi3.c: Move to ../libgcc/config/stormy16/ashrsi3.c. * config/stormy16/stormy16-lib2-clzhi2.c: Move to ../libgcc/config/stormy16/clzhi2.c. * config/stormy16/stormy16-lib2-cmpsi2.c: Move to ../libgcc/config/stormy16/cmpsi2.c. * config/stormy16/stormy16-lib2-ctzhi2.c: Move to ../libgcc/config/stormy16/ctzhi2.c. * config/stormy16/stormy16-lib2-divsi3.c: Move to ../libgcc/config/stormy16/divsi3.c. * config/stormy16/stormy16-lib2-ffshi2.c: Move to ../libgcc/config/stormy16/ffshi2.c. * config/stormy16/stormy16-lib2-lshrsi3.c: Move to ../libgcc/config/stormy16/lshrsi3.c. * config/stormy16/stormy16-lib2-modsi3.c: Move to ../libgcc/config/stormy16/modsi3.c. * config/stormy16/stormy16-lib2-parityhi2.c: Move to ../libgcc/config/stormy16/parityhi2.c. * config/stormy16/stormy16-lib2-popcounthi2.c: Move to ../libgcc/config/stormy16/popcounthi2.c. * config/stormy16/stormy16-lib2-ucmpsi2.c: Move to ../libgcc/config/stormy16/ucmpsi2.c. * config/stormy16/stormy16-lib2-udivmodsi4.c: Move to ../libgcc/config/stormy16/udivmodsi4.c. * config/stormy16/stormy16-lib2-udivsi3.c: Move to ../libgcc/config/stormy16/udivsi3.c. * config/stormy16/stormy16-lib2-umodsi3.c: Move to ../libgcc/config/stormy16/umodsi3.c. * config/stormy16/t-stormy16: Move to ../libgcc/config/t-stormy16. * config/v850/t-v850 (INSTALL_LIBGCC): Remove. * config/xtensa/lib2funcs.S: Move to ../libgcc/config/xtensa. * config/xtensa/t-elf: Remove. * config/xtensa/t-xtensa (LIB2FUNCS_EXTRA): Remove. * config.gcc (*-*-freebsd*): Remove t-freebsd, t-freebsd-thread from tmake_file. (*-*-linux*, frv-*-*linux*, *-*-kfreebsd*-gnu, *-*-knetbsd*-gnu, *-*-gnu*, *-*-kopensolaris*-gnu): Remove t-linux from tmake_file. (*-*-netbsd*): Remove t-libgcc-pic from tmake_file. (*-*-openbsd*): Likewise. Remove t-openbsd-thread for posix threads. (alpha*-*-linux*): Remove alpha/t-alpha, alpha/t-ieee from tmake_file. (alpha*-*-freebsd*): Likewise. (alpha*-*-netbsd*): Likewise. (alpha*-*-openbsd*): Likewise. (alpha64-dec-*vms*): Likewise. (alpha*-dec-*vms*): Likewise. (arm*-*-netbsdelf*): Remove arm/t-netbsd from tmake_file. (arm*-*-linux*): Remove t-linux from tmake_file. Remove arm/t-bpabi from tmake_file for arm*-*-linux-*eabi. (arm*-*-uclinux*): Remove arm/t-bpabi from tmake_file for arm*-*-uclinux*eabi. (arm*-*-eabi*, arm*-*-symbianelf* ): Remove arm/t-bpabi from tmake_file for arm*-*-eabi*. (fr30-*-elf): Remove tmake_file. (hppa*64*-*-linux*): Remove tmake_file. (hppa*-*-linux*): Likewise. (hppa[12]*-*-hpux10*): Remove pa/t-pa-hpux10, pa/t-pa-hpux from tmake_file. (hppa*64*-*-hpux11*): Remove pa/t-pa64, pa/t-pa-hpux from tmake_file. (hppa[12]*-*-hpux11*): Remove pa/t-pa-hpux11, pa/t-pa-hpux from tmake_file. (i[34567]86-*-elf*): Remove tmake_file. (x86_64-*-elf*): Likewise. (i[34567]86-*-nto-qnx*): Likewise. (i[34567]86-*-cygwin*): Remove i386/t-cygwin from tmake_file. (i[34567]86-*-mingw*, x86_64-*-mingw*): Remove i386/t-gthr-win32 from tmake_file if using win32 threads. (iq2000*-*-elf*): Remove tmake-file. (microblaze*-linux*): Likewise. (sh-*-elf*, sh[12346l]*-*-elf*, sh-*-linux*) (sh[2346lbe]*-*-linux*, sh-*-netbsdelf*, shl*-*-netbsdelf*) (sh5-*-netbsd*, sh5l*-*-netbsd*, sh64-*-netbsd*) (sh64l*-*-netbsd*): Remove sh/t-netbsd from tmake_file for sh5*-*-netbsd*, sh64*-netbsd*, *-*-netbsd. (xtensa*-*-elf*): Remove tmake_file. gcc/po: * EXCLUDES (config/vxlib.c, gbl-ctors.h, libgcc2.c, libgcc2.h) (longlong.h): Remove. libgcc: * configure.ac: Include ../config/picflag.m4. (GCC_PICFLAG): Call it. Substitute. * configure: Regenerate. * Makefile.in (gcc_srcdir): Remove. (LIBGCC2_DEBUG_CFLAGS, LIBGCC2_CFLAGS, LIBGCC2_INCLUDES) (HOST_LIBGCC2_CFLAGS, PICFLAG, LIB2FUNCS_ST, LIB2FUNCS_EXCLUDE) (LIB2_DIVMOD_FUNCS, LIB2ADD, LIB2ADD_ST): Set. ($(lib2funcs-o), $(lib2funcs-s-o), $(lib2-divmod-o)) ($(lib2-divmod-s-o)): Use $(srcdir) to refer to libgcc2.c. Use $<. Remove comment. * libgcc2.c, libgcc2.h, gbl-ctors.h, longlong.h: New files. * siditi-object.mk ($o$(objext), $(o)_s$(objext)): Use $(srcdir) to refer to libgcc2.c. Use $<. * config/darwin-64.c: New file. * config/darwin-crt3.c: Remove comment. * config/divmod.c, config/floatunsidf.c, config/floatunsisf.c, config/floatunsitf.c, config/floatunsixf.c, config/udivmod.c, config/udivmodsi4.c: New files. * config/memcmp.c, config/memcpy.c, config/memmove.c, config/memset.c: New files. * config/t-crtstuff-pic (CRTSTUFF_T_CFLAGS_S): Use $(PICFLAG). * config/t-darwin (HOST_LIBGCC2_CFLAGS): Set. * config/t-freebsd-thread, config/t-libgcc-pic: New files. * config/t-libunwind (HOST_LIBGCC2_CFLAGS): Set. * config/t-openbsd-thread: New file. * config/t-sol2 (HOST_LIBGCC2_CFLAGS): Remove. * config/t-vxworks, config/vxlib-tls.c, config/vxlib.c: New files. * config/alpha/gthr-posix.c, config/alpha/qrnnd.S: New files. * config/alpha/t-alpha (LIB2ADD): Use $(srcdir) to refer to qrnnd.S. Adapt filename. * config/alpha/t-osf-pthread (LIB2ADD): Use $(srcdir)/config/alpha to refer to gthr-posix.c. * config/alpha/t-vms (LIB2ADD): Set. * config/alpha/vms-gcc_shell_handler.c: New file. * config/arm/bpabi.c, config/arm/fp16.c, config/arm/linux-atomic.c, config/arm/linux-atomic-64bit.c, config/arm/unaligned-funcs.c: New files. * config/arm/t-bpabi (LIB2ADD, LIB2ADD_ST): Set. * config/arm/t-elf (HOST_LIBGCC2_CFLAGS): Set. * config/arm/t-linux: Likewise. * config/arm/t-linux-eabi (LIB2ADD_ST): Add. * config/arm/t-netbsd: New file. * config/arm/t-strongarm-elf (HOST_LIBGCC2_CFLAGS): Set. * config/arm/t-symbian (LIB2ADD_ST): Set. * config/avr/t-avr (LIB2FUNCS_EXCLUDE, HOST_LIBGCC2_CFLAGS): Set. * config/bfin/t-crtstuff (CRTSTUFF_T_CFLAGS): Use $(PICFLAG). * config/bfin/t-elf: New file. * config/c6x/eqd.c, config/c6x/eqf.c, config/c6x/ged.c, config/c6x/gef.c, config/c6x/gtd.c, config/c6x/gtf.c, config/c6x/led.c, config/c6x/lef.c, config/c6x/ltd.c, config/c6x/ltf.c: New files. * config/c6x/t-elf (LIB2FUNCS_EXCLUDE, LIB2ADD) (HOST_LIBGCC2_CFLAGS): Set. * config/c6x/t-uclinux (HOST_LIBGCC2_CFLAGS): Set. (CRTSTUFF_T_CFLAGS): Use $(PICFLAG). * config/cris/arit.c, config/cris/mulsi3.S, config/cris/t-cris: New files. * config/cris/t-elfmulti (LIB2ADD_ST): Set. * config/cris/t-linux (HOST_LIBGCC2_CFLAGS): Remove. * config/frv/cmovd.c, config/frv/cmovh.c, config/frv/cmovw.c, config/frv/modi.c, config/frv/uitod.c, config/frv/uitof.c, config/frv/ulltod.c, config/frv/ulltof.c, config/frv/umodi.c: New files. * config/frv/t-frv (LIB2ADD): Set. * config/frv/t-linux (CRTSTUFF_T_CFLAGS): Use $(PICFLAG). * config/h8300/clzhi2.c, config/h8300/ctzhi2.c, config/h8300/fixunssfsi.c, config/h8300/parityhi2.c, config/h8300/popcounthi2.c: New files. * config/h8300/t-h8300 (LIB2ADD, HOST_LIBGCC2_CFLAGS): Set. * config/i386/gthr-win32.c: New file. * config/i386/t-cygming (LIBGCC2_INCLUDES): Set. * config/i386/t-cygwin: Likewise. * config/i386/t-darwin, config/i386/t-darwin64, config/i386/t-gthr-win32, config/i386/t-interix: New files. * config/i386/t-nto (HOST_LIBGCC2_CFLAGS): Set. (CRTSTUFF_T_CFLAGS): Use $(PICFLAG). * config/i386/t-sol2 (CRTSTUFF_T_CFLAGS): Use $(PICFLAG). * config/ia64/quadlib.c: New file. * config/ia64/t-hpux (LIB2ADD): Set. * config/ia64/t-ia64: Add comment. * config/iq2000/lib2funcs.c, config/iq2000/t-iq2000: New files. * config/lm32/t-uclinux (CRTSTUFF_T_CFLAGS): Use $(PICFLAG). (HOST_LIBGCC2_CFLAGS): Append, remove -fPIC. * config/m32c/lib2funcs.c, config/m32c/trapv.c: New files. * config/m32c/t-m32c (LIB2ADD): Set. * config/m32r/t-linux (HOST_LIBGCC2_CFLAGS): Set. * config/m32r/t-m32r: Likewise. * config/m68k/fpgnulib.c: New file. * config/m68k/t-floatlib (LIB2ADD): Set. (xfgnulib.c): New target. * config/mcore/t-mcore (HOST_LIBGCC2_CFLAGS): Set. * config/mep/lib2funcs.c, config/mep/tramp.c: New files. * config/mep/t-mep (LIB2ADD): Set. * config/microblaze/divsi3.asm: Rename to divsi3.S. * config/microblaze/moddi3.asm: Rename to moddi3.S. * config/microblaze/modsi3.asm: Rename to modsi3.S. * config/microblaze/muldi3_hard.asm: Rename to hard.S. * config/microblaze/mulsi3.asm: Rename to mulsi3.S. * config/microblaze/stack_overflow_exit.asm: Rename to exit.S. * config/microblaze/udivsi3.asm: Rename to udivsi3.S. * config/microblaze/umodsi3.asm: Rename to umodsi3.S. * config/microblaze/t-microblaze (LIB2ADD): Reflect this. * config/mips/t-elf, config/mips/t-vr, config/mips/vr4120-div.S: New files. * config/mips/t-mips (LIB2_SIDITI_CONV_FUNCS): Set. * config/mmix/t-mmix (HOST_LIBGCC2_CFLAGS): Set. * config/pa/fptr.c, config/pa/lib2funcs.S, config/pa/linux-atomic.c, config/pa/quadlib.c: New files. * config/pa/t-linux (HOST_LIBGCC2_CFLAGS): Set. (LIB2ADD, LIB2ADD_ST): Set. * config/pa/t-hpux, config/pa/t-hpux10, config/pa/t-pa64: New files. * config/pa/t-linux (HOST_LIBGCC2_CFLAGS, LIB2ADD, LIB2ADD_ST): Set. * config/pa/t-linux64 (LIB2ADD_ST, HOST_LIBGCC2_CFLAGS): Set. * config/pdp11/t-pdp11: New file. * config/picochip/libgccExtras/adddi3.S, config/picochip/libgccExtras/ashlsi3.S, config/picochip/libgccExtras/ashrsi3.S, config/picochip/libgccExtras/clzsi2.S, config/picochip/libgccExtras/cmpsi2.S, config/picochip/libgccExtras/divmod15.S, config/picochip/libgccExtras/divmodhi4.S, config/picochip/libgccExtras/divmodsi4.S, config/picochip/libgccExtras/lshrsi3.S, config/picochip/libgccExtras/parityhi2.S, config/picochip/libgccExtras/popcounthi2.S, config/picochip/libgccExtras/subdi3.S, config/picochip/libgccExtras/ucmpsi2.S, config/picochip/libgccExtras/udivmodhi4.S, config/picochip/libgccExtras/udivmodsi4.S: New files. * config/picochip/t-picochip (LIB2ADD, HOST_LIBGCC2_CFLAGS) (LIBGCC2_DEBUG_CFLAGS, RANLIB_FOR_TARGET): Set. * config/rs6000/crtresfpr.S, config/rs6000/crtresgpr.S, config/rs6000/crtresxfpr.S, config/rs6000/crtresxgpr.S, config/rs6000/crtsavfpr.S, config/rs6000/crtsavgpr.S) config/rs6000/darwin-asm.h, config/rs6000/darwin-fpsave.S, config/rs6000/darwin-gpsave.S, config/rs6000/darwin-tramp.S, config/rs6000/darwin-vecsave.S, config/rs6000/darwin-world.S: New files. * config/rs6000/t-darwin (LIB2ADD, LIB2ADD_ST) (HOST_LIBGCC2_CFLAGS): Set. * config/rs6000/t-darwin64: New file. * config/rs6000/t-linux64 (HOST_LIBGCC2_CFLAGS): Set. * config/rs6000/t-lynx, config/rs6000/t-netbsd: New files. * config/rs6000/t-ppccomm (LIB2ADD): Add $(srcdir)/config/rs6000/tramp.S. (LIB2ADD_ST): Use $(srcdir)/config/rs6000 to refer to sources. Add $(srcdir)/config/rs6000/eabi.S. (crtsavfpr.S, crtresfpr.S, crtsavgpr.S, crtresgpr.S, crtresxfpr.S) (crtresxgpr.S, e500crtres32gpr.S, e500crtres64gpr.S) (e500crtres64gprctr.S, e500crtrest32gpr.S, e500crtrest64gpr.S) (e500crtresx32gpr.S, e500crtresx64gpr.S, e500crtsav32gpr.S) (e500crtsav64gpr.S, e500crtsav64gprctr.S, e500crtsavg32gpr.S) (e500crtsavg64gpr.S, e500crtsavg64gprctr.S): Remove. * config/rs6000/tramp.S: New file. * config/s390/t-tpf: Remove. * config/sh/linux-atomic.S: New file. * config/sh/t-linux (LIB2ADD): Set. (HOST_LIBGCC2_CFLAGS): Append, remove -fpic. * config/sh/t-netbsd (LIB2ADD, HOST_LIBGCC2_CFLAGS): Set. * config/sh/t-sh (unwind-dw2-Os-4-200.o): Use $(srcdir) to refer to unwind-dw2.c. (HOST_LIBGCC2_CFLAGS): Set. * config/sparc/t-sol2 (CRTSTUFF_T_CFLAGS): Use $(PICFLAG). * config/spu/divmodti4.c, config/spu/divv2df3.c, config/spu/float_disf.c, config/spu/float_unsdidf.c, config/spu/float_unsdisf.c, config/spu/float_unssidf.c, config/spu/mfc_multi_tag_release.c, config/spu/mfc_multi_tag_reserve.c, config/spu/mfc_tag_release.c, config/spu/mfc_tag_reserve.c, config/spu/mfc_tag_table.c, config/spu/multi3.c: New files. * config/spu/t-elf (LIB2ADD, LIB2ADD_ST, LIB2_SIDITI_CONV_FUNCS) (HOST_LIBGCC2_CFLAGS): Set. * config/stormy16/ashlsi3.c, config/stormy16/ashrsi3.c, config/stormy16/clzhi2.c, config/stormy16/cmpsi2.c, config/stormy16/ctzhi2.c, config/stormy16/divsi3.c, config/stormy16/ffshi2.c, config/stormy16/lib2.c, config/stormy16/lshrsi3.c, config/stormy16/modsi3.c, config/stormy16/parityhi2.c, config/stormy16/popcounthi2.c, config/stormy16/t-stormy16, config/stormy16/ucmpsi2.c, config/stormy16/udivmodsi4.c, config/stormy16/udivsi3.c, config/stormy16/umodsi3.c: New files. * config/xtensa/lib2funcs.S: New file. * config/xtensa/t-elf (HOST_LIBGCC2_CFLAGS): Set. * config/xtensa/t-xtensa (LIB2ADD): Set. * config.host (*-*-darwin*): Add t-libgcc-pic to tmake_file. (*-*-freebsd*): Add t-freebsd, t-libgcc-pic to tmake_file. Add t-freebsd-thread to tmake_file for posix threads. (*-*-linux*, frv-*-*linux*, *-*-kfreebsd*-gnu, *-*-knetbsd*-gnu) (*-*-gnu*, *-*-kopensolaris*-gnu): Add t-libgcc-pic to tmake_file. (*-*-lynxos*): Likewise. (*-*-netbsd*): Likewise. (*-*-openbsd*): Likewise. Add t-openbsd-thread to tmake_file for posix threads. (*-*-solaris2*): Add t-libgcc-pic to tmake_file. (*-*-vxworks*): Set tmake_file. (alpha*-*-linux*): Add alpha/t-alpha, alpha/t-ieee to tmake_file. (alpha*-*-freebsd*): Likewise. (alpha*-*-netbsd*): Likewise. (alpha*-*-openbsd*): Likewise. (alpha*-dec-osf5.1*): Remove qrnnd.o, gthr-posix.o from extra_parts. (alpha64-dec-*vms*): Add alpha/t-alpha, alpha/t-ieee to tmake_file. (alpha*-dec-*vms*): Likewise. (arm*-*-netbsdelf*): Add arm/t-netbsd to tmake_file. (bfin*-elf*): Add bfin/t-elf to tmake_file. (bfin*-uclinux*): Likewise. (bfin*-linux-uclibc*): Likewise. (crisv32-*-elf): Add cris/t-cris to tmake_file. (crisv32-*-none): Likewise. (cris-*-elf): Likewise. (cris-*-none): Likewise. (cris-*-linux*, crisv32-*-linux*): Likewise. (hppa[12]*-*-hpux10*): Add pa/t-hpux pa/t-hpux10, t-libgcc-pic to tmake_file. (hppa*64*-*-hpux11*): Add pa/t-hpux, pa/t-pa64, t-libgcc-pic to tmake_file. (hppa[12]*-*-hpux11*): Add pa/t-hpux, t-libgcc-pic to tmake_file. (i[34567]86-*-elf*): Add t-libgcc-pic to tmake_file. (x86_64-*-elf*): Likewise. (i[34567]86-*-nto-qnx*): Likewise. (i[34567]86-*-mingw*): Add i386/t-gthr-win32 to tmake_file for win32 threads. (x86_64-*-mingw*): Likewise. (i[34567]86-*-interix3*): Add i386/t-interix to tmake_file. (lm32-*-uclinux*): Add t-libgcc-pic to tmake_file. (mipsisa32-*-elf*, mipsisa32el-*-elf*, mipsisa32r2-*-elf*) (mipsisa32r2el-*-elf*, mipsisa64-*-elf*, mipsisa64el-*-elf*) (mipsisa64r2-*-elf*, mipsisa64r2el-*-elf*): Add mips/t-elf to tmake_file. (mipsisa64sr71k-*-elf*): Likewise. (mipsisa64sb1-*-elf*, mipsisa64sb1el-*-elf*): Likewise. (mips-*-elf*, mipsel-*-elf*): Likewise. (mips64-*-elf*, mips64el-*-elf*): Likewise. (mips64orion-*-elf*, mips64orionel-*-elf*): Likewise. (mips*-*-rtems*): Likewise. (mips64vr-*-elf*, mips64vrel-*-elf*): Add mips/t-elf, mips/t-vr to tmake_file. (pdp11-*-*): Add pdp11/t-pdp11 to tmake_file. (powerpc64-*-darwin*): Add rs6000/t-darwin64 to tmake_file. (s390x-ibm-tpf*): Add t-libgcc-pic to tmake_file. (spu-*-elf*): Likewise. (tic6x-*-uclinux): Add t-libgcc-pic to tmake_file. libquadmath: * printf/gmp-impl.h: Adapt path to longlong.h. From-SVN: r180774
529 lines
16 KiB
C
529 lines
16 KiB
C
/* __cxa_atexit backwards-compatibility support for Darwin.
|
|
Copyright (C) 2006, 2009, 2011 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 3, or (at your option) any later
|
|
version.
|
|
|
|
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.
|
|
|
|
Under Section 7 of GPL version 3, you are granted additional
|
|
permissions described in the GCC Runtime Library Exception, version
|
|
3.1, as published by the Free Software Foundation.
|
|
|
|
You should have received a copy of the GNU General Public License and
|
|
a copy of the GCC Runtime Library Exception along with this program;
|
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
/* Don't do anything if we are compiling for a kext multilib. */
|
|
#ifdef __PIC__
|
|
|
|
#include "tconfig.h"
|
|
#include "tsystem.h"
|
|
|
|
#include <dlfcn.h>
|
|
#include <stdbool.h>
|
|
#include <stdlib.h>
|
|
#include <string.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 a complete atexit and
|
|
__cxa_atexit emulation called from the regular atexit.
|
|
|
|
The second problem is that on all shipping versions of Mac OS,
|
|
__cxa_finalize and exit() don't work right: they don't run routines
|
|
that were registered while other atexit routines are running. This
|
|
is worked around by wrapping each atexit/__cxa_atexit routine with
|
|
our own routine which ensures that any __cxa_atexit calls while it
|
|
is running are honoured.
|
|
|
|
There are still problems which this does not solve. Before 10.4,
|
|
shared objects linked with previous compilers won't have their
|
|
atexit calls properly interleaved with code compiled with newer
|
|
compilers. Also, atexit routines registered from shared objects
|
|
linked with previous compilers won't get the bug fix. */
|
|
|
|
typedef int (*cxa_atexit_p)(void (*func) (void*), void* arg, const void* dso);
|
|
typedef void (*cxa_finalize_p)(const void *dso);
|
|
typedef int (*atexit_p)(void (*func)(void));
|
|
|
|
/* These are from "keymgr.h". */
|
|
extern void *_keymgr_get_and_lock_processwide_ptr (unsigned key);
|
|
extern int _keymgr_get_and_lock_processwide_ptr_2 (unsigned, void **);
|
|
extern int _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 ;
|
|
|
|
#ifdef __ppc__
|
|
#define CHECK_KEYMGR_ERROR(e) \
|
|
(((_Tinfo_Node *)__keymgr_global[2])->major_version >= 4 ? (e) : 0)
|
|
#else
|
|
#define CHECK_KEYMGR_ERROR(e) (e)
|
|
#endif
|
|
|
|
/* Our globals are stored under this keymgr index. */
|
|
#define KEYMGR_ATEXIT_LIST 14
|
|
|
|
/* The different kinds of callback routines. */
|
|
typedef void (*atexit_callback)(void);
|
|
typedef void (*cxa_atexit_callback)(void *);
|
|
|
|
/* This structure holds a routine to call. There may be extra fields
|
|
at the end of the structure that this code doesn't know about. */
|
|
struct one_atexit_routine
|
|
{
|
|
union {
|
|
atexit_callback ac;
|
|
cxa_atexit_callback cac;
|
|
} callback;
|
|
/* has_arg is 0/2/4 if 'ac' is live, 1/3/5 if 'cac' is live.
|
|
Higher numbers indicate a later version of the structure that this
|
|
code doesn't understand and will ignore. */
|
|
int has_arg;
|
|
void * arg;
|
|
};
|
|
|
|
struct atexit_routine_list
|
|
{
|
|
struct atexit_routine_list * next;
|
|
struct one_atexit_routine r;
|
|
};
|
|
|
|
/* The various possibilities for status of atexit(). */
|
|
enum atexit_status {
|
|
atexit_status_unknown = 0,
|
|
atexit_status_missing = 1,
|
|
atexit_status_broken = 2,
|
|
atexit_status_working = 16
|
|
};
|
|
|
|
struct keymgr_atexit_list
|
|
{
|
|
/* Version of this list. This code knows only about version 0.
|
|
If the version is higher than 0, this code may add new atexit routines
|
|
but should not attempt to run the list. */
|
|
short version;
|
|
/* 1 if an atexit routine is currently being run by this code, 0
|
|
otherwise. */
|
|
char running_routines;
|
|
/* Holds a value from 'enum atexit_status'. */
|
|
unsigned char atexit_status;
|
|
/* The list of atexit and cxa_atexit routines registered. If
|
|
atexit_status_missing it contains all routines registered while
|
|
linked with this code. If atexit_status_broken it contains all
|
|
routines registered during cxa_finalize while linked with this
|
|
code. */
|
|
struct atexit_routine_list *l;
|
|
/* &__cxa_atexit; set if atexit_status >= atexit_status_broken. */
|
|
cxa_atexit_p cxa_atexit_f;
|
|
/* &__cxa_finalize; set if atexit_status >= atexit_status_broken. */
|
|
cxa_finalize_p cxa_finalize_f;
|
|
/* &atexit; set if atexit_status >= atexit_status_working
|
|
or atexit_status == atexit_status_missing. */
|
|
atexit_p atexit_f;
|
|
};
|
|
|
|
/* Return 0 if __cxa_atexit has the bug it has in Mac OS 10.4: it
|
|
fails to call routines registered while an atexit routine is
|
|
running. Return 1 if it works properly, and -1 if an error occurred. */
|
|
|
|
struct atexit_data
|
|
{
|
|
int result;
|
|
cxa_atexit_p cxa_atexit;
|
|
};
|
|
|
|
static void cxa_atexit_check_2 (void *arg)
|
|
{
|
|
((struct atexit_data *)arg)->result = 1;
|
|
}
|
|
|
|
static void cxa_atexit_check_1 (void *arg)
|
|
{
|
|
struct atexit_data * aed = arg;
|
|
if (aed->cxa_atexit (cxa_atexit_check_2, arg, arg) != 0)
|
|
aed->result = -1;
|
|
}
|
|
|
|
static int
|
|
check_cxa_atexit (cxa_atexit_p cxa_atexit, cxa_finalize_p cxa_finalize)
|
|
{
|
|
struct atexit_data aed = { 0, cxa_atexit };
|
|
|
|
/* We re-use &aed as the 'dso' parameter, since it's a unique address. */
|
|
if (cxa_atexit (cxa_atexit_check_1, &aed, &aed) != 0)
|
|
return -1;
|
|
cxa_finalize (&aed);
|
|
if (aed.result == 0)
|
|
{
|
|
/* Call __cxa_finalize again to make sure that cxa_atexit_check_2
|
|
is removed from the list before AED goes out of scope. */
|
|
cxa_finalize (&aed);
|
|
aed.result = 0;
|
|
}
|
|
return aed.result;
|
|
}
|
|
|
|
#ifdef __ppc__
|
|
/* This comes from Csu. It works only before 10.4. The prototype has
|
|
been altered a bit to avoid casting. */
|
|
extern int _dyld_func_lookup(const char *dyld_func_name,
|
|
void *address) __attribute__((visibility("hidden")));
|
|
|
|
static void our_atexit (void);
|
|
|
|
/* We're running on 10.3.9. Find the address of the system atexit()
|
|
function. So easy to say, so hard to do. */
|
|
static atexit_p
|
|
find_atexit_10_3 (void)
|
|
{
|
|
unsigned int (*dyld_image_count_fn)(void);
|
|
const char *(*dyld_get_image_name_fn)(unsigned int image_index);
|
|
const void *(*dyld_get_image_header_fn)(unsigned int image_index);
|
|
const void *(*NSLookupSymbolInImage_fn)(const void *image,
|
|
const char *symbolName,
|
|
unsigned int options);
|
|
void *(*NSAddressOfSymbol_fn)(const void *symbol);
|
|
unsigned i, count;
|
|
|
|
/* Find some dyld functions. */
|
|
_dyld_func_lookup("__dyld_image_count", &dyld_image_count_fn);
|
|
_dyld_func_lookup("__dyld_get_image_name", &dyld_get_image_name_fn);
|
|
_dyld_func_lookup("__dyld_get_image_header", &dyld_get_image_header_fn);
|
|
_dyld_func_lookup("__dyld_NSLookupSymbolInImage", &NSLookupSymbolInImage_fn);
|
|
_dyld_func_lookup("__dyld_NSAddressOfSymbol", &NSAddressOfSymbol_fn);
|
|
|
|
/* If any of these don't exist, that's an error. */
|
|
if (! dyld_image_count_fn || ! dyld_get_image_name_fn
|
|
|| ! dyld_get_image_header_fn || ! NSLookupSymbolInImage_fn
|
|
|| ! NSAddressOfSymbol_fn)
|
|
return NULL;
|
|
|
|
count = dyld_image_count_fn ();
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
const char * path = dyld_get_image_name_fn (i);
|
|
const void * image;
|
|
const void * symbol;
|
|
|
|
if (strcmp (path, "/usr/lib/libSystem.B.dylib") != 0)
|
|
continue;
|
|
image = dyld_get_image_header_fn (i);
|
|
if (! image)
|
|
return NULL;
|
|
/* '4' is NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR. */
|
|
symbol = NSLookupSymbolInImage_fn (image, "_atexit", 4);
|
|
if (! symbol)
|
|
return NULL;
|
|
return NSAddressOfSymbol_fn (symbol);
|
|
}
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
/* Create (if necessary), find, lock, fill in, and return our globals.
|
|
Return NULL on error, in which case the globals will not be locked.
|
|
The caller should call keymgr_set_and_unlock. */
|
|
static struct keymgr_atexit_list *
|
|
get_globals (void)
|
|
{
|
|
struct keymgr_atexit_list * r;
|
|
|
|
#ifdef __ppc__
|
|
/* 10.3.9 doesn't have _keymgr_get_and_lock_processwide_ptr_2 so the
|
|
PPC side can't use it. On 10.4 this just means the error gets
|
|
reported a little later when
|
|
_keymgr_set_and_unlock_processwide_ptr finds that the key was
|
|
never locked. */
|
|
r = _keymgr_get_and_lock_processwide_ptr (KEYMGR_ATEXIT_LIST);
|
|
#else
|
|
void * rr;
|
|
if (_keymgr_get_and_lock_processwide_ptr_2 (KEYMGR_ATEXIT_LIST, &rr))
|
|
return NULL;
|
|
r = rr;
|
|
#endif
|
|
|
|
if (r == NULL)
|
|
{
|
|
r = calloc (sizeof (struct keymgr_atexit_list), 1);
|
|
if (! r)
|
|
return NULL;
|
|
}
|
|
|
|
if (r->atexit_status == atexit_status_unknown)
|
|
{
|
|
void *handle;
|
|
|
|
handle = dlopen ("/usr/lib/libSystem.B.dylib", RTLD_NOLOAD);
|
|
if (!handle)
|
|
{
|
|
#ifdef __ppc__
|
|
r->atexit_status = atexit_status_missing;
|
|
r->atexit_f = find_atexit_10_3 ();
|
|
if (! r->atexit_f)
|
|
goto error;
|
|
if (r->atexit_f (our_atexit))
|
|
goto error;
|
|
#else
|
|
goto error;
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
int chk_result;
|
|
|
|
r->cxa_atexit_f = (cxa_atexit_p)dlsym (handle, "__cxa_atexit");
|
|
r->cxa_finalize_f = (cxa_finalize_p)dlsym (handle, "__cxa_finalize");
|
|
if (! r->cxa_atexit_f || ! r->cxa_finalize_f)
|
|
goto error;
|
|
|
|
chk_result = check_cxa_atexit (r->cxa_atexit_f, r->cxa_finalize_f);
|
|
if (chk_result == -1)
|
|
goto error;
|
|
else if (chk_result == 0)
|
|
r->atexit_status = atexit_status_broken;
|
|
else
|
|
{
|
|
r->atexit_f = (atexit_p)dlsym (handle, "atexit");
|
|
if (! r->atexit_f)
|
|
goto error;
|
|
r->atexit_status = atexit_status_working;
|
|
}
|
|
}
|
|
}
|
|
|
|
return r;
|
|
|
|
error:
|
|
_keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, r);
|
|
return NULL;
|
|
}
|
|
|
|
/* Add TO_ADD to ATEXIT_LIST. ATEXIT_LIST may be NULL but is
|
|
always the result of calling _keymgr_get_and_lock_processwide_ptr and
|
|
so KEYMGR_ATEXIT_LIST is known to be locked; this routine is responsible
|
|
for unlocking it. */
|
|
|
|
static int
|
|
add_routine (struct keymgr_atexit_list * g,
|
|
const struct one_atexit_routine * to_add)
|
|
{
|
|
struct atexit_routine_list * s
|
|
= malloc (sizeof (struct atexit_routine_list));
|
|
int result;
|
|
|
|
if (!s)
|
|
{
|
|
_keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);
|
|
return -1;
|
|
}
|
|
s->r = *to_add;
|
|
s->next = g->l;
|
|
g->l = s;
|
|
result = _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);
|
|
return CHECK_KEYMGR_ERROR (result) == 0 ? 0 : -1;
|
|
}
|
|
|
|
/* This runs the routines in G->L up to STOP. */
|
|
static struct keymgr_atexit_list *
|
|
run_routines (struct keymgr_atexit_list *g,
|
|
struct atexit_routine_list *stop)
|
|
{
|
|
for (;;)
|
|
{
|
|
struct atexit_routine_list * cur = g->l;
|
|
if (! cur || cur == stop)
|
|
break;
|
|
g->l = cur->next;
|
|
_keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);
|
|
|
|
switch (cur->r.has_arg) {
|
|
case 0: case 2: case 4:
|
|
cur->r.callback.ac ();
|
|
break;
|
|
case 1: case 3: case 5:
|
|
cur->r.callback.cac (cur->r.arg);
|
|
break;
|
|
default:
|
|
/* Don't understand, so don't call it. */
|
|
break;
|
|
}
|
|
free (cur);
|
|
|
|
g = _keymgr_get_and_lock_processwide_ptr (KEYMGR_ATEXIT_LIST);
|
|
if (! g)
|
|
break;
|
|
}
|
|
return g;
|
|
}
|
|
|
|
/* Call the routine described by ROUTINE_PARAM and then call any
|
|
routines added to KEYMGR_ATEXIT_LIST while that routine was
|
|
running, all with in_cxa_finalize set. */
|
|
|
|
static void
|
|
cxa_atexit_wrapper (void* routine_param)
|
|
{
|
|
struct one_atexit_routine * routine = routine_param;
|
|
struct keymgr_atexit_list *g;
|
|
struct atexit_routine_list * base = NULL;
|
|
char prev_running = 0;
|
|
|
|
g = _keymgr_get_and_lock_processwide_ptr (KEYMGR_ATEXIT_LIST);
|
|
if (g)
|
|
{
|
|
prev_running = g->running_routines;
|
|
g->running_routines = 1;
|
|
base = g->l;
|
|
_keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);
|
|
}
|
|
|
|
if (routine->has_arg)
|
|
routine->callback.cac (routine->arg);
|
|
else
|
|
routine->callback.ac ();
|
|
|
|
if (g)
|
|
g = _keymgr_get_and_lock_processwide_ptr (KEYMGR_ATEXIT_LIST);
|
|
if (g)
|
|
g = run_routines (g, base);
|
|
if (g)
|
|
{
|
|
g->running_routines = prev_running;
|
|
_keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);
|
|
}
|
|
}
|
|
|
|
#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 routine is called from the system atexit(); it runs everything
|
|
registered on the KEYMGR_ATEXIT_LIST. */
|
|
|
|
static void
|
|
our_atexit (void)
|
|
{
|
|
struct keymgr_atexit_list *g;
|
|
char prev_running;
|
|
|
|
g = _keymgr_get_and_lock_processwide_ptr (KEYMGR_ATEXIT_LIST);
|
|
if (! g || g->version != 0 || g->atexit_status != atexit_status_missing)
|
|
return;
|
|
|
|
prev_running = g->running_routines;
|
|
g->running_routines = 1;
|
|
g = run_routines (g, NULL);
|
|
if (! g)
|
|
return;
|
|
g->running_routines = prev_running;
|
|
_keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);
|
|
}
|
|
#endif
|
|
|
|
/* This is our wrapper around atexit and __cxa_atexit. It will return
|
|
nonzero if an error occurs, and otherwise:
|
|
- if in_cxa_finalize is set, or running on 10.3.9, add R to
|
|
KEYMGR_ATEXIT_LIST; or
|
|
- call the system __cxa_atexit to add cxa_atexit_wrapper with an argument
|
|
that indicates how cxa_atexit_wrapper should call R. */
|
|
|
|
static int
|
|
atexit_common (const struct one_atexit_routine *r, const void *dso)
|
|
{
|
|
struct keymgr_atexit_list *g = get_globals ();
|
|
|
|
if (! g)
|
|
return -1;
|
|
|
|
if (g->running_routines || g->atexit_status == atexit_status_missing)
|
|
return add_routine (g, r);
|
|
|
|
if (g->atexit_status >= atexit_status_working)
|
|
{
|
|
int result;
|
|
if (r->has_arg)
|
|
{
|
|
cxa_atexit_p cxa_atexit = g->cxa_atexit_f;
|
|
result = _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST,
|
|
g);
|
|
if (CHECK_KEYMGR_ERROR (result))
|
|
return -1;
|
|
return cxa_atexit (r->callback.cac, r->arg, dso);
|
|
}
|
|
else
|
|
{
|
|
atexit_p atexit_f = g->atexit_f;
|
|
result = _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST,
|
|
g);
|
|
if (CHECK_KEYMGR_ERROR (result))
|
|
return -1;
|
|
return atexit_f (r->callback.ac);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cxa_atexit_p cxa_atexit = g->cxa_atexit_f;
|
|
struct one_atexit_routine *alloced;
|
|
int result;
|
|
|
|
result = _keymgr_set_and_unlock_processwide_ptr (KEYMGR_ATEXIT_LIST, g);
|
|
if (CHECK_KEYMGR_ERROR (result))
|
|
return -1;
|
|
|
|
alloced = malloc (sizeof (struct one_atexit_routine));
|
|
if (! alloced)
|
|
return -1;
|
|
*alloced = *r;
|
|
return cxa_atexit (cxa_atexit_wrapper, alloced, dso);
|
|
}
|
|
}
|
|
|
|
/* These are the actual replacement routines; they just funnel into
|
|
atexit_common. */
|
|
|
|
int __cxa_atexit (cxa_atexit_callback func, void* arg,
|
|
const void* dso) __attribute__((visibility("hidden")));
|
|
|
|
int
|
|
__cxa_atexit (cxa_atexit_callback func, void* arg, const void* dso)
|
|
{
|
|
struct one_atexit_routine r;
|
|
r.callback.cac = func;
|
|
r.has_arg = 1;
|
|
r.arg = arg;
|
|
return atexit_common (&r, dso);
|
|
}
|
|
|
|
int atexit (atexit_callback func) __attribute__((visibility("hidden")));
|
|
|
|
/* Use __dso_handle to allow even bundles that call atexit() to be unloaded
|
|
on 10.4. */
|
|
extern void __dso_handle;
|
|
|
|
int
|
|
atexit (atexit_callback func)
|
|
{
|
|
struct one_atexit_routine r;
|
|
r.callback.ac = func;
|
|
r.has_arg = 0;
|
|
return atexit_common (&r, &__dso_handle);
|
|
}
|
|
|
|
#endif /* __PIC__ */
|