1 /*
2  * Copyright (c) 2023 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_LLEXT_SYMBOL_H
8 #define ZEPHYR_LLEXT_SYMBOL_H
9 
10 #include <zephyr/sys/iterable_sections.h>
11 #include <zephyr/toolchain.h>
12 #include <stddef.h>
13 #include <stdint.h>
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 /**
20  * @file
21  * @brief Linkable loadable extension symbol definitions
22  *
23  * This file provides a set of macros and structures for defining and exporting
24  * symbols from the base image to extensions and vice versa, so that proper
25  * linking can be done between the two entities.
26  *
27  * @defgroup llext_symbols Exported symbol definitions
28  * @ingroup llext_apis
29  * @{
30  */
31 
32 /**
33  * @brief Constant symbols are unchangeable named memory addresses
34  *
35  * Symbols may be named function or global objects that have been exported
36  * for linking. These constant symbols are useful in the base image
37  * as they may be placed in ROM.
38  *
39  * @note When updating this structure, make sure to also update the
40  * 'scripts/build/llext_prepare_exptab.py' build script.
41  */
42 struct llext_const_symbol {
43 	/** At build time, we always write to 'name'.
44 	 *  At runtime, which field is used depends
45 	 *  on CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID.
46 	 */
47 	union {
48 		/** Name of symbol */
49 		const char *const name;
50 
51 		/** Symbol Link Identifier */
52 		const uintptr_t slid;
53 	};
54 
55 	/** Address of symbol */
56 	const void *const addr;
57 };
58 BUILD_ASSERT(sizeof(struct llext_const_symbol) == 2 * sizeof(uintptr_t));
59 
60 /**
61  * @brief Symbols are named memory addresses
62  *
63  * Symbols may be named function or global objects that have been exported
64  * for linking. These are mutable and should come from extensions where
65  * the location may need updating depending on where memory is placed.
66  */
67 struct llext_symbol {
68 	/** Name of symbol */
69 	const char *name;
70 
71 	/** Address of symbol */
72 	void *addr;
73 };
74 
75 
76 /**
77  * @brief A symbol table
78  *
79  * An array of symbols
80  */
81 struct llext_symtable {
82 	/** Number of symbols in the table */
83 	size_t sym_cnt;
84 
85 	/** Array of symbols */
86 	struct llext_symbol *syms;
87 };
88 
89 
90 /** @cond ignore */
91 #ifdef LL_EXTENSION_BUILD
92 /* Extension build: add exported symbols to llext table */
93 #define Z_LL_EXTENSION_SYMBOL_NAMED(sym_ident, sym_name)			\
94 	static const struct llext_const_symbol					\
95 			Z_GENERIC_SECTION(.exported_sym) __used			\
96 			__llext_sym_ ## sym_name = {				\
97 		.name = STRINGIFY(sym_name), .addr = (const void *)&sym_ident,	\
98 	}
99 #else
100 /* No-op when not building an extension */
101 #define Z_LL_EXTENSION_SYMBOL_NAMED(sym_ident, sym_name)
102 #endif
103 /** @endcond */
104 
105 /**
106  * @brief Exports a symbol from an extension to the base image with a custom name
107  *
108  * Version of @ref LL_EXTENSION_SYMBOL that allows the user to specify a custom
109  * name for the exported symbol.
110  *
111  * @param sym_ident Extension symbol to export to the base image
112  * @param sym_name Name associated with the symbol
113  */
114 #define LL_EXTENSION_SYMBOL_NAMED(sym_ident, sym_name)				\
115 	Z_LL_EXTENSION_SYMBOL_NAMED(sym_ident, sym_name)
116 
117 /**
118  * @brief Exports a symbol from an extension to the base image
119  *
120  * This macro can be used in extensions to add a symbol (function or object)
121  * to the extension's exported symbol table, so that it may be referenced by
122  * the base image.
123  *
124  * When not building an extension, this macro is a no-op.
125  *
126  * @param x Extension symbol to export to the base image
127  */
128 #define LL_EXTENSION_SYMBOL(x) Z_LL_EXTENSION_SYMBOL_NAMED(x, x)
129 
130 /** @cond ignore */
131 #if defined(LL_EXTENSION_BUILD)
132 /* Extension build: EXPORT_SYMBOL maps to LL_EXTENSION_SYMBOL */
133 #define Z_EXPORT_SYMBOL_NAMED(sym_ident, sym_name)				\
134 	Z_LL_EXTENSION_SYMBOL_NAMED(sym_ident, sym_name)
135 #elif defined(CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID)
136 /* SLID-enabled LLEXT application: export symbols, names in separate section */
137 #define Z_EXPORT_SYMBOL_NAMED(sym_ident, sym_name)				\
138 	static const char Z_GENERIC_SECTION(llext_exports_strtab) __used	\
139 		__llext_sym_name_ ## sym_name[] = STRINGIFY(sym_name);		\
140 	static const STRUCT_SECTION_ITERABLE(llext_const_symbol,		\
141 					     __llext_sym_ ## sym_name) = {	\
142 		.name = __llext_sym_name_ ## sym_name,				\
143 		.addr = (const void *)&sym_ident,				\
144 	}
145 #elif defined(CONFIG_LLEXT)
146 /* LLEXT application: export symbols */
147 #define Z_EXPORT_SYMBOL_NAMED(sym_ident, sym_name)				\
148 	static const STRUCT_SECTION_ITERABLE(llext_const_symbol,		\
149 					     __llext_sym_ ## sym_name) = {	\
150 		.name = STRINGIFY(sym_name), .addr = (const void *)&sym_ident,	\
151 	}
152 #else
153 /* No extension support in this build */
154 #define Z_EXPORT_SYMBOL_NAMED(sym_ident, sym_name)
155 #endif
156 /** @endcond */
157 
158 /**
159  * @brief Export a constant symbol from the current build with a custom name
160  *
161  * Version of @ref EXPORT_SYMBOL that allows the user to specify a custom name
162  * for the exported symbol.
163  *
164  * When @c CONFIG_LLEXT is not enabled, this macro is a no-op.
165  *
166  * @param sym_ident Symbol to export
167  * @param sym_name Name associated with the symbol
168  */
169 #define EXPORT_SYMBOL_NAMED(sym_ident, sym_name)				\
170 	Z_EXPORT_SYMBOL_NAMED(sym_ident, sym_name)
171 
172 /**
173  * @brief Export a constant symbol from the current build
174  *
175  * Takes a symbol (function or object) by symbolic name and adds the name
176  * and address of the symbol to a table of symbols that may be referenced
177  * by extensions or by the base image, depending on the current build type.
178  *
179  * When @c CONFIG_LLEXT is not enabled, this macro is a no-op.
180  *
181  * @param x Symbol to export
182  */
183 #define EXPORT_SYMBOL(x) EXPORT_SYMBOL_NAMED(x, x)
184 
185 /**
186  * @}
187  */
188 
189 #ifdef __cplusplus
190 }
191 #endif
192 
193 
194 #endif /* ZEPHYR_LLEXT_SYMBOL_H */
195