ofldbegin.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. /*
  2. Copyright (c) 2014-2016 Intel Corporation. All Rights Reserved.
  3. Redistribution and use in source and binary forms, with or without
  4. modification, are permitted provided that the following conditions
  5. are met:
  6. * Redistributions of source code must retain the above copyright
  7. notice, this list of conditions and the following disclaimer.
  8. * Redistributions in binary form must reproduce the above copyright
  9. notice, this list of conditions and the following disclaimer in the
  10. documentation and/or other materials provided with the distribution.
  11. * Neither the name of Intel Corporation nor the names of its
  12. contributors may be used to endorse or promote products derived
  13. from this software without specific prior written permission.
  14. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  17. A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  18. HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  19. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  20. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  21. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  22. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  24. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #if HOST_LIBRARY
  27. #include "offload_table.h"
  28. #ifdef MYO_SUPPORT
  29. #include "offload_myo_host.h"
  30. #endif // MYO_SUPPORT
  31. #else
  32. #include "compiler_if_target.h"
  33. #include "offload_target.h"
  34. #ifdef MYO_SUPPORT
  35. #include "offload_myo_target.h"
  36. #endif // MYO_SUPPORT
  37. #endif // HOST_LIBRARY
  38. // Initializes library and registers specified offload image.
  39. // Don't use this declarations from offload_host.h as offload_table.h
  40. // is used instead of it. Using offload_host.h contradicts with
  41. // STL library compiled with VS2010.
  42. extern "C" bool __offload_register_image(const void* image);
  43. extern "C" void __offload_unregister_image(const void* image);
  44. extern "C" bool __offload_target_image_is_executable(const void *image);
  45. #ifdef TARGET_WINNT
  46. #define ALLOCATE(name) __declspec(allocate(name))
  47. #define DLL_LOCAL
  48. #else // TARGET_WINNT
  49. #define ALLOCATE(name) __attribute__((section(name)))
  50. #define DLL_LOCAL __attribute__((visibility("hidden")))
  51. #endif // TARGET_WINNT
  52. #if HOST_LIBRARY
  53. // the host program/shared library should always have __offload_target_image
  54. // symbol defined. This symbol specifies the beginning of the target program
  55. // image.
  56. extern "C" DLL_LOCAL const void* __offload_target_image;
  57. #else // HOST_LIBRARY
  58. // Define a weak main which would be used on target side in case usere's
  59. // source file containing main does not have offload code.
  60. #pragma weak main
  61. int main(void)
  62. {
  63. OFFLOAD_TARGET_MAIN();
  64. return 0;
  65. }
  66. #pragma weak MAIN__
  67. extern "C" int MAIN__(void)
  68. {
  69. OFFLOAD_TARGET_MAIN();
  70. return 0;
  71. }
  72. #endif // HOST_LIBRARY
  73. // offload section prolog
  74. ALLOCATE(OFFLOAD_ENTRY_TABLE_SECTION_START)
  75. #ifdef TARGET_WINNT
  76. __declspec(align(sizeof(FuncTable::Entry)))
  77. #endif // TARGET_WINNT
  78. static FuncTable::Entry __offload_entry_table_start = { 0 };
  79. // list element for the current module
  80. static FuncList::Node __offload_entry_node = {
  81. { &__offload_entry_table_start + 1, -1 },
  82. 0, 0
  83. };
  84. // offload fp section prolog
  85. ALLOCATE(OFFLOAD_FUNC_TABLE_SECTION_START)
  86. #ifdef TARGET_WINNT
  87. __declspec(align(sizeof(FuncTable::Entry)))
  88. #endif // TARGET_WINNT
  89. static FuncTable::Entry __offload_func_table_start = { 0 };
  90. // list element for the current module
  91. static FuncList::Node __offload_func_node = {
  92. { &__offload_func_table_start + 1, -1 },
  93. 0, 0
  94. };
  95. // offload fp section prolog
  96. ALLOCATE(OFFLOAD_VAR_TABLE_SECTION_START)
  97. #ifdef TARGET_WINNT
  98. __declspec(align(sizeof(VarTable::Entry)))
  99. #endif // TARGET_WINNT
  100. static VarTable::Entry __offload_var_table_start = { 0 };
  101. // list element for the current module
  102. static VarList::Node __offload_var_node = {
  103. { &__offload_var_table_start + 1 },
  104. 0, 0
  105. };
  106. #ifdef MYO_SUPPORT
  107. // offload myo shared var section prolog
  108. // first element is empty
  109. ALLOCATE(OFFLOAD_MYO_SHARED_TABLE_SECTION_START)
  110. #ifdef TARGET_WINNT
  111. __declspec(align(sizeof(SharedTableEntry)))
  112. #endif // TARGET_WINNT
  113. static MYOVarTable::Entry __offload_myo_shared_var_start = { 0 };
  114. // list element for the current module
  115. // table entry pointer skips the empty first entry
  116. static MYOVarTableList::Node __offload_myo_shared_var_node = {
  117. { &__offload_myo_shared_var_start + 1 },
  118. 0, 0
  119. };
  120. // offload myo shared vtable section prolog
  121. // first element is empty
  122. ALLOCATE(OFFLOAD_MYO_SHARED_VTABLE_SECTION_START)
  123. #ifdef TARGET_WINNT
  124. __declspec(align(sizeof(SharedTableEntry)))
  125. #endif // TARGET_WINNT
  126. static MYOVarTable::Entry __offload_myo_shared_vtable_start = { 0 };
  127. // list element for the current module
  128. // table entry pointer skips the empty first entry
  129. static MYOVarTableList::Node __offload_myo_shared_vtable_node = {
  130. { &__offload_myo_shared_vtable_start + 1 },
  131. 0, 0
  132. };
  133. // offload myo shared var init section prolog
  134. // first element is empty
  135. ALLOCATE(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START)
  136. #ifdef TARGET_WINNT
  137. __declspec(align(sizeof(InitTableEntry)))
  138. #endif // TARGET_WINNT
  139. static MYOInitTable::Entry __offload_myo_init_table_start = { 0 };
  140. // list element for the current module
  141. // table entry pointer skips the empty first entry
  142. static MYOInitTableList::Node __offload_myo_init_table_node = {
  143. { &__offload_myo_init_table_start + 1 },
  144. 0, 0
  145. };
  146. // The functions and variables needed for a built-in
  147. // remote function entry for vtable initialization on MIC
  148. #if !HOST_LIBRARY
  149. MyoError __offload_init_vtables(void)
  150. {
  151. SharedTableEntry *t_start;
  152. //OFFLOAD_DEBUG_TRACE(3, "%s\n", __func__);
  153. t_start = &__offload_myo_shared_vtable_start + 1;
  154. //OFFLOAD_DEBUG_TRACE(3, "%s(%p)\n", __func__, t_start);
  155. while (t_start->varName != 0) {
  156. //OFFLOAD_DEBUG_TRACE(4,
  157. // "myo shared vtable \"%s\" &myo_ptr = %p myo_ptr = %p\n",
  158. // t_start->varName,
  159. // (void *)(t_start->sharedAddr),
  160. // ((void **)(t_start->sharedAddr))[0]);
  161. t_start++;
  162. }
  163. __offload_myo_shared_init_table_process(
  164. &__offload_myo_init_table_start + 1);
  165. return MYO_SUCCESS;
  166. }
  167. #endif // !HOST_LIBRARY
  168. static void vtable_initializer()
  169. {
  170. }
  171. #if !HOST_LIBRARY
  172. static MyoError vtable_initializer_wrapper()
  173. {
  174. __offload_myoAcquire();
  175. __offload_init_vtables();
  176. __offload_myoRelease();
  177. return MYO_SUCCESS;
  178. }
  179. #endif
  180. static void* __offload_vtable_initializer_thunk_ptr = 0;
  181. // offload myo fptr section prolog
  182. // first element is pre-initialized to the MIC vtable initializer
  183. ALLOCATE(OFFLOAD_MYO_FPTR_TABLE_SECTION_START)
  184. #ifdef TARGET_WINNT
  185. __declspec(align(sizeof(FptrTableEntry)))
  186. #endif // TARGET_WINNT
  187. static MYOFuncTable::Entry __offload_myo_fptr_table_start = {
  188. #if HOST_LIBRARY
  189. "--vtable_initializer--",
  190. (void*)&vtable_initializer,
  191. (void*)&__offload_vtable_initializer_thunk_ptr,
  192. #ifdef TARGET_WINNT
  193. // Dummy to pad up to 32 bytes
  194. 0
  195. #endif // TARGET_WINNT
  196. #else // HOST_LIBRARY
  197. "--vtable_initializer--",
  198. (void*)&vtable_initializer,
  199. (void*)&vtable_initializer_wrapper,
  200. &__offload_vtable_initializer_thunk_ptr,
  201. #endif // HOST_LIBRARY
  202. };
  203. // list element for the current module
  204. static MYOFuncTableList::Node __offload_myo_fptr_table_node = {
  205. { &__offload_myo_fptr_table_start },
  206. 0, 0
  207. };
  208. #endif // MYO_SUPPORT
  209. // init/fini code which adds/removes local lookup data to/from the global list
  210. static void offload_fini();
  211. static void offload_fini_so();
  212. #ifndef TARGET_WINNT
  213. static void offload_init() __attribute__((constructor(101)));
  214. #else // TARGET_WINNT
  215. static void offload_init();
  216. // Place offload initialization before user constructors
  217. ALLOCATE(OFFLOAD_CRTINIT_SECTION_START)
  218. static void (*addressof_offload_init)() = offload_init;
  219. #endif // TARGET_WINNT
  220. static void offload_init()
  221. {
  222. bool success;
  223. // Set offload version
  224. __offload_set_version(OFFLOAD_VERSION_17);
  225. // register offload tables
  226. __offload_register_tables(&__offload_entry_node,
  227. &__offload_func_node,
  228. &__offload_var_node);
  229. #if HOST_LIBRARY
  230. success = __offload_register_image(&__offload_target_image);
  231. if (!success)
  232. {
  233. return;
  234. }
  235. #endif // HOST_LIBRARY
  236. #ifdef MYO_SUPPORT
  237. #if HOST_LIBRARY
  238. // If this was the main program register main atexit routine
  239. if (__offload_myoProcessTables(
  240. &__offload_target_image,
  241. &__offload_myo_init_table_node,
  242. &__offload_myo_shared_var_node,
  243. &__offload_myo_shared_vtable_node,
  244. &__offload_myo_fptr_table_node))
  245. {
  246. atexit(offload_fini);
  247. #ifdef TARGET_WINNT
  248. } else {
  249. atexit(offload_fini_so);
  250. #endif
  251. }
  252. #else // HOST_LIBRARY
  253. __offload_myoProcessTables(
  254. &__offload_myo_init_table_start + 1,
  255. &__offload_myo_shared_var_start + 1,
  256. &__offload_myo_shared_vtable_start + 1,
  257. &__offload_myo_fptr_table_start
  258. );
  259. #endif // HOST_LIBRARY
  260. #endif // MYO_SUPPORT
  261. }
  262. #ifndef TARGET_WINNT
  263. static void offload_fini_so() __attribute__((destructor(101)));
  264. #endif // TARGET_WINNT
  265. static void offload_fini()
  266. {
  267. #if HOST_LIBRARY
  268. __offload_unregister_image(&__offload_target_image);
  269. #endif // HOST_LIBRARY
  270. }
  271. static void offload_fini_so()
  272. {
  273. // Offload and MYO tables need to be removed from list
  274. // to prevent invalid accesses after dlclose
  275. // Remove offload tables
  276. __offload_unregister_tables(&__offload_entry_node,
  277. &__offload_func_node,
  278. &__offload_var_node);
  279. #if HOST_LIBRARY
  280. if(!__offload_target_image_is_executable(&__offload_target_image)) {
  281. __offload_unregister_image(&__offload_target_image);
  282. }
  283. #endif
  284. #ifdef MYO_SUPPORT
  285. #if HOST_LIBRARY
  286. // Remove MYO tables
  287. __offload_myoRemoveTables(
  288. &__offload_myo_init_table_node,
  289. &__offload_myo_shared_var_node,
  290. &__offload_myo_shared_vtable_node,
  291. &__offload_myo_fptr_table_node);
  292. #endif // HOST_LIBRARY
  293. #endif // MYO_SUPPORT
  294. }