When building relocatable extensions, exported symbol names might end
up in a separate section (in my case ".rodata.str1.1") for which
storage address don't match section address. To access those names
addresses have to be relalculated.
Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
The new CONFIG_LLEXT_IMPORT_ALL_GLOBALS option allows all global symbols
from extensions to be used by the main application. This is useful to
load basic extensions that have been compiled without the full Zephyr
EDK.
Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
The ELF format allows for multiple string and symbol tables with
complex references between them. This is especially evident when
debugging information is included.
This patch fixes the issues that have been identified with multiple
string tables to allow LLEXT to properly parse those files:
* The symbol table used by LLEXT (LLEXT_MEM_SYMTAB) is now chosen
depending on the loaded file type, and other tables are ignored.
This change is also applied to the SLID injection script.
* The LLEXT string table (LLEXT_MEM_SYMTAB) is now correctly identified
by the symbol table reference, instead of picking the first one.
* VMA range checks only make sense for allocated sections.
Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
When linking and relocations are performed on the ELF object itself
with no copying, also global binding linking can break references.
Disable linking globally for such cases.
Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Move cached section headers to struct llext from struct llext_loader
to preserve them after llext_load() returns.
Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
When CONFIG_LLEXT_STORAGE_WRITABLE is selected and .pre_located is
set, the BSS section is allocated by the user too, no need to
allocate it internally.
Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
This commit introduces architecture-specific ELF relocations for RISC-V,
in accordance with the RISC-V PSABI specification:
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc
Also, the necessary compiler configurations for compiling LLEXT
extensions on RISC-V are added, and the llext tests are executed on
RISC-V targets.
Calling llext extensions from user threads in RISC-V is still
unsupported as of this commit.
Signed-off-by: Eric Ackermann <eric.ackermann@cispa.de>
Some LLEXT objects can include sections, that should not be merged
with other sections of the same type. E.g. when such sections should
be placed into locations, other than the default. Add support for
such sections.
Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
To simplify LLEXT loader parameter extension pass the whole
struct llext_load_param to final consumers instead of extracting
individual fields from it in the caller function.
Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Make llext_loaded_sect_ptr() a proper function to be able to call it
from platform LLEXT code.
Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
There's no reason for the .exported_sym data to always land at one end of a
data region; the order of sections depends on the whim of the compiler and
assembler.
Ignore overlaps between that region and other data regions.
Signed-off-by: Keith Packard <keithp@keithp.com>
Load the .preinit_array, .init_array and .fini_array sections in ELF
files. These sections are arrays of function pointers that are filled by
the compiler with the addresses of functions that need to be called at
startup or termination by the loader, such as C++ constructors and
destructors.
Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
Introducing `llext_prepare()` and `llext_finalize()` APIs
that are invoked and the beginning and the end of the `llext_load()`
function.
The purpose of these functions is to bring possibility of initializing
loader before it is used and uninitialize or clean up when
it is no longer needed. Both functions are optional.
The buffer loader has been aligned to methods introduced in the patch.
Signed-off-by: Adam Wojasinski <awojasinski@baylibre.com>
By default, normal memory is set readable+writable and not executable.
Adjust those permissions according to each region:
LLEXT_MEM_TEXT --> K_MEM_PERM_EXEC
LLEXT_MEM_DATA, LLEXT_MEM_BSS --> K_MEM_PERM_RW
LLEXT_MEM_RODATA --> K_MEM_PERM_RO aka 0
This must be done only at the end of an LLEXT load operation as memory
needs to remain RW for reloc processing, etc.
And while at it, flush/invalidate the cache accordingly.
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
When deciding which sections to group together, only the low 3
section attribute bits are relevant, ignore the rest.
Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Review and improve comments in source code to better describe the API
and the functionality provided by the llext library.
No actual code changes are performed in this commit.
Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
The term "section" has a very specific meaning in the ELF file format.
After 709b2e4 ("llext: automatically merge sections by type"), some of
the code that was originally dealing with ELF sections is now handling
"memory regions" made of multiple ELF sections of the same type.
Make sure to use the term "region" consistently in the code and
log messages to avoid confusion with the original ELF sections.
Notable exception to this is the "ldr->sect" array, which is actively
used outside Zephyr and will need to be phased out in the future.
Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
This patch changes the error codes returned by the ELF subsystem to be
more consistent with the standard error descriptions. In particular:
- issues with the ELF file are now reported as -ENOEXEC;
- valid but unsupported edge cases are reported as -ENOTSUP;
- failures in searching for an entry are reported as -ENOENT.
Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
llext_load() included a check to ensure that the ELF file contains all
the necessary tables, but it was not functional. Add the missing check
and rename the variable to avoid confusion with the total section count.
Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
From https://mails.dpdk.org/archives/dev/2021-December/231212.html:
Downcasting a void* to struct aesni_gcm_session* caused the session
data to be treated as tainted. Removing the void* temporary variable
and adding a cast avoids this issue.
Try the same approach here to prevent the ldr->sect_hdrs pointer from
being treated as tainted.
May fix#74817.
Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
The function llext_section_by_name() is used only in one place, and it
expects the caller to have the section headers cache available. This
cache is freed after the ELF file is loaded, so the function is not
usable in the context where it is called.
Remove the function and replace the call with a direct search in the
ELF file section headers array, as was done before 08eb314c35.
Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
The optimization in llext_load() to avoid using the generic path for
sections that are cached in memory was broken for two reasons:
- it was comparing an ELF section index to LLEXT_MEM_BSS, which is a
llext_mem enum, and
- it was using the wrong section address for the cached sections since
the "merged sections" feature was introduced in 709b2e44bf.
This patch fixes both issues using the new llext_loaded_sect_ptr()
helper function.
Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
The recent changes to the loader code merged related sections together,
making sure the merged sections are self-coherent. This, however, did
not take into account that the original ELF sections are now a _subset_
of the merged section - and might not start from the beginning of the
merged section.
This patch converts the `sect_map` member of `struct llext_loader` to a
structure with two fields:
- mem_idx: the memory area index where the ELF section is mapped
- offset: the offset of the ELF section inside the memory area
The offset is calculated after all sections are merged and the final
groups are defined. This will allow the loader to correctly calculate
the address of symbols and relocations in the merged sections.
Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
The section headers are now available in the loader structure, so we can
use those directly instead of reading them from the ELF file every time.
This commit contains no logic changes; it removes all copies of the
header loading code and replaces them with direct access to the cached
section headers.
Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
This change reads all section headers at once, instead of reading them
one by one. This is more efficient and allows to further simplify the
code downstream.
The section headers are directly accessed from the file buffer if the
llext_peek() function is supported by the loader. Otherwise, they are
read into a buffer allocated on the heap and used only during the
llext_load() function.
Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
The do_llext_load function is responsible for loading an extension from a
file, and for this purpose it calls a number of functions that a) allocate
memory, and b) can fail. This creates the opportunity for memory leaks if
the error paths are not handled correctly.
This commit adds a comment at the beginning of the function to document
the memory management policy that has to be followed in this file:
cleanup is not performed in the error paths, and all memory is freed at
the end of the do_llext_load() function, both in the case of error and of
successful loading.
As an improvement, the symbol table is not freed if the LLEXT log level
is set to debug, so that it can be used, for example, to inspect the
symbols of the loaded extension.
Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
The recent llext_map_sections() rework changed the way debug messages
are output so that the names of most skipped sections are not printed
at all. This makes debugging harder since the section names are useful
to identify the contents at a glance.
Also print a few additional fields from the section header, and use 0x
prefixes for hex numbers.
Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
This commit moves ELF loading and linking code to separate files. This
is done to make the code more manageable and to make it easier to add
new features in the future.
No functional changes are introduced by this commit, except for a few
static functions now made public to allow this file split to occur.
Signed-off-by: Luca Burelli <l.burelli@arduino.cc>