Skip to content

Commit b7377eb

Browse files
committed
llext: add a test for the pre_located feature
This test checks that the pre_located feature works as expected. It creates a new extension that is manually relocated to a specific address via the add_llext_command() CMake function invoking a custom linker command. The test then loads the extension setting the pre_located option and checks that the symbol is resolved properly. Signed-off-by: Luca Burelli <[email protected]>
1 parent 518a712 commit b7377eb

File tree

3 files changed

+62
-9
lines changed

3 files changed

+62
-9
lines changed

tests/subsys/llext/simple/CMakeLists.txt

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ if(CONFIG_ARM)
2323
endif()
2424
endif()
2525

26+
if (CONFIG_LLEXT_TYPE_ELF_RELOCATABLE AND CONFIG_XTENSA)
27+
list(APPEND ext_names pre_located)
28+
endif()
29+
2630
# generate extension targets foreach extension given by 'ext_names'
2731
foreach(ext_name ${ext_names})
2832
set(ext_src ${PROJECT_SOURCE_DIR}/src/${ext_name}_ext.c)
@@ -45,12 +49,15 @@ if(NOT CONFIG_LLEXT_TYPE_ELF_OBJECT)
4549
)
4650
endif()
4751

48-
# Add a dummy custom processing command to test add_llext_command
49-
get_target_property(proc_in_file hello_world_ext lib_output)
50-
get_target_property(proc_out_file hello_world_ext pkg_input)
51-
add_llext_command(
52-
TARGET hello_world_ext
53-
POST_BUILD
54-
COMMAND echo "dummy patching ${proc_in_file} to create ${proc_out_file}"
55-
COMMAND ${CMAKE_COMMAND} -E copy ${proc_in_file} ${proc_out_file}
56-
)
52+
if (CONFIG_LLEXT_TYPE_ELF_RELOCATABLE AND CONFIG_XTENSA)
53+
# Manually fix the pre_located extension's text address at a multiple of 4
54+
get_target_property(pre_located_target pre_located_ext lib_target)
55+
get_target_property(pre_located_file pre_located_ext pkg_input)
56+
add_llext_command(
57+
TARGET pre_located_ext
58+
POST_BUILD
59+
COMMAND ${CMAKE_C_COMPILER}
60+
-Wl,-r -Wl,-Ttext=0xbada110c -nostdlib -nodefaultlibs -nostartfiles
61+
$<TARGET_OBJECTS:${pre_located_target}> -o ${pre_located_file}
62+
)
63+
endif()
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Copyright (c) 2024 Arduino SA.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/*
8+
* This file contains a simple test extension that defines an entry point
9+
* in the .text section. The entry point is never called, but the symbol
10+
* address is fixed via a linker call and then checked by the test.
11+
*/
12+
13+
#include <zephyr/llext/symbol.h>
14+
15+
void test_entry(void)
16+
{
17+
/* This function is never called */
18+
}
19+
LL_EXTENSION_SYMBOL(test_entry);

tests/subsys/llext/simple/src/test_llext_simple.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,33 @@ static LLEXT_CONST uint8_t multi_file_ext[] __aligned(4) = {
237237
LLEXT_LOAD_UNLOAD(multi_file, true, NULL)
238238
#endif
239239

240+
#if defined(CONFIG_LLEXT_TYPE_ELF_RELOCATABLE) && defined(CONFIG_XTENSA)
241+
static LLEXT_CONST uint8_t pre_located_ext[] __aligned(4) = {
242+
#include "pre_located.inc"
243+
};
244+
245+
ZTEST(llext, test_pre_located)
246+
{
247+
struct llext_buf_loader buf_loader =
248+
LLEXT_BUF_LOADER(pre_located_ext, ARRAY_SIZE(pre_located_ext));
249+
struct llext_loader *loader = &buf_loader.loader;
250+
struct llext_load_param ldr_parm = LLEXT_LOAD_PARAM_DEFAULT;
251+
struct llext *ext = NULL;
252+
const void *test_entry_fn;
253+
int res;
254+
255+
/* load the extension trying to respect the addresses in the ELF */
256+
ldr_parm.pre_located = true;
257+
res = llext_load(loader, "pre_located", &ext, &ldr_parm);
258+
zassert_ok(res, "load should succeed");
259+
260+
/* check the function address is the expected one */
261+
test_entry_fn = llext_find_sym(&ext->exp_tab, "test_entry");
262+
zassert_equal(test_entry_fn, (void *)0xbada110c, "test_entry should be at 0xbada110c");
263+
264+
llext_unload(&ext);
265+
}
266+
#endif
240267

241268
/*
242269
* Ensure that EXPORT_SYMBOL does indeed provide a symbol and a valid address

0 commit comments

Comments
 (0)