@@ -61,16 +61,6 @@ struct llext_test {
6161K_THREAD_STACK_DEFINE (llext_stack , 1024 );
6262struct k_thread llext_thread ;
6363
64- #ifdef CONFIG_USERSPACE
65- void llext_entry (void * arg0 , void * arg1 , void * arg2 )
66- {
67- void (* fn )(void ) = arg0 ;
68-
69- LOG_INF ("calling fn %p from thread %p" , fn , k_current_get ());
70- fn ();
71- }
72- #endif /* CONFIG_USERSPACE */
73-
7464
7565/* syscalls test */
7666
@@ -163,7 +153,8 @@ void load_call_unload(const struct llext_test *test_case)
163153 /* Should be runnable from newly created thread */
164154 k_thread_create (& llext_thread , llext_stack ,
165155 K_THREAD_STACK_SIZEOF (llext_stack ),
166- & llext_entry , test_entry_fn , NULL , NULL ,
156+ (k_thread_entry_t ) & llext_bootstrap ,
157+ ext , test_entry_fn , NULL ,
167158 1 , 0 , K_FOREVER );
168159
169160 k_mem_domain_add_thread (& domain , & llext_thread );
@@ -186,7 +177,8 @@ void load_call_unload(const struct llext_test *test_case)
186177 if (!test_case -> kernel_only ) {
187178 k_thread_create (& llext_thread , llext_stack ,
188179 K_THREAD_STACK_SIZEOF (llext_stack ),
189- & llext_entry , test_entry_fn , NULL , NULL ,
180+ (k_thread_entry_t ) & llext_bootstrap ,
181+ ext , test_entry_fn , NULL ,
190182 1 , K_USER , K_FOREVER );
191183
192184 k_mem_domain_add_thread (& domain , & llext_thread );
@@ -204,12 +196,24 @@ void load_call_unload(const struct llext_test *test_case)
204196 }
205197
206198#else /* CONFIG_USERSPACE */
199+ /* No userspace support: run the test only in supervisor mode, without
200+ * creating a new thread.
201+ */
207202 if (test_case -> test_setup ) {
208203 test_case -> test_setup (ext , NULL );
209204 }
210205
206+ #ifdef CONFIG_LLEXT_TYPE_ELF_SHAREDLIB
207+ /* The ELF specification forbids shared libraries from defining init
208+ * entries, so calling llext_bootstrap here would be redundant. Use
209+ * this opportunity to test llext_call_fn, even though llext_bootstrap
210+ * would have behaved simlarly.
211+ */
211212 zassert_ok (llext_call_fn (ext , "test_entry" ),
212213 "test_entry call should succeed" );
214+ #else /* !USERSPACE && !SHAREDLIB */
215+ llext_bootstrap (ext , test_entry_fn , NULL );
216+ #endif
213217
214218 if (test_case -> test_cleanup ) {
215219 test_case -> test_cleanup (ext );
@@ -251,6 +255,29 @@ LLEXT_LOAD_UNLOAD(hello_world,
251255 .kernel_only = true
252256)
253257
258+ #ifndef CONFIG_LLEXT_TYPE_ELF_SHAREDLIB
259+ static LLEXT_CONST uint8_t init_fini_ext [] ELF_ALIGN = {
260+ #include "init_fini.inc"
261+ };
262+
263+ static void init_fini_test_cleanup (struct llext * ext )
264+ {
265+ /* Make sure fini_fn() was called during teardown.
266+ * (see init_fini_ext.c for more details).
267+ */
268+ const int * number = llext_find_sym (& ext -> exp_tab , "number" );
269+ const int expected = (((((1 << 4 ) | 2 ) << 4 ) | 3 ) << 4 ) | 4 ; /* 0x1234 */
270+
271+ zassert_not_null (number , "number should be an exported symbol" );
272+ zassert_equal (* number , expected , "got 0x%x instead of 0x%x during cleanup" ,
273+ * number , expected );
274+ }
275+
276+ LLEXT_LOAD_UNLOAD (init_fini ,
277+ .test_cleanup = init_fini_test_cleanup
278+ )
279+ #endif
280+
254281static LLEXT_CONST uint8_t logging_ext [] ELF_ALIGN = {
255282 #include "logging.inc"
256283};
0 commit comments