Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions tests/subsys/llext/simple/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ if(CONFIG_ARM)
endif()
endif()

if (CONFIG_LLEXT_TYPE_ELF_RELOCATABLE AND CONFIG_XTENSA)
list(APPEND ext_names pre_located)
endif()

# generate extension targets foreach extension given by 'ext_names'
foreach(ext_name ${ext_names})
set(ext_src ${PROJECT_SOURCE_DIR}/src/${ext_name}_ext.c)
Expand All @@ -45,12 +49,15 @@ if(NOT CONFIG_LLEXT_TYPE_ELF_OBJECT)
)
endif()

# Add a dummy custom processing command to test add_llext_command
get_target_property(proc_in_file hello_world_ext lib_output)
get_target_property(proc_out_file hello_world_ext pkg_input)
add_llext_command(
TARGET hello_world_ext
POST_BUILD
COMMAND echo "dummy patching ${proc_in_file} to create ${proc_out_file}"
COMMAND ${CMAKE_COMMAND} -E copy ${proc_in_file} ${proc_out_file}
)
if (CONFIG_LLEXT_TYPE_ELF_RELOCATABLE AND CONFIG_XTENSA)
# Manually fix the pre_located extension's text address at a multiple of 4
get_target_property(pre_located_target pre_located_ext lib_target)
get_target_property(pre_located_file pre_located_ext pkg_input)
add_llext_command(
TARGET pre_located_ext
POST_BUILD
COMMAND ${CMAKE_C_COMPILER}
-Wl,-r -Wl,-Ttext=0xbada110c -nostdlib -nodefaultlibs -nostartfiles
$<TARGET_OBJECTS:${pre_located_target}> -o ${pre_located_file}
)
endif()
19 changes: 19 additions & 0 deletions tests/subsys/llext/simple/src/pre_located_ext.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2024 Arduino SA.
*
* SPDX-License-Identifier: Apache-2.0
*/

/*
* This file contains a simple test extension that defines an entry point
* in the .text section. The entry point is never called, but the symbol
* address is fixed via a linker call and then checked by the test.
*/

#include <zephyr/llext/symbol.h>

void test_entry(void)
{
/* This function is never called */
}
LL_EXTENSION_SYMBOL(test_entry);
27 changes: 27 additions & 0 deletions tests/subsys/llext/simple/src/test_llext_simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,33 @@ static LLEXT_CONST uint8_t multi_file_ext[] __aligned(4) = {
LLEXT_LOAD_UNLOAD(multi_file, true, NULL)
#endif

#if defined(CONFIG_LLEXT_TYPE_ELF_RELOCATABLE) && defined(CONFIG_XTENSA)
static LLEXT_CONST uint8_t pre_located_ext[] __aligned(4) = {
#include "pre_located.inc"
};

ZTEST(llext, test_pre_located)
{
struct llext_buf_loader buf_loader =
LLEXT_BUF_LOADER(pre_located_ext, ARRAY_SIZE(pre_located_ext));
struct llext_loader *loader = &buf_loader.loader;
struct llext_load_param ldr_parm = LLEXT_LOAD_PARAM_DEFAULT;
struct llext *ext = NULL;
const void *test_entry_fn;
int res;

/* load the extension trying to respect the addresses in the ELF */
ldr_parm.pre_located = true;
res = llext_load(loader, "pre_located", &ext, &ldr_parm);
zassert_ok(res, "load should succeed");

/* check the function address is the expected one */
test_entry_fn = llext_find_sym(&ext->exp_tab, "test_entry");
zassert_equal(test_entry_fn, (void *)0xbada110c, "test_entry should be at 0xbada110c");

llext_unload(&ext);
}
#endif

/*
* Ensure that EXPORT_SYMBOL does indeed provide a symbol and a valid address
Expand Down