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(x)						\
94 	static const struct llext_const_symbol					\
95 			Z_GENERIC_SECTION(".exported_sym") __used		\
96 			__llext_sym_ ## x = {					\
97 		.name = STRINGIFY(x), .addr = (const void *)&x,			\
98 	}
99 #else
100 /* No-op when not building an extension */
101 #define Z_LL_EXTENSION_SYMBOL(x)
102 #endif
103 /** @endcond */
104 
105 /**
106  * @brief Exports a symbol from an extension to the base image
107  *
108  * This macro can be used in extensions to add a symbol (function or object)
109  * to the extension's exported symbol table, so that it may be referenced by
110  * the base image.
111  *
112  * When not building an extension, this macro is a no-op.
113  *
114  * @param x Extension symbol to export to the base image
115  */
116 #define LL_EXTENSION_SYMBOL(x) Z_LL_EXTENSION_SYMBOL(x)
117 
118 /** @cond ignore */
119 #if defined(LL_EXTENSION_BUILD)
120 /* Extension build: EXPORT_SYMBOL maps to LL_EXTENSION_SYMBOL */
121 #define Z_EXPORT_SYMBOL(x) Z_LL_EXTENSION_SYMBOL(x)
122 #elif defined(CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID)
123 /* SLID-enabled LLEXT application: export symbols, names in separate section */
124 #define Z_EXPORT_SYMBOL(x)							\
125 	static const char Z_GENERIC_SECTION("llext_exports_strtab") __used	\
126 		__llext_sym_name_ ## x[] = STRINGIFY(x);				\
127 	static const STRUCT_SECTION_ITERABLE(llext_const_symbol,                \
128 					     __llext_sym_ ## x) = {	        \
129 		.name = __llext_sym_name_ ## x, .addr = (const void *)&x,		\
130 	}
131 #elif defined(CONFIG_LLEXT)
132 /* LLEXT application: export symbols */
133 #define Z_EXPORT_SYMBOL(x)							\
134 	static const STRUCT_SECTION_ITERABLE(llext_const_symbol,                \
135 					     __llext_sym_ ## x) = {	        \
136 		.name = STRINGIFY(x), .addr = (const void *)&x,			\
137 	}
138 #else
139 /* No extension support in this build */
140 #define Z_EXPORT_SYMBOL(x)
141 #endif
142 /** @endcond */
143 
144 /**
145  * @brief Export a constant symbol from the current build
146  *
147  * Takes a symbol (function or object) by symbolic name and adds the name
148  * and address of the symbol to a table of symbols that may be referenced
149  * by extensions or by the base image, depending on the current build type.
150  *
151  * When @c CONFIG_LLEXT is not enabled, this macro is a no-op.
152  *
153  * @param x Symbol to export
154  */
155 #define EXPORT_SYMBOL(x) Z_EXPORT_SYMBOL(x)
156 
157 /**
158  * @}
159  */
160 
161 #ifdef __cplusplus
162 }
163 #endif
164 
165 
166 #endif /* ZEPHYR_LLEXT_SYMBOL_H */
167