2 Copyright (c) 2014 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 \brief Function and Variable tables used by the runtime library
35 #ifndef OFFLOAD_TABLE_H_INCLUDED
36 #define OFFLOAD_TABLE_H_INCLUDED
39 #include "offload_util.h"
41 // Template representing double linked list of tables
42 template <typename T
> class TableList
{
55 explicit TableList(Node
*node
= 0) : m_head(node
) {}
57 void add_table(Node
*node
) {
69 void remove_table(Node
*node
) {
72 if (node
->next
!= 0) {
73 node
->next
->prev
= node
->prev
;
75 if (node
->prev
!= 0) {
76 node
->prev
->next
= node
->next
;
90 // Function lookup table.
92 //! Function table entry
93 /*! This table contains functions created from offload regions. */
94 /*! Each entry consists of a pointer to the function's "key"
95 and the function address. */
96 /*! Each shared library or executable may contain one such table. */
97 /*! The end of the table is marked with an entry whose name field
100 const char* name
; //!< Name of the function
101 void* func
; //!< Address of the function
105 const Entry
*entries
;
108 int64_t max_name_len
;
112 class FuncList
: public TableList
<FuncTable
> {
114 explicit FuncList(Node
*node
= 0) : TableList
<Table
>(node
),
118 // add table to the list
119 void add_table(Node
*node
) {
120 // recalculate max function name length
124 TableList
<Table
>::add_table(node
);
127 // find function address for the given name
128 const void* find_addr(const char *name
);
130 // find function name for the given address
131 const char* find_name(const void *addr
);
133 // max name length from all tables in the list
134 int64_t max_name_length(void);
140 // max name length within from all tables
141 int64_t m_max_name_len
;
144 // Table entry for static variables
146 //! Variable table entry
147 /*! This table contains statically allocated variables marked with
148 __declspec(target(mic) or #pragma omp declare target. */
149 /*! Each entry consists of a pointer to the variable's "key",
150 the variable address and its size in bytes. */
151 /*! Because memory allocation is done from the host,
152 the MIC table does not need the size of the variable. */
153 /*! Padding to make the table entry size a power of 2 is necessary
154 to avoid "holes" between table contributions from different object
155 files on Windows when debug information is specified with /Zi. */
157 const char* name
; //!< Name of the variable
158 void* addr
; //!< Address of the variable
164 // padding to make entry size a power of 2
166 #endif // TARGET_WINNT
170 // Table terminated by an entry with name == -1
171 const Entry
*entries
;
174 // List of var tables
175 class VarList
: public TableList
<VarTable
> {
177 VarList() : TableList
<Table
>()
184 // var table list iterator
185 class Iterator
: public std::iterator
<std::input_iterator_tag
,
188 Iterator() : m_node(0), m_entry(0) {}
190 explicit Iterator(Node
*node
) {
194 Iterator
& operator++() {
197 while (m_entry
->name
== 0) {
200 if (m_entry
->name
== reinterpret_cast<const char*>(-1)) {
201 new_node(m_node
->next
);
207 bool operator==(const Iterator
&other
) const {
208 return m_entry
== other
.m_entry
;
211 bool operator!=(const Iterator
&other
) const {
212 return m_entry
!= other
.m_entry
;
215 const Table::Entry
* operator*() const {
220 void new_node(Node
*node
) {
223 while (m_node
!= 0) {
224 m_entry
= m_node
->table
.entries
;
225 while (m_entry
->name
== 0) {
228 if (m_entry
->name
!= reinterpret_cast<const char*>(-1)) {
231 m_node
= m_node
->next
;
238 const Table::Entry
*m_entry
;
241 Iterator
begin() const {
242 return Iterator(m_head
);
245 Iterator
end() const {
250 // Entry representation in a copy buffer
256 // Calculate the number of elements in the table and
257 // returns the size of buffer for the table
258 int64_t table_size(int64_t &nelems
);
260 // Copy table contents to given buffer. It is supposed to be large
261 // enough to hold all elements as string table.
262 void table_copy(void *buf
, int64_t nelems
);
264 // Patch name offsets in a table after it's been copied to other side
265 static void table_patch_names(void *buf
, int64_t nelems
);
268 extern FuncList __offload_entries
;
269 extern FuncList __offload_funcs
;
270 extern VarList __offload_vars
;
272 // Section names where the lookup tables are stored
274 #define OFFLOAD_ENTRY_TABLE_SECTION_START ".OffloadEntryTable$a"
275 #define OFFLOAD_ENTRY_TABLE_SECTION_END ".OffloadEntryTable$z"
277 #define OFFLOAD_FUNC_TABLE_SECTION_START ".OffloadFuncTable$a"
278 #define OFFLOAD_FUNC_TABLE_SECTION_END ".OffloadFuncTable$z"
280 #define OFFLOAD_VAR_TABLE_SECTION_START ".OffloadVarTable$a"
281 #define OFFLOAD_VAR_TABLE_SECTION_END ".OffloadVarTable$z"
283 #define OFFLOAD_CRTINIT_SECTION_START ".CRT$XCT"
285 #pragma section(OFFLOAD_CRTINIT_SECTION_START, read)
287 #else // TARGET_WINNT
289 #define OFFLOAD_ENTRY_TABLE_SECTION_START ".OffloadEntryTable."
290 #define OFFLOAD_ENTRY_TABLE_SECTION_END ".OffloadEntryTable."
292 #define OFFLOAD_FUNC_TABLE_SECTION_START ".OffloadFuncTable."
293 #define OFFLOAD_FUNC_TABLE_SECTION_END ".OffloadFuncTable."
295 #define OFFLOAD_VAR_TABLE_SECTION_START ".OffloadVarTable."
296 #define OFFLOAD_VAR_TABLE_SECTION_END ".OffloadVarTable."
297 #endif // TARGET_WINNT
299 #pragma section(OFFLOAD_ENTRY_TABLE_SECTION_START, read, write)
300 #pragma section(OFFLOAD_ENTRY_TABLE_SECTION_END, read, write)
302 #pragma section(OFFLOAD_FUNC_TABLE_SECTION_START, read, write)
303 #pragma section(OFFLOAD_FUNC_TABLE_SECTION_END, read, write)
305 #pragma section(OFFLOAD_VAR_TABLE_SECTION_START, read, write)
306 #pragma section(OFFLOAD_VAR_TABLE_SECTION_END, read, write)
309 // register/unregister given tables
310 extern "C" void __offload_register_tables(
311 FuncList::Node
*entry_table
,
312 FuncList::Node
*func_table
,
313 VarList::Node
*var_table
316 extern "C" void __offload_unregister_tables(
317 FuncList::Node
*entry_table
,
318 FuncList::Node
*func_table
,
319 VarList::Node
*var_table
321 #endif // OFFLOAD_TABLE_H_INCLUDED