2 Copyright (c) 2014-2015 Intel Corporation. All Rights Reserved.
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 * Neither the name of Intel Corporation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include "offload_table.h"
33 #include "offload_myo_host.h"
35 #include "compiler_if_target.h"
36 #include "offload_target.h"
37 #include "offload_myo_target.h"
40 // Initializes library and registers specified offload image.
41 // Don't use this declarations from offload_host.h as offload_table.h
42 // is used instead of it. Using offload_host.h contradicts with
43 // STL library compiled with VS2010.
44 extern "C" bool __offload_register_image(const void* image
);
45 extern "C" void __offload_unregister_image(const void* image
);
46 extern "C" bool __offload_target_image_is_executable(const void *image
);
49 #define ALLOCATE(name) __declspec(allocate(name))
52 #define ALLOCATE(name) __attribute__((section(name)))
53 #define DLL_LOCAL __attribute__((visibility("hidden")))
54 #endif // TARGET_WINNT
57 // the host program/shared library should always have __offload_target_image
58 // symbol defined. This symbol specifies the beginning of the target program
60 extern "C" DLL_LOCAL
const void* __offload_target_image
;
62 // Define a weak main which would be used on target side in case usere's
63 // source file containing main does not have offload code.
67 OFFLOAD_TARGET_MAIN();
72 extern "C" int MAIN__(void)
74 OFFLOAD_TARGET_MAIN();
77 #endif // HOST_LIBRARY
79 // offload section prolog
80 ALLOCATE(OFFLOAD_ENTRY_TABLE_SECTION_START
)
82 __declspec(align(sizeof(FuncTable::Entry
)))
83 #endif // TARGET_WINNT
84 static FuncTable::Entry __offload_entry_table_start
= { 0 };
86 // list element for the current module
87 static FuncList::Node __offload_entry_node
= {
88 { &__offload_entry_table_start
+ 1, -1 },
92 // offload fp section prolog
93 ALLOCATE(OFFLOAD_FUNC_TABLE_SECTION_START
)
95 __declspec(align(sizeof(FuncTable::Entry
)))
96 #endif // TARGET_WINNT
97 static FuncTable::Entry __offload_func_table_start
= { 0 };
99 // list element for the current module
100 static FuncList::Node __offload_func_node
= {
101 { &__offload_func_table_start
+ 1, -1 },
105 // offload fp section prolog
106 ALLOCATE(OFFLOAD_VAR_TABLE_SECTION_START
)
108 __declspec(align(sizeof(VarTable::Entry
)))
109 #endif // TARGET_WINNT
110 static VarTable::Entry __offload_var_table_start
= { 0 };
112 // list element for the current module
113 static VarList::Node __offload_var_node
= {
114 { &__offload_var_table_start
+ 1 },
120 // offload myo shared var section prolog
121 // first element is empty
122 ALLOCATE(OFFLOAD_MYO_SHARED_TABLE_SECTION_START
)
124 __declspec(align(sizeof(SharedTableEntry
)))
125 #endif // TARGET_WINNT
126 static MYOVarTable::Entry __offload_myo_shared_var_start
= { 0 };
128 // list element for the current module
129 // table entry pointer skips the empty first entry
130 static MYOVarTableList::Node __offload_myo_shared_var_node
= {
131 { &__offload_myo_shared_var_start
+ 1 },
135 // offload myo shared vtable section prolog
136 // first element is empty
137 ALLOCATE(OFFLOAD_MYO_SHARED_VTABLE_SECTION_START
)
139 __declspec(align(sizeof(SharedTableEntry
)))
140 #endif // TARGET_WINNT
141 static MYOVarTable::Entry __offload_myo_shared_vtable_start
= { 0 };
143 // list element for the current module
144 // table entry pointer skips the empty first entry
145 static MYOVarTableList::Node __offload_myo_shared_vtable_node
= {
146 { &__offload_myo_shared_vtable_start
+ 1 },
150 // offload myo shared var init section prolog
151 // first element is empty
152 ALLOCATE(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START
)
154 __declspec(align(sizeof(InitTableEntry
)))
155 #endif // TARGET_WINNT
156 static MYOInitTable::Entry __offload_myo_init_table_start
= { 0 };
158 // list element for the current module
159 // table entry pointer skips the empty first entry
160 static MYOInitTableList::Node __offload_myo_init_table_node
= {
161 { &__offload_myo_init_table_start
+ 1 },
165 // The functions and variables needed for a built-in
166 // remote function entry for vtable initialization on MIC
169 MyoError
__offload_init_vtables(void)
171 SharedTableEntry
*t_start
;
173 //OFFLOAD_DEBUG_TRACE(3, "%s\n", __func__);
174 t_start
= &__offload_myo_shared_vtable_start
+ 1;
175 //OFFLOAD_DEBUG_TRACE(3, "%s(%p)\n", __func__, t_start);
176 while (t_start
->varName
!= 0) {
177 //OFFLOAD_DEBUG_TRACE(4,
178 // "myo shared vtable \"%s\" &myo_ptr = %p myo_ptr = %p\n",
180 // (void *)(t_start->sharedAddr),
181 // ((void **)(t_start->sharedAddr))[0]);
185 __offload_myo_shared_init_table_process(
186 &__offload_myo_init_table_start
+ 1);
189 #endif // !HOST_LIBRARY
191 static void vtable_initializer()
196 static MyoError
vtable_initializer_wrapper()
198 __offload_myoAcquire();
199 __offload_init_vtables();
200 __offload_myoRelease();
205 static void* __offload_vtable_initializer_thunk_ptr
= 0;
207 // offload myo fptr section prolog
208 // first element is pre-initialized to the MIC vtable initializer
209 ALLOCATE(OFFLOAD_MYO_FPTR_TABLE_SECTION_START
)
211 __declspec(align(sizeof(FptrTableEntry
)))
212 #endif // TARGET_WINNT
213 static MYOFuncTable::Entry __offload_myo_fptr_table_start
= {
215 "--vtable_initializer--",
216 (void*)&vtable_initializer
,
217 (void*)&__offload_vtable_initializer_thunk_ptr
,
219 // Dummy to pad up to 32 bytes
221 #endif // TARGET_WINNT
222 #else // HOST_LIBRARY
223 "--vtable_initializer--",
224 (void*)&vtable_initializer
,
225 (void*)&vtable_initializer_wrapper
,
226 &__offload_vtable_initializer_thunk_ptr
,
227 #endif // HOST_LIBRARY
230 // list element for the current module
231 static MYOFuncTableList::Node __offload_myo_fptr_table_node
= {
232 { &__offload_myo_fptr_table_start
},
236 #endif // MYO_SUPPORT
238 // init/fini code which adds/removes local lookup data to/from the global list
240 static void offload_fini();
241 static void offload_fini_so();
244 static void offload_init() __attribute__((constructor(101)));
245 #else // TARGET_WINNT
246 static void offload_init();
248 // Place offload initialization before user constructors
249 ALLOCATE(OFFLOAD_CRTINIT_SECTION_START
)
250 static void (*addressof_offload_init
)() = offload_init
;
251 #endif // TARGET_WINNT
253 static void offload_init()
257 // register offload tables
258 __offload_register_tables(&__offload_entry_node
,
259 &__offload_func_node
,
260 &__offload_var_node
);
263 success
= __offload_register_image(&__offload_target_image
);
268 #endif // HOST_LIBRARY
271 // If this was the main program register main atexit routine
272 if (__offload_myoProcessTables(
273 &__offload_target_image
,
274 &__offload_myo_init_table_node
,
275 &__offload_myo_shared_var_node
,
276 &__offload_myo_shared_vtable_node
,
277 &__offload_myo_fptr_table_node
))
279 atexit(offload_fini
);
282 atexit(offload_fini_so
);
285 #else // HOST_LIBRARY
286 __offload_myoProcessTables(
287 &__offload_myo_init_table_start
+ 1,
288 &__offload_myo_shared_var_start
+ 1,
289 &__offload_myo_shared_vtable_start
+ 1,
290 &__offload_myo_fptr_table_start
292 #endif // HOST_LIBRARY
293 #endif // MYO_SUPPORT
297 static void offload_fini_so() __attribute__((destructor(101)));
298 #else // TARGET_WINNT
299 static void offload_init_so();
300 #endif // TARGET_WINNT
302 static void offload_fini()
305 __offload_unregister_image(&__offload_target_image
);
306 #endif // HOST_LIBRARY
309 static void offload_fini_so()
311 // Offload and MYO tables need to be removed from list
312 // to prevent invalid accesses after dlclose
313 // Remove offload tables
314 __offload_unregister_tables(&__offload_entry_node
,
315 &__offload_func_node
,
316 &__offload_var_node
);
318 if(!__offload_target_image_is_executable(&__offload_target_image
)) {
319 __offload_unregister_image(&__offload_target_image
);
325 __offload_myoRemoveTables(
326 &__offload_myo_init_table_node
,
327 &__offload_myo_shared_var_node
,
328 &__offload_myo_shared_vtable_node
,
329 &__offload_myo_fptr_table_node
);
330 #endif // HOST_LIBRARY
331 #endif // MYO_SUPPORT