Merged to master at 84d462594c01..f644f50aae5e (from, to] You can see the entire diff with 'git diff' or at https://github.com/brho/akaros/compare/84d462594c01...f644f50aae5e
You'll need to rebuild your toolchain eventually, but there's no rush. Barret On 2016-08-19 at 13:53 Barret Rhoden <[email protected]> wrote: > If we don't build with PT_GNU_EN_FRAME set, our shared libraries (e.g. > libm.so) will have a dependency on unwinding, which can get erronously > linked with libgcc_eh.a's hidden __register_frame_info. > > Those references would come from frame_dummy(), called from _init. On > Linux, this doesn't happen, and we attempt to be as similar to Linux > as possible, at least regarding the toolchain. > > Note that USE_PT_GNU_EH_FRAME is not set when CRTSTUFFT_0 is set. > That is explicitly set when building with -static. That makes some > sense, since static apps will link against libgcc_eh.a (and not > libgcc_s.so), and the dynamic apps will use the PT_GNU_EH_FRAME. > > There's some info on this stuff here: > > http://www.airs.com/blog/archives/166 > > Rebuild your toolchain. > > Signed-off-by: Barret Rhoden <[email protected]> > --- > .../gcc-glibc/gcc-4.9.2-akaros/libgcc/crtstuff.c | 765 > +++++++++++++++++++++ 1 file changed, 765 insertions(+) > create mode 100644 > tools/compilers/gcc-glibc/gcc-4.9.2-akaros/libgcc/crtstuff.c > > diff --git > a/tools/compilers/gcc-glibc/gcc-4.9.2-akaros/libgcc/crtstuff.c > b/tools/compilers/gcc-glibc/gcc-4.9.2-akaros/libgcc/crtstuff.c new > file mode 100644 index 000000000000..480631b92944 --- /dev/null > +++ b/tools/compilers/gcc-glibc/gcc-4.9.2-akaros/libgcc/crtstuff.c > @@ -0,0 +1,765 @@ > +/* Specialized bits of code needed to support construction and > + destruction of file-scope objects in C++ code. > + Copyright (C) 1991-2014 Free Software Foundation, Inc. > + Contributed by Ron Guilmette ([email protected]). > + > +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/>. */ > + > +/* This file is a bit like libgcc2.c in that it is compiled > + multiple times and yields multiple .o files. > + > + This file is useful on target machines where the object file > format > + supports multiple "user-defined" sections (e.g. COFF, ELF, > ROSE). On > + such systems, this file allows us to avoid running collect (or any > + other such slow and painful kludge). Additionally, if the target > + system supports a .init section, this file allows us to support > the > + linking of C++ code with a non-C++ main program. > + > + Note that if INIT_SECTION_ASM_OP is defined in the tm.h file, then > + this file *will* make use of the .init section. If that symbol is > + not defined however, then the .init section will not be used. > + > + Currently, only ELF and COFF are supported. It is likely however > that > + ROSE could also be supported, if someone was willing to do the > work to > + make whatever (small?) adaptations are needed. (Some work may be > + needed on the ROSE assembler and linker also.) > + > + This file must be compiled with gcc. */ > + > +/* AKAROS: changed so we set # define USE_PT_GNU_EH_FRAME */ > + > +/* Target machine header files require this define. */ > +#define IN_LIBGCC2 > + > +/* FIXME: Including auto-host is incorrect, but until we have > + identified the set of defines that need to go into auto-target.h, > + this will have to do. */ > +#include "auto-host.h" > +#undef pid_t > +#undef rlim_t > +#undef ssize_t > +#undef vfork > +#include "tconfig.h" > +#include "tsystem.h" > +#include "coretypes.h" > +#include "tm.h" > +#include "libgcc_tm.h" > +#include "unwind-dw2-fde.h" > + > +#ifndef FORCE_CODE_SECTION_ALIGN > +# define FORCE_CODE_SECTION_ALIGN > +#endif > + > +#ifndef CRT_CALL_STATIC_FUNCTION > +# define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ > +static void __attribute__((__used__)) \ > +call_ ## FUNC (void) \ > +{ \ > + asm (SECTION_OP); \ > + FUNC (); \ > + FORCE_CODE_SECTION_ALIGN \ > + asm (TEXT_SECTION_ASM_OP); \ > +} > +#endif > + > +#if defined(OBJECT_FORMAT_ELF) \ > + && !defined(OBJECT_FORMAT_FLAT) \ > + && defined(HAVE_LD_EH_FRAME_HDR) \ > + && !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \ > + && defined(__FreeBSD__) && __FreeBSD__ >= 7 > +#include <link.h> > +# define USE_PT_GNU_EH_FRAME > +#endif > + > +#if defined(OBJECT_FORMAT_ELF) \ > + && !defined(OBJECT_FORMAT_FLAT) \ > + && defined(HAVE_LD_EH_FRAME_HDR) && > defined(TARGET_DL_ITERATE_PHDR) \ > + && !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \ > + && defined(__sun__) && defined(__svr4__) > +#include <link.h> > +# define USE_PT_GNU_EH_FRAME > +#endif > + > +#if defined(OBJECT_FORMAT_ELF) \ > + && !defined(OBJECT_FORMAT_FLAT) \ > + && defined(HAVE_LD_EH_FRAME_HDR) \ > + && !defined(inhibit_libc) && !defined(CRTSTUFFT_O) \ > + && defined(__GLIBC__) && __GLIBC__ >= 2 > +#include <link.h> > +/* uClibc pretends to be glibc 2.2 and DT_CONFIG is defined in its > link.h. > + But it doesn't use PT_GNU_EH_FRAME ELF segment currently. */ > +# if !defined(__UCLIBC__) \ > + && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \ > + || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && > defined(DT_CONFIG))) +# define USE_PT_GNU_EH_FRAME > +# endif > +#endif > + > +/* AKAROS: added __gnu_akaros__ */ > +#if defined(OBJECT_FORMAT_ELF) \ > + && !defined(OBJECT_FORMAT_FLAT) \ > + && defined(HAVE_LD_EH_FRAME_HDR) \ > + && !defined(CRTSTUFFT_O) \ > + && defined(inhibit_libc) \ > + && (defined(__GLIBC__) || defined(__gnu_linux__) || \ > + defined(__gnu_akaros__) || defined(__GNU__)) > +/* On systems using glibc, an inhibit_libc build of libgcc is only > + part of a bootstrap process. Build the same crt*.o as would be > + built with headers present, so that it is not necessary to build > + glibc more than once for the bootstrap to converge. */ > +# define USE_PT_GNU_EH_FRAME > +#endif > + > +#if defined(EH_FRAME_SECTION_NAME) && !defined(USE_PT_GNU_EH_FRAME) > +# define USE_EH_FRAME_REGISTRY > +#endif > +#if defined(EH_FRAME_SECTION_NAME) && EH_TABLES_CAN_BE_READ_ONLY > +# define EH_FRAME_SECTION_CONST const > +#else > +# define EH_FRAME_SECTION_CONST > +#endif > + > +#if !defined(DTOR_LIST_END) && defined(OBJECT_FORMAT_ELF) \ > + && defined(HAVE_GAS_HIDDEN) > && !defined(FINI_ARRAY_SECTION_ASM_OP) +# define HIDDEN_DTOR_LIST_END > +#endif > + > +#if !defined(USE_TM_CLONE_REGISTRY) && defined(OBJECT_FORMAT_ELF) > +# define USE_TM_CLONE_REGISTRY 1 > +#endif > + > +/* We do not want to add the weak attribute to the declarations of > these > + routines in unwind-dw2-fde.h because that will cause the > definition of > + these symbols to be weak as well. > + > + This exposes a core issue, how to handle creating weak references > vs > + how to create weak definitions. Either we have to have the > definition > + of TARGET_WEAK_ATTRIBUTE be conditional in the shared header > files or > + have a second declaration if we want a function's references to > be weak, > + but not its definition. > + > + Making TARGET_WEAK_ATTRIBUTE conditional seems like a good > solution until > + one thinks about scaling to larger problems -- i.e., the > condition under > + which TARGET_WEAK_ATTRIBUTE is active will eventually get far too > + complicated. > + > + So, we take an approach similar to #pragma weak -- we have a > second > + declaration for functions that we want to have weak references. > + > + Neither way is particularly good. */ > + > +/* References to __register_frame_info and __deregister_frame_info > should > + be weak in this file if at all possible. */ > +extern void __register_frame_info (const void *, struct object *) > + TARGET_ATTRIBUTE_WEAK; > +extern void __register_frame_info_bases (const void *, struct object > *, > + void *, void *) > + TARGET_ATTRIBUTE_WEAK; > +extern void *__deregister_frame_info (const void *) > + TARGET_ATTRIBUTE_WEAK; > +extern void *__deregister_frame_info_bases (const void *) > + TARGET_ATTRIBUTE_WEAK; > +extern void __do_global_ctors_1 (void); > + > +/* Likewise for _Jv_RegisterClasses. */ > +extern void _Jv_RegisterClasses (void *) TARGET_ATTRIBUTE_WEAK; > + > +/* Likewise for transactional memory clone tables. */ > +extern void _ITM_registerTMCloneTable (void *, size_t) > TARGET_ATTRIBUTE_WEAK; +extern void _ITM_deregisterTMCloneTable (void > *) TARGET_ATTRIBUTE_WEAK; + > +#ifdef OBJECT_FORMAT_ELF > + > +/* Declare a pointer to void function type. */ > +typedef void (*func_ptr) (void); > +#define STATIC static > + > +#else /* OBJECT_FORMAT_ELF */ > + > +#include "gbl-ctors.h" > + > +#define STATIC > + > +#endif /* OBJECT_FORMAT_ELF */ > + > +#ifdef CRT_BEGIN > + > +/* NOTE: In order to be able to support SVR4 shared libraries, we > arrange > + to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, > __CTOR_END__, > + __DTOR_END__ } per root executable and also one set of these > symbols > + per shared library. So in any given whole process image, we may > have > + multiple definitions of each of these symbols. In order to > prevent > + these definitions from conflicting with one another, and in order > to > + ensure that the proper lists are used for the > initialization/finalization > + of each individual shared library (respectively), we give these > symbols > + only internal (i.e. `static') linkage, and we also make it a > point to > + refer to only the __CTOR_END__ symbol in crtend.o and the > __DTOR_LIST__ > + symbol in crtbegin.o, where they are defined. */ > + > +/* No need for .ctors/.dtors section if linker can place them in > + .init_array/.fini_array section. */ > +#ifndef USE_INITFINI_ARRAY > +/* The -1 is a flag to __do_global_[cd]tors indicating that this > table > + does not start with a count of elements. */ > +#ifdef CTOR_LIST_BEGIN > +CTOR_LIST_BEGIN; > +#elif defined(CTORS_SECTION_ASM_OP) > +/* Hack: force cc1 to switch to .data section early, so that > assembling > + __CTOR_LIST__ does not undo our behind-the-back change > to .ctors. */ +static func_ptr force_to_data[1] __attribute__ > ((__used__)) = { }; +asm (CTORS_SECTION_ASM_OP); > +STATIC func_ptr __CTOR_LIST__[1] > + __attribute__ ((__used__, aligned(sizeof(func_ptr)))) > + = { (func_ptr) (-1) }; > +#else > +STATIC func_ptr __CTOR_LIST__[1] > + __attribute__ ((__used__, section(".ctors"), > aligned(sizeof(func_ptr)))) > + = { (func_ptr) (-1) }; > +#endif /* __CTOR_LIST__ alternatives */ > + > +#ifdef DTOR_LIST_BEGIN > +DTOR_LIST_BEGIN; > +#elif defined(DTORS_SECTION_ASM_OP) > +asm (DTORS_SECTION_ASM_OP); > +STATIC func_ptr __DTOR_LIST__[1] > + __attribute__ ((aligned(sizeof(func_ptr)))) > + = { (func_ptr) (-1) }; > +#else > +STATIC func_ptr __DTOR_LIST__[1] > + __attribute__((section(".dtors"), aligned(sizeof(func_ptr)))) > + = { (func_ptr) (-1) }; > +#endif /* __DTOR_LIST__ alternatives */ > +#endif /* USE_INITFINI_ARRAY */ > + > +#ifdef USE_EH_FRAME_REGISTRY > +/* Stick a label at the beginning of the frame unwind info so we can > register > + and deregister it with the exception handling library code. */ > +STATIC EH_FRAME_SECTION_CONST char __EH_FRAME_BEGIN__[] > + __attribute__((section(EH_FRAME_SECTION_NAME), aligned(4))) > + = { }; > +#endif /* USE_EH_FRAME_REGISTRY */ > + > +#ifdef JCR_SECTION_NAME > +/* Stick a label at the beginning of the java class registration info > + so we can register them properly. */ > +STATIC void *__JCR_LIST__[] > + __attribute__ ((used, section(JCR_SECTION_NAME), > aligned(sizeof(void*)))) > + = { }; > +#endif /* JCR_SECTION_NAME */ > + > +#if USE_TM_CLONE_REGISTRY > +STATIC func_ptr __TMC_LIST__[] > + __attribute__((used, section(".tm_clone_table"), > aligned(sizeof(void*)))) > + = { }; > +# ifdef HAVE_GAS_HIDDEN > +extern func_ptr __TMC_END__[] __attribute__((__visibility__ > ("hidden"))); +# endif > + > +static inline void > +deregister_tm_clones (void) > +{ > + void (*fn) (void *); > + > +#ifdef HAVE_GAS_HIDDEN > + if (__TMC_END__ - __TMC_LIST__ == 0) > + return; > +#else > + if (__TMC_LIST__[0] == NULL) > + return; > +#endif > + > + fn = _ITM_deregisterTMCloneTable; > + __asm ("" : "+r" (fn)); > + if (fn) > + fn (__TMC_LIST__); > +} > + > +static inline void > +register_tm_clones (void) > +{ > + void (*fn) (void *, size_t); > + size_t size; > + > +#ifdef HAVE_GAS_HIDDEN > + size = (__TMC_END__ - __TMC_LIST__) / 2; > +#else > + for (size = 0; __TMC_LIST__[size * 2] != NULL; size++) > + continue; > +#endif > + if (size == 0) > + return; > + > + fn = _ITM_registerTMCloneTable; > + __asm ("" : "+r" (fn)); > + if (fn) > + fn (__TMC_LIST__, size); > +} > +#endif /* USE_TM_CLONE_REGISTRY */ > + > +#if defined(INIT_SECTION_ASM_OP) || > defined(INIT_ARRAY_SECTION_ASM_OP) + > +#ifdef OBJECT_FORMAT_ELF > + > +/* Declare the __dso_handle variable. It should have a unique value > + in every shared-object; in a main program its value is zero. The > + object should in any case be protected. This means the instance > + in one DSO or the main program is not used in another object. The > + dynamic linker takes care of this. */ > + > +#ifdef TARGET_LIBGCC_SDATA_SECTION > +extern void *__dso_handle __attribute__ ((__section__ > (TARGET_LIBGCC_SDATA_SECTION))); +#endif > +#ifdef HAVE_GAS_HIDDEN > +extern void *__dso_handle __attribute__ ((__visibility__ > ("hidden"))); +#endif > +#ifdef CRTSTUFFS_O > +void *__dso_handle = &__dso_handle; > +#else > +void *__dso_handle = 0; > +#endif > + > +/* The __cxa_finalize function may not be available so we use only a > + weak declaration. */ > +extern void __cxa_finalize (void *) TARGET_ATTRIBUTE_WEAK; > + > +/* Run all the global destructors on exit from the program. */ > + > +/* Some systems place the number of pointers in the first word of the > + table. On SVR4 however, that word is -1. In all cases, the > table is > + null-terminated. On SVR4, we start from the beginning of the > list and > + invoke each per-compilation-unit destructor routine in order > + until we find that null. > + > + Note that this function MUST be static. There will be one of > these > + functions in each root executable and one in each shared library, > but > + although they all have the same code, each one is unique in that > it > + refers to one particular associated `__DTOR_LIST__' which belongs > to the > + same particular root executable or shared library file. > + > + On some systems, this routine is run more than once from > the .fini, > + when exit is called recursively, so we arrange to remember where > in > + the list we left off processing, and we resume at that point, > + should we be re-invoked. */ > + > +static void __attribute__((used)) > +__do_global_dtors_aux (void) > +{ > + static _Bool completed; > + > + if (__builtin_expect (completed, 0)) > + return; > + > +#ifdef CRTSTUFFS_O > + if (__cxa_finalize) > + __cxa_finalize (__dso_handle); > +#endif > + > +#ifdef FINI_ARRAY_SECTION_ASM_OP > + /* If we are using .fini_array then destructors will be run via > that > + mechanism. */ > +#elif defined(HIDDEN_DTOR_LIST_END) > + { > + /* Safer version that makes sure only .dtors function pointers > are > + called even if the static variable is maliciously changed. */ > + extern func_ptr __DTOR_END__[] __attribute__((visibility > ("hidden"))); > + static size_t dtor_idx; > + const size_t max_idx = __DTOR_END__ - __DTOR_LIST__ - 1; > + func_ptr f; > + > + while (dtor_idx < max_idx) > + { > + f = __DTOR_LIST__[++dtor_idx]; > + f (); > + } > + } > +#else /* !defined (FINI_ARRAY_SECTION_ASM_OP) */ > + { > + static func_ptr *p = __DTOR_LIST__ + 1; > + func_ptr f; > + > + while ((f = *p)) > + { > + p++; > + f (); > + } > + } > +#endif /* !defined(FINI_ARRAY_SECTION_ASM_OP) */ > + > +#if USE_TM_CLONE_REGISTRY > + deregister_tm_clones (); > +#endif /* USE_TM_CLONE_REGISTRY */ > + > +#ifdef USE_EH_FRAME_REGISTRY > +#ifdef CRT_GET_RFIB_DATA > + /* If we used the new __register_frame_info_bases interface, > + make sure that we deregister from the same place. */ > + if (__deregister_frame_info_bases) > + __deregister_frame_info_bases (__EH_FRAME_BEGIN__); > +#else > + if (__deregister_frame_info) > + __deregister_frame_info (__EH_FRAME_BEGIN__); > +#endif > +#endif > + > + completed = 1; > +} > + > +/* Stick a call to __do_global_dtors_aux into the .fini section. */ > +#ifdef FINI_SECTION_ASM_OP > +CRT_CALL_STATIC_FUNCTION (FINI_SECTION_ASM_OP, __do_global_dtors_aux) > +#elif defined (FINI_ARRAY_SECTION_ASM_OP) > +static func_ptr __do_global_dtors_aux_fini_array_entry[] > + __attribute__ ((__used__, section(".fini_array"), > aligned(sizeof(func_ptr)))) > + = { __do_global_dtors_aux }; > +#else /* !FINI_SECTION_ASM_OP && !FINI_ARRAY_SECTION_ASM_OP */ > +static void __attribute__((used)) > +__do_global_dtors_aux_1 (void) > +{ > + atexit (__do_global_dtors_aux); > +} > +CRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, > __do_global_dtors_aux_1) +#endif > + > +#if defined(USE_EH_FRAME_REGISTRY) \ > + || defined(JCR_SECTION_NAME) \ > + || defined(USE_TM_CLONE_REGISTRY) > +/* Stick a call to __register_frame_info into the .init section. > For some > + reason calls with no arguments work more reliably in .init, so > stick the > + call in another function. */ > + > +static void __attribute__((used)) > +frame_dummy (void) > +{ > +#ifdef USE_EH_FRAME_REGISTRY > + static struct object object; > +#ifdef CRT_GET_RFIB_DATA > + void *tbase, *dbase; > + tbase = 0; > + CRT_GET_RFIB_DATA (dbase); > + if (__register_frame_info_bases) > + __register_frame_info_bases (__EH_FRAME_BEGIN__, &object, tbase, > dbase); +#else > + if (__register_frame_info) > + __register_frame_info (__EH_FRAME_BEGIN__, &object); > +#endif /* CRT_GET_RFIB_DATA */ > +#endif /* USE_EH_FRAME_REGISTRY */ > + > +#ifdef JCR_SECTION_NAME > + void **jcr_list; > + __asm ("" : "=g" (jcr_list) : "0" (__JCR_LIST__)); > + if (__builtin_expect (*jcr_list != NULL, 0)) > + { > + void (*register_classes) (void *) = _Jv_RegisterClasses; > + __asm ("" : "+r" (register_classes)); > + if (register_classes) > + register_classes (jcr_list); > + } > +#endif /* JCR_SECTION_NAME */ > + > +#if USE_TM_CLONE_REGISTRY > + register_tm_clones (); > +#endif /* USE_TM_CLONE_REGISTRY */ > +} > + > +#ifdef INIT_SECTION_ASM_OP > +CRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, frame_dummy) > +#else /* defined(INIT_SECTION_ASM_OP) */ > +static func_ptr __frame_dummy_init_array_entry[] > + __attribute__ ((__used__, section(".init_array"), > aligned(sizeof(func_ptr)))) > + = { frame_dummy }; > +#endif /* !defined(INIT_SECTION_ASM_OP) */ > +#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME || > USE_TM_CLONE_REGISTRY */ + > +#else /* OBJECT_FORMAT_ELF */ > + > +/* The function __do_global_ctors_aux is compiled twice (once in > crtbegin.o > + and once in crtend.o). It must be declared static to avoid a link > + error. Here, we define __do_global_ctors as an externally > callable > + function. It is externally callable so that __main can invoke it > when > + INVOKE__main is defined. This has the additional effect of > forcing cc1 > + to switch to the .text section. */ > + > +static void __do_global_ctors_aux (void); > +void > +__do_global_ctors (void) > +{ > +#ifdef INVOKE__main > + /* If __main won't actually call __do_global_ctors then it doesn't > matter > + what's inside the function. The inside of > __do_global_ctors_aux is > + called automatically in that case. And the Alliant fx2800 > linker > + crashes on this reference. So prevent the crash. */ > + __do_global_ctors_aux (); > +#endif > +} > + > +asm (INIT_SECTION_ASM_OP); /* cc1 doesn't know that we are > switching! */ + > +/* A routine to invoke all of the global constructors upon entry to > the > + program. We put this into the .init section (for systems that > have > + such a thing) so that we can properly perform the construction of > + file-scope static-storage C++ objects within shared libraries. */ > + > +static void __attribute__((used)) > +__do_global_ctors_aux (void) /* prologue goes in .init > section */ +{ > + FORCE_CODE_SECTION_ALIGN /* explicit align before switch > to .text */ > + asm (TEXT_SECTION_ASM_OP); /* don't put epilogue and body > in .init */ > + DO_GLOBAL_CTORS_BODY; > + atexit (__do_global_dtors); > +} > + > +#endif /* OBJECT_FORMAT_ELF */ > + > +#elif defined(HAS_INIT_SECTION) /* ! INIT_SECTION_ASM_OP */ > + > +extern void __do_global_dtors (void); > + > +/* This case is used by the Irix 6 port, which supports named > sections but > + not an SVR4-style .fini section. __do_global_dtors can be > non-static > + in this case because we protect it with -hidden_symbol. */ > + > +void > +__do_global_dtors (void) > +{ > + func_ptr *p, f; > + for (p = __DTOR_LIST__ + 1; (f = *p); p++) > + f (); > + > +#if USE_TM_CLONE_REGISTRY > + deregister_tm_clones (); > +#endif /* USE_TM_CLONE_REGISTRY */ > + > +#ifdef USE_EH_FRAME_REGISTRY > + if (__deregister_frame_info) > + __deregister_frame_info (__EH_FRAME_BEGIN__); > +#endif > +} > + > +#if defined(USE_EH_FRAME_REGISTRY) \ > + || defined(JCR_SECTION_NAME) \ > + || defined(USE_TM_CLONE_REGISTRY) > +/* A helper function for __do_global_ctors, which is in crtend.o. > Here > + in crtbegin.o, we can reference a couple of symbols not visible > there. > + Plus, since we're before libgcc.a, we have no problems referencing > + functions from there. */ > +void > +__do_global_ctors_1(void) > +{ > +#ifdef USE_EH_FRAME_REGISTRY > + static struct object object; > + if (__register_frame_info) > + __register_frame_info (__EH_FRAME_BEGIN__, &object); > +#endif > + > +#ifdef JCR_SECTION_NAME > + void **jcr_list > + __asm ("" : "=g" (jcr_list) : "0" (__JCR_LIST__)); > + if (__builtin_expect (*jcr_list != NULL, 0)) > + { > + void (*register_classes) (void *) = _Jv_RegisterClasses; > + __asm ("" : "+r" (register_classes)); > + if (register_classes) > + register_classes (jcr_list); > + } > +#endif > + > +#if USE_TM_CLONE_REGISTRY > + register_tm_clones (); > +#endif /* USE_TM_CLONE_REGISTRY */ > +} > +#endif /* USE_EH_FRAME_REGISTRY || JCR_SECTION_NAME || > USE_TM_CLONE_REGISTRY */ + > +#else /* ! INIT_SECTION_ASM_OP && ! HAS_INIT_SECTION */ > +#error "What are you doing with crtstuff.c, then?" > +#endif > + > +#elif defined(CRT_END) /* ! CRT_BEGIN */ > + > +/* No need for .ctors/.dtors section if linker can place them in > + .init_array/.fini_array section. */ > +#ifndef USE_INITFINI_ARRAY > +/* Put a word containing zero at the end of each of our two lists of > function > + addresses. Note that the words defined here go into the .ctors > and .dtors > + sections of the crtend.o file, and since that file is always > linked in > + last, these words naturally end up at the very ends of the two > lists > + contained in these two sections. */ > + > +#ifdef CTOR_LIST_END > +CTOR_LIST_END; > +#elif defined(CTORS_SECTION_ASM_OP) > +/* Hack: force cc1 to switch to .data section early, so that > assembling > + __CTOR_LIST__ does not undo our behind-the-back change > to .ctors. */ +static func_ptr force_to_data[1] __attribute__ > ((__used__)) = { }; +asm (CTORS_SECTION_ASM_OP); > +STATIC func_ptr __CTOR_END__[1] > + __attribute__((aligned(sizeof(func_ptr)))) > + = { (func_ptr) 0 }; > +#else > +STATIC func_ptr __CTOR_END__[1] > + __attribute__((section(".ctors"), aligned(sizeof(func_ptr)))) > + = { (func_ptr) 0 }; > +#endif > + > +#ifdef DTOR_LIST_END > +DTOR_LIST_END; > +#elif defined(HIDDEN_DTOR_LIST_END) > +#ifdef DTORS_SECTION_ASM_OP > +asm (DTORS_SECTION_ASM_OP); > +#endif > +func_ptr __DTOR_END__[1] > + __attribute__ ((used, > +#ifndef DTORS_SECTION_ASM_OP > + section(".dtors"), > +#endif > + aligned(sizeof(func_ptr)), visibility ("hidden"))) > + = { (func_ptr) 0 }; > +#elif defined(DTORS_SECTION_ASM_OP) > +asm (DTORS_SECTION_ASM_OP); > +STATIC func_ptr __DTOR_END__[1] > + __attribute__ ((used, aligned(sizeof(func_ptr)))) > + = { (func_ptr) 0 }; > +#else > +STATIC func_ptr __DTOR_END__[1] > + __attribute__((used, section(".dtors"), aligned(sizeof(func_ptr)))) > + = { (func_ptr) 0 }; > +#endif > +#endif /* USE_INITFINI_ARRAY */ > + > +#ifdef EH_FRAME_SECTION_NAME > +/* Terminate the frame unwind info section with a 4byte 0 as a > sentinel; > + this would be the 'length' field in a real FDE. */ > +# if __INT_MAX__ == 2147483647 > +typedef int int32; > +# elif __LONG_MAX__ == 2147483647 > +typedef long int32; > +# elif __SHRT_MAX__ == 2147483647 > +typedef short int32; > +# else > +# error "Missing a 4 byte integer" > +# endif > +STATIC EH_FRAME_SECTION_CONST int32 __FRAME_END__[] > + __attribute__ ((used, section(EH_FRAME_SECTION_NAME), > + aligned(sizeof(int32)))) > + = { 0 }; > +#endif /* EH_FRAME_SECTION_NAME */ > + > +#ifdef JCR_SECTION_NAME > +/* Null terminate the .jcr section array. */ > +STATIC void *__JCR_END__[1] > + __attribute__ ((used, section(JCR_SECTION_NAME), > + aligned(sizeof(void *)))) > + = { 0 }; > +#endif /* JCR_SECTION_NAME */ > + > +#if USE_TM_CLONE_REGISTRY > +# ifndef HAVE_GAS_HIDDEN > +static > +# endif > +func_ptr __TMC_END__[] > + __attribute__((used, section(".tm_clone_table"), > aligned(sizeof(void *)))) +# ifdef HAVE_GAS_HIDDEN > + __attribute__((__visibility__ ("hidden"))) = { }; > +# else > + = { 0, 0 }; > +# endif > +#endif /* USE_TM_CLONE_REGISTRY */ > + > +#ifdef INIT_ARRAY_SECTION_ASM_OP > + > +/* If we are using .init_array, there is nothing to do. */ > + > +#elif defined(INIT_SECTION_ASM_OP) > + > +#ifdef OBJECT_FORMAT_ELF > +static void __attribute__((used)) > +__do_global_ctors_aux (void) > +{ > + func_ptr *p; > + for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) > + (*p) (); > +} > + > +/* Stick a call to __do_global_ctors_aux into the .init section. */ > +CRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, __do_global_ctors_aux) > +#else /* OBJECT_FORMAT_ELF */ > + > +/* Stick the real initialization code, followed by a normal sort of > + function epilogue at the very end of the .init section for this > + entire root executable file or for this entire shared library > file. + > + Note that we use some tricks here to get *just* the body and just > + a function epilogue (but no function prologue) into the .init > + section of the crtend.o file. Specifically, we switch to > the .text > + section, start to define a function, and then we switch to > the .init > + section just before the body code. > + > + Earlier on, we put the corresponding function prologue into > the .init > + section of the crtbegin.o file (which will be linked in first). > + > + Note that we want to invoke all constructors for C++ file-scope > static- > + storage objects AFTER any other possible initialization actions > which > + may be performed by the code in the .init section contributions > made by > + other libraries, etc. That's because those other initializations > may > + include setup operations for very primitive things (e.g. > initializing > + the state of the floating-point coprocessor, etc.) which should > be done > + before we start to execute any of the user's code. */ > + > +static void > +__do_global_ctors_aux (void) /* prologue goes in .text > section */ +{ > + asm (INIT_SECTION_ASM_OP); > + DO_GLOBAL_CTORS_BODY; > + atexit (__do_global_dtors); > +} /* epilogue and body go in .init > section */ + > +FORCE_CODE_SECTION_ALIGN > +asm (TEXT_SECTION_ASM_OP); > + > +#endif /* OBJECT_FORMAT_ELF */ > + > +#elif defined(HAS_INIT_SECTION) /* ! INIT_SECTION_ASM_OP */ > + > +extern void __do_global_ctors (void); > + > +/* This case is used by the Irix 6 port, which supports named > sections but > + not an SVR4-style .init section. __do_global_ctors can be > non-static > + in this case because we protect it with -hidden_symbol. */ > +void > +__do_global_ctors (void) > +{ > + func_ptr *p; > +#if defined(USE_EH_FRAME_REGISTRY) \ > + || defined(JCR_SECTION_NAME) \ > + || defined(USE_TM_CLONE_REGISTRY) > + __do_global_ctors_1(); > +#endif > + for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) > + (*p) (); > +} > + > +#else /* ! INIT_SECTION_ASM_OP && ! HAS_INIT_SECTION */ > +#error "What are you doing with crtstuff.c, then?" > +#endif > + > +#else /* ! CRT_BEGIN && ! CRT_END */ > +#error "One of CRT_BEGIN or CRT_END must be defined." > +#endif -- You received this message because you are subscribed to the Google Groups "Akaros" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. For more options, visit https://groups.google.com/d/optout.
