xref: /netbsd-src/external/gpl3/gcc/dist/libgcc/config/vxcrtstuff.c (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1 /* This file is part of GCC.
2 
3 GCC is free software; you can redistribute it and/or modify it under
4 the terms of the GNU General Public License as published by the Free
5 Software Foundation; either version 3, or (at your option) any later
6 version.
7 
8 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
9 WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11 for more details.
12 
13 Under Section 7 of GPL version 3, you are granted additional
14 permissions described in the GCC Runtime Library Exception, version
15 3.1, as published by the Free Software Foundation.
16 
17 You should have received a copy of the GNU General Public License and
18 a copy of the GCC Runtime Library Exception along with this program;
19 see 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).   */
65 extern void *__dso_handle __attribute__ ((__visibility__ ("hidden")));
66 #ifdef CRTSTUFFS_O
67 void *__dso_handle = &__dso_handle;
68 #else
69 void *__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 
112 typedef void (*initfini_ptr) (void);
113 extern initfini_ptr __init_array_start[];
114 extern initfini_ptr __init_array_end[];
115 extern initfini_ptr __fini_array_start[];
116 extern 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 
__exec_init_array(void)121 static 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 
__exec_fini_array(void)128 static 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 
_init()137 void __attribute__ ((__section__  (".init"))) _init()
138 {
139   __exec_init_array();
140 }
141 
_fini()142 void __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.  */
163 static const char __EH_FRAME_BEGIN__[]
164 __attribute__((section(__LIBGCC_EH_FRAME_SECTION_NAME__), aligned(4)))
165   = { };
166 
EH_CTOR_NAME(void)167 EH_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 
EH_DTOR_NAME(void)173 EH_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.  */
182 static void (* volatile eh_registration_ctors[])()
183   __attribute__((section (".ctors.101")))
184 = { &EH_CTOR_NAME };
185 static 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 
198 static 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