1/* This file is part of GCC. 2 3GCC is free software; you can redistribute it and/or modify it under 4the terms of the GNU General Public License as published by the Free 5Software Foundation; either version 3, or (at your option) any later 6version. 7 8GCC is distributed in the hope that it will be useful, but WITHOUT ANY 9WARRANTY; without even the implied warranty of MERCHANTABILITY or 10FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11for more details. 12 13Under Section 7 of GPL version 3, you are granted additional 14permissions described in the GCC Runtime Library Exception, version 153.1, as published by the Free Software Foundation. 16 17You should have received a copy of the GNU General Public License and 18a copy of the GCC Runtime Library Exception along with this program; 19see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 20<http://www.gnu.org/licenses/>. */ 21 22/* The essential point of the crtbegin/crtend files on VxWorks is to handle 23 the eh frames registration thanks to dedicated constructors and 24 destructors. What needs to be done depends on the VxWorks version and the 25 kind of module (rtp, dkm, ...) one is building. */ 26 27#define IN_LIBGCC2 28 29/* FIXME: Including auto-host is incorrect, but until we have 30 identified the set of defines that need to go into auto-target.h, 31 this will have to do. */ 32#include "auto-host.h" 33#undef caddr_t 34#undef pid_t 35#undef rlim_t 36#undef ssize_t 37#undef vfork 38#include "tconfig.h" 39#include "tsystem.h" 40#include "coretypes.h" 41#include "tm.h" 42#include "libgcc_tm.h" 43#include "unwind-dw2-fde.h" 44 45/* If we are entitled/requested to use init/fini arrays, we'll rely on that. 46 Otherwise, we may rely on ctors/dtors sections for RTPs or expect munch to 47 be involved for kernel modules. */ 48 49#if !defined(USE_INITFINI_ARRAY) && defined(__RTP__) 50#define USE_CDTORS_SECTIONS 51#endif 52 53#if DWARF2_UNWIND_INFO && !defined(__USING_SJLJ_EXCEPTIONS__) 54#define USE_EH_FRAME_REGISTRY 55#endif 56 57/* ------------------------------ crtbegin ------------------------------- */ 58 59#ifdef CRT_BEGIN 60 61#if DEFAULT_USE_CXA_ATEXIT && defined(__RTP__) 62/* This mimics the crtstuff.c behavior. dso_handle should be NULL for the 63 main program (in vx_crtbegin.o) and a unique value for the shared libraries 64 (in vx_crtbeginS.o). */ 65extern void *__dso_handle __attribute__ ((__visibility__ ("hidden"))); 66#ifdef CRTSTUFFS_O 67void *__dso_handle = &__dso_handle; 68#else 69void *__dso_handle = 0; 70#endif 71#endif /* DEFAULT_USE_CXA_ATEXIT */ 72 73/* Determine what names to use for the constructor/destructor functions. */ 74 75#if defined(USE_CDTORS_SECTIONS) || defined(USE_INITFINI_ARRAY) 76 77#define EH_CTOR_NAME _crtbe_register_frame 78#define EH_DTOR_NAME _ctrbe_deregister_frame 79#define EH_LINKAGE static 80 81#else 82 83/* No specific sections for constructors or destructors: we thus use a 84 symbol naming convention so that the constructors are then recognized 85 by munch or whatever tool is used for the final link phase. Since the 86 pointers to the constructor/destructor functions are not created in this 87 translation unit, they must have external linkage. */ 88#define EH_CTOR_NAME _GLOBAL__I_00101_0__crtbe_register_frame 89#define EH_DTOR_NAME _GLOBAL__D_00101_1__crtbe_deregister_frame 90#define EH_LINKAGE 91 92#endif 93 94#ifdef USE_INITFINI_ARRAY 95/* .init_array and .fini_array is supported starting VxWorks 7.2 in all 96 cases. The compiler is then configured to always support priorities in 97 constructors, so we can rely on the constructor and destructor attributes 98 to generate the proper sections. */ 99#define EH_CTOR_ATTRIBUTE __attribute__((constructor (101))) 100#define EH_DTOR_ATTRIBUTE __attribute__((destructor (101))) 101 102/* Provide the init/fini array support functions for shared libraries, 103 where we don't want to drag libc_internal contents blindly and which 104 provides functions with a slightly different name anyway. */ 105 106#if HAVE_INITFINI_ARRAY_SUPPORT && defined(CRTSTUFFS_O) 107 108/* Run through the .init_array, .fini_array sections. The linker script 109 *must* provide __init_array_start, __init_array_end, __fini_array_start, 110 __fini_array_end symbols. */ 111 112typedef void (*initfini_ptr) (void); 113extern initfini_ptr __init_array_start[]; 114extern initfini_ptr __init_array_end[]; 115extern initfini_ptr __fini_array_start[]; 116extern initfini_ptr __fini_array_end[]; 117 118/* Provide the actual code through static functions, which don't need 119 to be exposed in the shared lib interface. */ 120 121static void __exec_init_array(void) 122{ 123 initfini_ptr *fn; 124 for (fn = __init_array_start; fn < __init_array_end; ++fn) 125 (*fn)(); 126} 127 128static void __exec_fini_array(void) 129{ 130 initfini_ptr *fn; 131 for (fn = __fini_array_end - 1; fn >= __fini_array_start; --fn) 132 (*fn)(); 133} 134 135/* Reference the two above functions as the init / fini function. */ 136 137void __attribute__ ((__section__ (".init"))) _init() 138{ 139 __exec_init_array(); 140} 141 142void __attribute__ ((__section__ (".fini"))) _fini() 143{ 144 __exec_fini_array(); 145} 146 147#endif /* __CRTSTUFFS_O__ */ 148 149#else /* !USE_INITFINI_ARRAY */ 150 151/* Note: Even in case of .ctors/.dtors sections, we can't use the attribute 152 (constructor (15)) here as gcc may have been configured with constructors 153 priority disabled. We will instead craft an explicit section name for this 154 purpose. */ 155#define EH_CTOR_ATTRIBUTE 156#define EH_DTOR_ATTRIBUTE 157 158#endif /* USE_INITFINI_ARRAY */ 159 160#ifdef USE_EH_FRAME_REGISTRY 161/* Stick a label at the beginning of the frame unwind info so we can register 162 and deregister it with the exception handling library code. */ 163static const char __EH_FRAME_BEGIN__[] 164__attribute__((section(__LIBGCC_EH_FRAME_SECTION_NAME__), aligned(4))) 165 = { }; 166 167EH_LINKAGE EH_CTOR_ATTRIBUTE void EH_CTOR_NAME (void) 168{ 169 static struct object object; 170 __register_frame_info (__EH_FRAME_BEGIN__, &object); 171} 172 173EH_LINKAGE EH_DTOR_ATTRIBUTE void EH_DTOR_NAME (void) 174{ 175 __deregister_frame_info (__EH_FRAME_BEGIN__); 176} 177#endif /* USE_EH_FRAME_REGISTRY */ 178 179#ifdef USE_CDTORS_SECTIONS 180/* As explained above, we need to manually build the sections here as the 181 compiler may not have support for constructors priority enabled. */ 182static void (* volatile eh_registration_ctors[])() 183 __attribute__((section (".ctors.101"))) 184= { &EH_CTOR_NAME }; 185static void (* volatile eh_registration_dtors[])() 186 __attribute__((section (".dtors.65434"))) 187= { &EH_DTOR_NAME }; 188#endif 189 190/* ------------------------------ crtend --------------------------------- */ 191 192#elif defined (CRT_END) /* ! CRT_BEGIN */ 193 194#ifdef USE_EH_FRAME_REGISTRY 195/* Terminate the frame unwind info section with a 4byte 0 as a sentinel; 196 this would be the 'length' field in a real FDE. */ 197 198static const char __FRAME_END__[] 199 __attribute__ ((used, section(__LIBGCC_EH_FRAME_SECTION_NAME__), 200 aligned(4))) 201 = { 0, 0, 0, 0 }; 202#endif /* USE_EH_FRAME_REGISTRY */ 203 204#else /* ! CRT_BEGIN & ! CRT_END */ 205 206#error "One of CRT_BEGIN or CRT_END must be defined." 207 208#endif 209