111
|
1 /*
|
|
2 Copyright (c) 2014-2016 Intel Corporation. All Rights Reserved.
|
|
3
|
|
4 Redistribution and use in source and binary forms, with or without
|
|
5 modification, are permitted provided that the following conditions
|
|
6 are met:
|
|
7
|
|
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.
|
|
16
|
|
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.
|
|
28 */
|
|
29
|
|
30
|
|
31 #if HOST_LIBRARY
|
|
32 #include "offload_table.h"
|
|
33 #ifdef MYO_SUPPORT
|
|
34 #include "offload_myo_host.h"
|
|
35 #endif // MYO_SUPPORT
|
|
36 #else
|
|
37 #include "compiler_if_target.h"
|
|
38 #include "offload_target.h"
|
|
39 #ifdef MYO_SUPPORT
|
|
40 #include "offload_myo_target.h"
|
|
41 #endif // MYO_SUPPORT
|
|
42 #endif // HOST_LIBRARY
|
|
43
|
|
44 // Initializes library and registers specified offload image.
|
|
45 // Don't use this declarations from offload_host.h as offload_table.h
|
|
46 // is used instead of it. Using offload_host.h contradicts with
|
|
47 // STL library compiled with VS2010.
|
|
48 extern "C" bool __offload_register_image(const void* image);
|
|
49 extern "C" void __offload_unregister_image(const void* image);
|
|
50 extern "C" bool __offload_target_image_is_executable(const void *image);
|
|
51
|
|
52 #ifdef TARGET_WINNT
|
|
53 #define ALLOCATE(name) __declspec(allocate(name))
|
|
54 #define DLL_LOCAL
|
|
55 #else // TARGET_WINNT
|
|
56 #define ALLOCATE(name) __attribute__((section(name)))
|
|
57 #define DLL_LOCAL __attribute__((visibility("hidden")))
|
|
58 #endif // TARGET_WINNT
|
|
59
|
|
60 #if HOST_LIBRARY
|
|
61 // the host program/shared library should always have __offload_target_image
|
|
62 // symbol defined. This symbol specifies the beginning of the target program
|
|
63 // image.
|
|
64 extern "C" DLL_LOCAL const void* __offload_target_image;
|
|
65 #else // HOST_LIBRARY
|
|
66 // Define a weak main which would be used on target side in case usere's
|
|
67 // source file containing main does not have offload code.
|
|
68 #pragma weak main
|
|
69 int main(void)
|
|
70 {
|
|
71 OFFLOAD_TARGET_MAIN();
|
|
72 return 0;
|
|
73 }
|
|
74
|
|
75 #pragma weak MAIN__
|
|
76 extern "C" int MAIN__(void)
|
|
77 {
|
|
78 OFFLOAD_TARGET_MAIN();
|
|
79 return 0;
|
|
80 }
|
|
81 #endif // HOST_LIBRARY
|
|
82
|
|
83 // offload section prolog
|
|
84 ALLOCATE(OFFLOAD_ENTRY_TABLE_SECTION_START)
|
|
85 #ifdef TARGET_WINNT
|
|
86 __declspec(align(sizeof(FuncTable::Entry)))
|
|
87 #endif // TARGET_WINNT
|
|
88 static FuncTable::Entry __offload_entry_table_start = { 0 };
|
|
89
|
|
90 // list element for the current module
|
|
91 static FuncList::Node __offload_entry_node = {
|
|
92 { &__offload_entry_table_start + 1, -1 },
|
|
93 0, 0
|
|
94 };
|
|
95
|
|
96 // offload fp section prolog
|
|
97 ALLOCATE(OFFLOAD_FUNC_TABLE_SECTION_START)
|
|
98 #ifdef TARGET_WINNT
|
|
99 __declspec(align(sizeof(FuncTable::Entry)))
|
|
100 #endif // TARGET_WINNT
|
|
101 static FuncTable::Entry __offload_func_table_start = { 0 };
|
|
102
|
|
103 // list element for the current module
|
|
104 static FuncList::Node __offload_func_node = {
|
|
105 { &__offload_func_table_start + 1, -1 },
|
|
106 0, 0
|
|
107 };
|
|
108
|
|
109 // offload fp section prolog
|
|
110 ALLOCATE(OFFLOAD_VAR_TABLE_SECTION_START)
|
|
111 #ifdef TARGET_WINNT
|
|
112 __declspec(align(sizeof(VarTable::Entry)))
|
|
113 #endif // TARGET_WINNT
|
|
114 static VarTable::Entry __offload_var_table_start = { 0 };
|
|
115
|
|
116 // list element for the current module
|
|
117 static VarList::Node __offload_var_node = {
|
|
118 { &__offload_var_table_start + 1 },
|
|
119 0, 0
|
|
120 };
|
|
121
|
|
122 #ifdef MYO_SUPPORT
|
|
123
|
|
124 // offload myo shared var section prolog
|
|
125 // first element is empty
|
|
126 ALLOCATE(OFFLOAD_MYO_SHARED_TABLE_SECTION_START)
|
|
127 #ifdef TARGET_WINNT
|
|
128 __declspec(align(sizeof(SharedTableEntry)))
|
|
129 #endif // TARGET_WINNT
|
|
130 static MYOVarTable::Entry __offload_myo_shared_var_start = { 0 };
|
|
131
|
|
132 // list element for the current module
|
|
133 // table entry pointer skips the empty first entry
|
|
134 static MYOVarTableList::Node __offload_myo_shared_var_node = {
|
|
135 { &__offload_myo_shared_var_start + 1 },
|
|
136 0, 0
|
|
137 };
|
|
138
|
|
139 // offload myo shared vtable section prolog
|
|
140 // first element is empty
|
|
141 ALLOCATE(OFFLOAD_MYO_SHARED_VTABLE_SECTION_START)
|
|
142 #ifdef TARGET_WINNT
|
|
143 __declspec(align(sizeof(SharedTableEntry)))
|
|
144 #endif // TARGET_WINNT
|
|
145 static MYOVarTable::Entry __offload_myo_shared_vtable_start = { 0 };
|
|
146
|
|
147 // list element for the current module
|
|
148 // table entry pointer skips the empty first entry
|
|
149 static MYOVarTableList::Node __offload_myo_shared_vtable_node = {
|
|
150 { &__offload_myo_shared_vtable_start + 1 },
|
|
151 0, 0
|
|
152 };
|
|
153
|
|
154 // offload myo shared var init section prolog
|
|
155 // first element is empty
|
|
156 ALLOCATE(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START)
|
|
157 #ifdef TARGET_WINNT
|
|
158 __declspec(align(sizeof(InitTableEntry)))
|
|
159 #endif // TARGET_WINNT
|
|
160 static MYOInitTable::Entry __offload_myo_init_table_start = { 0 };
|
|
161
|
|
162 // list element for the current module
|
|
163 // table entry pointer skips the empty first entry
|
|
164 static MYOInitTableList::Node __offload_myo_init_table_node = {
|
|
165 { &__offload_myo_init_table_start + 1 },
|
|
166 0, 0
|
|
167 };
|
|
168
|
|
169 // The functions and variables needed for a built-in
|
|
170 // remote function entry for vtable initialization on MIC
|
|
171
|
|
172 #if !HOST_LIBRARY
|
|
173 MyoError __offload_init_vtables(void)
|
|
174 {
|
|
175 SharedTableEntry *t_start;
|
|
176
|
|
177 //OFFLOAD_DEBUG_TRACE(3, "%s\n", __func__);
|
|
178 t_start = &__offload_myo_shared_vtable_start + 1;
|
|
179 //OFFLOAD_DEBUG_TRACE(3, "%s(%p)\n", __func__, t_start);
|
|
180 while (t_start->varName != 0) {
|
|
181 //OFFLOAD_DEBUG_TRACE(4,
|
|
182 // "myo shared vtable \"%s\" &myo_ptr = %p myo_ptr = %p\n",
|
|
183 // t_start->varName,
|
|
184 // (void *)(t_start->sharedAddr),
|
|
185 // ((void **)(t_start->sharedAddr))[0]);
|
|
186 t_start++;
|
|
187 }
|
|
188
|
|
189 __offload_myo_shared_init_table_process(
|
|
190 &__offload_myo_init_table_start + 1);
|
|
191 return MYO_SUCCESS;
|
|
192 }
|
|
193 #endif // !HOST_LIBRARY
|
|
194
|
|
195 static void vtable_initializer()
|
|
196 {
|
|
197 }
|
|
198
|
|
199 #if !HOST_LIBRARY
|
|
200 static MyoError vtable_initializer_wrapper()
|
|
201 {
|
|
202 __offload_myoAcquire();
|
|
203 __offload_init_vtables();
|
|
204 __offload_myoRelease();
|
|
205 return MYO_SUCCESS;
|
|
206 }
|
|
207 #endif
|
|
208
|
|
209 static void* __offload_vtable_initializer_thunk_ptr = 0;
|
|
210
|
|
211 // offload myo fptr section prolog
|
|
212 // first element is pre-initialized to the MIC vtable initializer
|
|
213 ALLOCATE(OFFLOAD_MYO_FPTR_TABLE_SECTION_START)
|
|
214 #ifdef TARGET_WINNT
|
|
215 __declspec(align(sizeof(FptrTableEntry)))
|
|
216 #endif // TARGET_WINNT
|
|
217 static MYOFuncTable::Entry __offload_myo_fptr_table_start = {
|
|
218 #if HOST_LIBRARY
|
|
219 "--vtable_initializer--",
|
|
220 (void*)&vtable_initializer,
|
|
221 (void*)&__offload_vtable_initializer_thunk_ptr,
|
|
222 #ifdef TARGET_WINNT
|
|
223 // Dummy to pad up to 32 bytes
|
|
224 0
|
|
225 #endif // TARGET_WINNT
|
|
226 #else // HOST_LIBRARY
|
|
227 "--vtable_initializer--",
|
|
228 (void*)&vtable_initializer,
|
|
229 (void*)&vtable_initializer_wrapper,
|
|
230 &__offload_vtable_initializer_thunk_ptr,
|
|
231 #endif // HOST_LIBRARY
|
|
232 };
|
|
233
|
|
234 // list element for the current module
|
|
235 static MYOFuncTableList::Node __offload_myo_fptr_table_node = {
|
|
236 { &__offload_myo_fptr_table_start },
|
|
237 0, 0
|
|
238 };
|
|
239
|
|
240 #endif // MYO_SUPPORT
|
|
241
|
|
242 // init/fini code which adds/removes local lookup data to/from the global list
|
|
243
|
|
244 static void offload_fini();
|
|
245 static void offload_fini_so();
|
|
246
|
|
247 #ifndef TARGET_WINNT
|
|
248 static void offload_init() __attribute__((constructor(101)));
|
|
249 #else // TARGET_WINNT
|
|
250 static void offload_init();
|
|
251
|
|
252 // Place offload initialization before user constructors
|
|
253 ALLOCATE(OFFLOAD_CRTINIT_SECTION_START)
|
|
254 static void (*addressof_offload_init)() = offload_init;
|
|
255 #endif // TARGET_WINNT
|
|
256
|
|
257 static void offload_init()
|
|
258 {
|
|
259 bool success;
|
|
260
|
|
261 // Set offload version
|
|
262 __offload_set_version(OFFLOAD_VERSION_17);
|
|
263
|
|
264 // register offload tables
|
|
265 __offload_register_tables(&__offload_entry_node,
|
|
266 &__offload_func_node,
|
|
267 &__offload_var_node);
|
|
268
|
|
269 #if HOST_LIBRARY
|
|
270 success = __offload_register_image(&__offload_target_image);
|
|
271 if (!success)
|
|
272 {
|
|
273 return;
|
|
274 }
|
|
275 #endif // HOST_LIBRARY
|
|
276 #ifdef MYO_SUPPORT
|
|
277 #if HOST_LIBRARY
|
|
278 // If this was the main program register main atexit routine
|
|
279 if (__offload_myoProcessTables(
|
|
280 &__offload_target_image,
|
|
281 &__offload_myo_init_table_node,
|
|
282 &__offload_myo_shared_var_node,
|
|
283 &__offload_myo_shared_vtable_node,
|
|
284 &__offload_myo_fptr_table_node))
|
|
285 {
|
|
286 atexit(offload_fini);
|
|
287 #ifdef TARGET_WINNT
|
|
288 } else {
|
|
289 atexit(offload_fini_so);
|
|
290 #endif
|
|
291 }
|
|
292 #else // HOST_LIBRARY
|
|
293 __offload_myoProcessTables(
|
|
294 &__offload_myo_init_table_start + 1,
|
|
295 &__offload_myo_shared_var_start + 1,
|
|
296 &__offload_myo_shared_vtable_start + 1,
|
|
297 &__offload_myo_fptr_table_start
|
|
298 );
|
|
299 #endif // HOST_LIBRARY
|
|
300 #endif // MYO_SUPPORT
|
|
301 }
|
|
302
|
|
303 #ifndef TARGET_WINNT
|
|
304 static void offload_fini_so() __attribute__((destructor(101)));
|
|
305 #endif // TARGET_WINNT
|
|
306
|
|
307 static void offload_fini()
|
|
308 {
|
|
309 #if HOST_LIBRARY
|
|
310 __offload_unregister_image(&__offload_target_image);
|
|
311 #endif // HOST_LIBRARY
|
|
312 }
|
|
313
|
|
314 static void offload_fini_so()
|
|
315 {
|
|
316 // Offload and MYO tables need to be removed from list
|
|
317 // to prevent invalid accesses after dlclose
|
|
318 // Remove offload tables
|
|
319 __offload_unregister_tables(&__offload_entry_node,
|
|
320 &__offload_func_node,
|
|
321 &__offload_var_node);
|
|
322 #if HOST_LIBRARY
|
|
323 if(!__offload_target_image_is_executable(&__offload_target_image)) {
|
|
324 __offload_unregister_image(&__offload_target_image);
|
|
325 }
|
|
326 #endif
|
|
327 #ifdef MYO_SUPPORT
|
|
328 #if HOST_LIBRARY
|
|
329 // Remove MYO tables
|
|
330 __offload_myoRemoveTables(
|
|
331 &__offload_myo_init_table_node,
|
|
332 &__offload_myo_shared_var_node,
|
|
333 &__offload_myo_shared_vtable_node,
|
|
334 &__offload_myo_fptr_table_node);
|
|
335 #endif // HOST_LIBRARY
|
|
336 #endif // MYO_SUPPORT
|
|
337 }
|