doc: llext: improve Doxygen comments

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>
This commit is contained in:
Luca Burelli 2024-06-28 11:54:27 +02:00 committed by Alberto Escolar
parent 5d80e253b7
commit f257c997b5
8 changed files with 264 additions and 177 deletions

View file

@ -14,14 +14,15 @@ extern "C" {
#endif
/**
* @brief LLEXT buffer loader
* @defgroup llext_buf_loader Linkable loadable extensions buffer loader
* @ingroup llext
* @file
* @brief LLEXT buffer loader implementation.
*
* @addtogroup llext_loader_apis
* @{
*/
/**
* @brief An extension loader from a provided buffer containing an ELF
* @brief Implementation of @ref llext_loader that reads from a memory buffer.
*/
struct llext_buf_loader {
/** Extension loader */
@ -41,9 +42,9 @@ void *llext_buf_peek(struct llext_loader *ldr, size_t pos);
/** @endcond */
/**
* @brief Initialize an extension buf loader
* @brief Initializer for an llext_buf_loader structure
*
* @param _buf Buffer containing an ELF binary
* @param _buf Buffer containing the ELF binary
* @param _buf_len Buffer length in bytes
*/
#define LLEXT_BUF_LOADER(_buf, _buf_len) \

View file

@ -11,12 +11,13 @@
#include <stdint.h>
/**
* @brief ELF types and parsing
* @file
* @brief Data structures and constants defined in the ELF specification.
*
* Reference documents can be found here https://refspecs.linuxfoundation.org/elf/
* Reference documents can be found here: https://refspecs.linuxfoundation.org/elf/
*
* @defgroup elf ELF data types and defines
* @ingroup llext
* @defgroup llext_elf ELF constants and data types
* @ingroup llext_apis
* @{
*/
@ -196,18 +197,20 @@ struct elf64_shdr {
elf64_xword sh_entsize;
};
#define SHT_NULL 0x0
#define SHT_PROGBITS 0x1
#define SHT_SYMTAB 0x2
#define SHT_STRTAB 0x3
#define SHT_RELA 0x4
#define SHT_NOBITS 0x8
#define SHT_REL 0x9
#define SHT_DYNSYM 0xB
/** ELF section types */
#define SHT_NULL 0x0 /**< Unused section */
#define SHT_PROGBITS 0x1 /**< Program data */
#define SHT_SYMTAB 0x2 /**< Symbol table */
#define SHT_STRTAB 0x3 /**< String table */
#define SHT_RELA 0x4 /**< Relocation entries with addends */
#define SHT_NOBITS 0x8 /**< Program data with no file image */
#define SHT_REL 0x9 /**< Relocation entries without addends */
#define SHT_DYNSYM 0xB /**< Dynamic linking symbol table */
#define SHF_WRITE 0x1
#define SHF_ALLOC 0x2
#define SHF_EXECINSTR 0x4
/** ELF section flags */
#define SHF_WRITE 0x1 /**< Section is writable */
#define SHF_ALLOC 0x2 /**< Section is present in memory */
#define SHF_EXECINSTR 0x4 /**< Section contains executable instructions */
/**
* @brief Symbol table entry(32-bit)
@ -245,30 +248,33 @@ struct elf64_sym {
elf64_xword st_size;
};
#define SHN_UNDEF 0
#define SHN_LORESERVE 0xff00
#define SHN_ABS 0xfff1
#define SHN_COMMON 0xfff2
#define SHN_HIRESERVE 0xffff
/** ELF section numbers */
#define SHN_UNDEF 0 /**< Undefined section */
#define SHN_LORESERVE 0xff00 /**< Start of reserved section numbers */
#define SHN_ABS 0xfff1 /**< Special value for absolute symbols */
#define SHN_COMMON 0xfff2 /**< Common block */
#define SHN_HIRESERVE 0xffff /**< End of reserved section numbers */
#define STT_NOTYPE 0
#define STT_OBJECT 1
#define STT_FUNC 2
#define STT_SECTION 3
#define STT_FILE 4
#define STT_COMMON 5
#define STT_LOOS 10
#define STT_HIOS 12
#define STT_LOPROC 13
#define STT_HIPROC 15
/** Symbol table entry types */
#define STT_NOTYPE 0 /**< No type */
#define STT_OBJECT 1 /**< Data or object */
#define STT_FUNC 2 /**< Function */
#define STT_SECTION 3 /**< Section */
#define STT_FILE 4 /**< File name */
#define STT_COMMON 5 /**< Common block */
#define STT_LOOS 10 /**< Start of OS specific */
#define STT_HIOS 12 /**< End of OS specific */
#define STT_LOPROC 13 /**< Start of processor specific */
#define STT_HIPROC 15 /**< End of processor specific */
#define STB_LOCAL 0
#define STB_GLOBAL 1
#define STB_WEAK 2
#define STB_LOOS 10
#define STB_HIOS 12
#define STB_LOPROC 13
#define STB_HIPROC 15
/** Symbol table entry bindings */
#define STB_LOCAL 0 /**< Local symbol */
#define STB_GLOBAL 1 /**< Global symbol */
#define STB_WEAK 2 /**< Weak symbol */
#define STB_LOOS 10 /**< Start of OS specific */
#define STB_HIOS 12 /**< End of OS specific */
#define STB_LOPROC 13 /**< Start of processor specific */
#define STB_HIPROC 15 /**< End of processor specific */
/**
* @brief Symbol binding from 32bit st_info
@ -300,19 +306,30 @@ struct elf64_sym {
#define ELF64_ST_TYPE(i) ((i) & 0xf)
/**
* @brief Relocation entry for 32-bit ELFs
* @brief Relocation entry for 32-bit ELFs.
*
* This structure stores information describing a relocation to be performed.
* Additional information about the relocation is stored at the location
* pointed to by @ref r_offset.
*/
struct elf32_rel {
/** Offset in the section to perform a relocation */
elf32_addr r_offset;
/** Information about the relocation, related symbol and type */
elf32_word r_info;
};
/**
* @brief Relocation entry for 32-bit ELFs with addend.
*
* This structure stores information describing a relocation to be performed.
*/
struct elf32_rela {
/** Offset in the section to perform a relocation */
elf32_addr r_offset;
/** Information about the relocation, related symbol and type */
elf32_word r_info;
/** Offset to be applied to the symbol address */
elf32_sword r_addend;
};
@ -331,18 +348,30 @@ struct elf32_rela {
#define ELF32_R_TYPE(i) ((i) & 0xff)
/**
* @brief Relocation entry for 64-bit ELFs
* @brief Relocation entry for 64-bit ELFs.
*
* This structure stores information describing a relocation to be performed.
* Additional information about the relocation is stored at the location
* pointed to by @ref r_offset.
*/
struct elf64_rel {
/** Offset in section to perform a relocation */
/** Offset in the section to perform a relocation */
elf64_addr r_offset;
/** Information about relocation, related symbol and type */
/** Information about the relocation, related symbol and type */
elf64_xword r_info;
};
/**
* @brief Relocation entry for 64-bit ELFs with addend.
*
* This structure stores information describing a relocation to be performed.
*/
struct elf64_rela {
/** Offset in the section to perform a relocation */
elf64_addr r_offset;
/** Information about the relocation, related symbol and type */
elf64_xword r_info;
/** Offset to be applied to the symbol address */
elf64_sxword r_addend;
};
@ -359,6 +388,10 @@ struct elf64_rela {
*/
#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
/**
* Relocation names (should be moved to arch-specific files)
* @cond ignore
*/
#define R_386_NONE 0
#define R_386_32 1
#define R_386_PC32 2
@ -401,33 +434,39 @@ struct elf64_rela {
#define R_XTENSA_NONE 0
#define R_XTENSA_32 1
#define R_XTENSA_SLOT0_OP 20
/** @endcond */
/**
* Dynamic features currently not used by LLEXT
* @cond ignore
*/
/**
* @brief Program header(32-bit)
*/
struct elf32_phdr {
elf32_word p_type;
elf32_off p_offset;
elf32_addr p_vaddr;
elf32_addr p_paddr;
elf32_word p_filesz;
elf32_word p_memsz;
elf32_word p_flags;
elf32_word p_align;
elf32_word p_type; /**< Type of segment */
elf32_off p_offset; /**< Offset in file */
elf32_addr p_vaddr; /**< Virtual address in memory */
elf32_addr p_paddr; /**< Physical address (usually reserved) */
elf32_word p_filesz; /**< Size of segment in file */
elf32_word p_memsz; /**< Size of segment in memory */
elf32_word p_flags; /**< Segment flags */
elf32_word p_align; /**< Alignment of segment */
};
/**
* @brief Program header(64-bit)
*/
struct elf64_phdr {
elf64_word p_type;
elf64_off p_offset;
elf64_addr p_vaddr;
elf64_addr p_paddr;
elf64_xword p_filesz;
elf64_xword p_memsz;
elf64_word p_flags;
elf64_xword p_align;
elf64_word p_type; /**< Type of segment */
elf64_off p_offset; /**< Offset in file */
elf64_addr p_vaddr; /**< Virtual address in memory */
elf64_addr p_paddr; /**< Physical address (usually reserved) */
elf64_xword p_filesz; /**< Size of segment in file */
elf64_xword p_memsz; /**< Size of segment in memory */
elf64_word p_flags; /**< Segment flags */
elf64_xword p_align; /**< Alignment of segment */
};
/**
@ -439,10 +478,10 @@ struct elf64_phdr {
* @brief Dynamic section entry(32-bit)
*/
struct elf32_dyn {
elf32_sword d_tag;
elf32_sword d_tag; /**< Entry tag */
union {
elf32_word d_val;
elf32_addr d_ptr;
elf32_word d_val; /**< Integer value */
elf32_addr d_ptr; /**< Address value */
} d_un;
};
@ -450,12 +489,13 @@ struct elf32_dyn {
* @brief Dynamic section entry(64-bit)
*/
struct elf64_dyn {
elf64_sxword d_tag;
elf64_sxword d_tag; /**< Entry tag */
union {
elf64_xword d_val;
elf64_addr d_ptr;
elf64_xword d_val; /**< Integer value */
elf64_addr d_ptr; /**< Address value */
} d_un;
};
/** @endcond */
#if defined(CONFIG_64BIT) || defined(__DOXYGEN__)
/** Machine sized elf header structure */
@ -472,6 +512,7 @@ typedef elf64_half elf_half;
typedef elf64_xword elf_word;
/** Machine sized relocation struct */
typedef struct elf64_rel elf_rel_t;
/** Machine sized relocation struct with addend */
typedef struct elf64_rela elf_rela_t;
/** Machine sized symbol struct */
typedef struct elf64_sym elf_sym_t;
@ -498,6 +539,7 @@ typedef elf32_half elf_half;
typedef elf32_word elf_word;
/** Machine sized relocation struct */
typedef struct elf32_rel elf_rel_t;
/** Machine sized relocation struct with addend */
typedef struct elf32_rela elf_rela_t;
/** Machine sized symbol struct */
typedef struct elf32_sym elf_sym_t;

View file

@ -20,8 +20,13 @@ extern "C" {
#endif
/**
* @brief Linkable loadable extensions
* @defgroup llext Linkable loadable extensions
* @file
* @brief Support for linkable loadable extensions
*
* This file describes the APIs for loading and interacting with Linkable
* Loadable Extensions (LLEXTs) in Zephyr.
*
* @defgroup llext_apis Linkable loadable extensions
* @since 3.5
* @version 0.1.0
* @ingroup os_services
@ -29,27 +34,39 @@ extern "C" {
*/
/**
* @brief List of ELF regions that are stored or referenced in the llext
* @brief List of memory regions stored or referenced in the LLEXT subsystem
*
* This enum lists the different types of memory regions that are used by the
* LLEXT subsystem. The names match common ELF file section names; but note
* that at load time multiple ELF sections with similar flags may be merged
* together into a single memory region.
*/
enum llext_mem {
LLEXT_MEM_TEXT,
LLEXT_MEM_DATA,
LLEXT_MEM_RODATA,
LLEXT_MEM_BSS,
LLEXT_MEM_EXPORT,
LLEXT_MEM_SYMTAB,
LLEXT_MEM_STRTAB,
LLEXT_MEM_SHSTRTAB,
LLEXT_MEM_TEXT, /**< Executable code */
LLEXT_MEM_DATA, /**< Initialized data */
LLEXT_MEM_RODATA, /**< Read-only data */
LLEXT_MEM_BSS, /**< Uninitialized data */
LLEXT_MEM_EXPORT, /**< Exported symbol table */
LLEXT_MEM_SYMTAB, /**< Symbol table */
LLEXT_MEM_STRTAB, /**< Symbol name strings */
LLEXT_MEM_SHSTRTAB, /**< Section name strings */
LLEXT_MEM_COUNT,
LLEXT_MEM_COUNT, /**< Number of regions managed by LLEXT */
};
/** @cond ignore */
/* Number of memory partitions used by LLEXT */
#define LLEXT_MEM_PARTITIONS (LLEXT_MEM_BSS+1)
struct llext_loader;
/** @endcond */
/**
* @brief Linkable loadable extension
* @brief Structure describing a linkable loadable extension
*
* This structure holds the data for a loaded extension. It is created by the
* @ref llext_load function and destroyed by the @ref llext_unload function.
*/
struct llext {
/** @cond ignore */
@ -65,90 +82,90 @@ struct llext {
/** Name of the llext */
char name[16];
/** Lookup table of llext memory regions */
/** Lookup table of memory regions */
void *mem[LLEXT_MEM_COUNT];
/** Is the memory for this section allocated on heap? */
/** Is the memory for this region allocated on heap? */
bool mem_on_heap[LLEXT_MEM_COUNT];
/** Size of each stored section */
/** Size of each stored region */
size_t mem_size[LLEXT_MEM_COUNT];
/** Total llext allocation size */
size_t alloc_size;
/*
* These are all global symbols in the extension, all of them don't
* have to be exported to other extensions, but this table is needed for
* faster internal linking, e.g. if the extension is built out of
/**
* Table of all global symbols in the extension; used internally as
* part of the linking process. E.g. if the extension is built out of
* several files, if any symbols are referenced between files, this
* table will be used to link them.
*/
struct llext_symtable sym_tab;
/** Exported symbols from the llext, may be linked against by other llext */
/**
* Table of symbols exported by the llext via @ref LL_EXTENSION_SYMBOL.
* This can be used in the main Zephyr binary to find symbols in the
* extension.
*/
struct llext_symtable exp_tab;
/** Extension use counter, prevents unloading while in use */
unsigned int use_count;
};
/**
* @brief Advanced llext_load parameters
*
* This structure contains advanced parameters for @ref llext_load.
*/
struct llext_load_param {
/** Perform local relocation */
bool relocate_local;
/**
* Use the virtual symbol addresses from the ELF, not addresses within
* the memory buffer, when calculating relocation targets.
*/
bool pre_located;
};
/** Default initializer for @ref llext_load_param */
#define LLEXT_LOAD_PARAM_DEFAULT { .relocate_local = true, }
/**
* @brief Find an llext by name
*
* @param[in] name String name of the llext
* @retval NULL if no llext not found
* @retval llext if llext found
* @returns a pointer to the @ref llext, or `NULL` if not found
*/
struct llext *llext_by_name(const char *name);
/**
* @brief Iterate overall registered llext instances
* @brief Iterate over all loaded extensions
*
* Calls a provided callback function for each registered extension or until the
* callback function returns a non-0 value.
*
* @param[in] fn callback function
* @param[in] arg a private argument to be provided to the callback function
* @returns the value returned by the last callback invocation
* @retval 0 if no extensions are registered
* @retval value returned by the most recent callback invocation
*/
int llext_iterate(int (*fn)(struct llext *ext, void *arg), void *arg);
/**
* @brief llext loader parameters
*
* These are parameters, not saved in the permanent llext context, needed only
* for the loader
*/
struct llext_load_param {
/** Should local relocation be performed */
bool relocate_local;
/**
* Use the virtual symbol addresses from the ELF, not addresses within
* the memory buffer, where the object is loaded
*/
bool pre_located;
};
#define LLEXT_LOAD_PARAM_DEFAULT {.relocate_local = true,}
/**
* @brief Load and link an extension
*
* Loads relevant ELF data into memory and provides a structure to work with it.
*
* Only relocatable ELF files are currently supported (partially linked).
*
* @param[in] loader An extension loader that provides input data and context
* @param[in] name A string identifier for the extension
* @param[out] ext This will hold the pointer to the llext struct
* @param[in] ldr_parm Loader parameters
* @param[out] ext Pointer to the newly allocated @ref llext structure
* @param[in] ldr_parm Optional advanced load parameters (may be `NULL`)
*
* @retval 0 Success
* @retval > 0 extension use count
* @returns the previous extension use count on success, or a negative error code.
* @retval -ENOMEM Not enough memory
* @retval -EINVAL Invalid ELF stream
* @retval -ENOEXEC Invalid ELF stream
* @retval -ENOTSUP Unsupported ELF features
*/
int llext_load(struct llext_loader *loader, const char *name, struct llext **ext,
struct llext_load_param *ldr_parm);
@ -161,69 +178,77 @@ int llext_load(struct llext_loader *loader, const char *name, struct llext **ext
int llext_unload(struct llext **ext);
/**
* @brief Find the address for an arbitrary symbol name.
* @brief Find the address for an arbitrary symbol.
*
* @param[in] sym_table Symbol table to lookup symbol in, if NULL uses base table
* Searches for a symbol address, either in the list of symbols exported by
* the main Zephyr binary or in an extension's symbol table.
*
* @param[in] sym_table Symbol table to lookup symbol in, or `NULL` to search
* in the main Zephyr symbol table
* @param[in] sym_name Symbol name to find
*
* @retval NULL if no symbol found
* @retval addr Address of symbol in memory if found
* @returns the address of symbol in memory, or `NULL` if not found
*/
const void *llext_find_sym(const struct llext_symtable *sym_table, const char *sym_name);
/**
* @brief Call a function by name
* @brief Call a function by name.
*
* Expects a symbol representing a void fn(void) style function exists
* Expects a symbol representing a `void fn(void)` style function exists
* and may be called.
*
* @param[in] ext Extension to call function in
* @param[in] sym_name Function name (exported symbol) in the extension
*
* @retval 0 success
* @retval -EINVAL invalid symbol name
* @retval 0 Success
* @retval -ENOENT Symbol name not found
*/
int llext_call_fn(struct llext *ext, const char *sym_name);
/**
* @brief Add the known memory partitions of the extension to a memory domain
* @brief Add an extension to a memory domain.
*
* Allows an extension to be executed in supervisor or user mode threads when
* memory protection hardware is enabled.
* Allows an extension to be executed in user mode threads when memory
* protection hardware is enabled by adding memory partitions covering the
* extension's memory regions to a memory domain.
*
* @param[in] ext Extension to add to a domain
* @param[in] domain Memory domain to add partitions to
*
* @retval 0 success
* @retval -errno error
* @returns 0 on success, or a negative error code.
* @retval -ENOSYS @kconfig{CONFIG_USERSPACE} is not enabled or supported
*/
int llext_add_domain(struct llext *ext, struct k_mem_domain *domain);
/**
* @brief Architecture specific function for updating op codes given a relocation
* @brief Architecture specific opcode update function
*
* Elf files contain a series of relocations described in a section. These relocation
* instructions are architecture specific and each architecture supporting extensions
* must implement this. They are instructions on how to rewrite opcodes given
* the actual placement of some symbolic data such as a section, function,
* or object.
* ELF files include sections describing a series of _relocations_, which are
* instructions on how to rewrite opcodes given the actual placement of some
* symbolic data such as a section, function, or object. These relocations
* are architecture specific and each architecture supporting LLEXT must
* implement this.
*
* @param[in] rel Relocation data provided by elf
* @param[in] loc Address of operation to rewrite with relocation
* @param[in] sym_base_addr Symbol address
* @param[in] sym_name Symbol name
* @param[in] load_bias .text load address
* @retval 0 success
* @retval -ENOEXEC invalid relocation
* @param[in] rel Relocation data provided by ELF
* @param[in] loc Address of opcode to rewrite
* @param[in] sym_base_addr Address of symbol referenced by relocation
* @param[in] sym_name Name of symbol referenced by relocation
* @param[in] load_bias `.text` load address
* @retval 0 Success
* @retval -ENOTSUP Unsupported relocation
* @retval -ENOEXEC Invalid relocation
*/
int arch_elf_relocate(elf_rela_t *rel, uintptr_t loc,
uintptr_t sym_base_addr, const char *sym_name, uintptr_t load_bias);
/**
* @brief Find an ELF section
* @brief Locates an ELF section in the file.
*
* Searches for a section by name in the ELF file and returns its offset.
*
* @param loader Extension loader data and context
* @param search_name Section name to search for
* @retval Section offset or a negative error code
* @returns the section offset or a negative error code
*/
ssize_t llext_find_section(struct llext_loader *loader, const char *search_name);

View file

@ -15,9 +15,14 @@ extern "C" {
#endif
/**
* @brief Loader context for llext
* @defgroup llext_loader Loader context for llext
* @ingroup llext
* @file
* @brief LLEXT ELF loader context types.
*
* The following types are used to define the context of the ELF loader
* used by the \ref llext subsystem.
*
* @defgroup llext_loader_apis ELF loader context
* @ingroup llext_apis
* @{
*/
@ -29,10 +34,14 @@ struct llext_elf_sect_map; /* defined in llext_priv.h */
/**
* @brief Linkable loadable extension loader context
*
* This object is used to access the ELF file data and cache its contents
* while an extension is being loaded by the LLEXT subsystem. Once the
* extension is loaded, this object is no longer needed.
*/
struct llext_loader {
/**
* @brief Read (copy) from the loader
* @brief Function to read (copy) from the loader
*
* Copies len bytes into buf from the current position of the
* loader.
@ -41,13 +50,12 @@ struct llext_loader {
* @param[in] out Output location
* @param[in] len Length to copy into the output location
*
* @retval 0 Success
* @retval -errno Error reading (any errno)
* @returns 0 on success, or a negative error code.
*/
int (*read)(struct llext_loader *ldr, void *out, size_t len);
/**
* @brief Seek to a new absolute location
* @brief Function to seek to a new absolute location in the stream.
*
* Changes the location of the loader position to a new absolute
* given position.
@ -55,20 +63,19 @@ struct llext_loader {
* @param[in] ldr Loader
* @param[in] pos Position in stream to move loader
*
* @retval 0 Success
* @retval -errno Error reading (any errno)
* @returns 0 on success, or a negative error code.
*/
int (*seek)(struct llext_loader *ldr, size_t pos);
/**
* @brief Peek at an absolute location
* @brief Optional function to peek at an absolute location in the ELF.
*
* Return a pointer to the buffer at specified offset.
*
* @param[in] ldr Loader
* @param[in] pos Position to obtain a pointer to
*
* @retval pointer into the buffer
* @returns a pointer into the buffer or `NULL` if not supported
*/
void *(*peek)(struct llext_loader *ldr, size_t pos);
@ -82,6 +89,7 @@ struct llext_loader {
/** @endcond */
};
/** @cond ignore */
static inline int llext_read(struct llext_loader *l, void *buf, size_t len)
{
return l->read(l, buf, len);
@ -100,6 +108,7 @@ static inline void *llext_peek(struct llext_loader *l, size_t pos)
return NULL;
}
/* @endcond */
/**
* @}

View file

@ -15,10 +15,17 @@
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Linkable loadable extension symbol
* @defgroup llext_symbols LLEXT symbols
* @ingroup llext
* @file
* @brief Linkable loadable extension symbol definitions
*
* This file provides a set of macros and structures for defining and exporting
* symbols from the base image to extensions and vice versa, so that proper
* linking can be done between the two entities.
*
* @defgroup llext_symbols Exported symbol definitions
* @ingroup llext_apis
* @{
*/

View file

@ -37,8 +37,8 @@ __weak void arch_elf_relocate_local(struct llext_loader *ldr, struct llext *ext,
}
/*
* Find the section containing the supplied offset and return file offset for
* that value
* Find the memory region containing the supplied offset and return the
* corresponding file offset
*/
static size_t llext_file_offset(struct llext_loader *ldr, size_t offset)
{
@ -353,7 +353,7 @@ int llext_link(struct llext_loader *ldr, struct llext *ext, bool do_local)
}
#ifdef CONFIG_CACHE_MANAGEMENT
/* Make sure changes to ext sections are flushed to RAM */
/* Make sure changes to memory regions are flushed to RAM */
for (i = 0; i < LLEXT_MEM_COUNT; ++i) {
if (ext->mem[i]) {
sys_cache_data_flush_range(ext->mem[i], ext->mem_size[i]);

View file

@ -195,7 +195,8 @@ static int llext_find_tables(struct llext_loader *ldr)
}
/*
* Maps the section indexes and copies special section headers for easier use
* Maps the ELF sections into regions according to their usage flags,
* calculating ldr->sects and ldr->sect_map.
*/
static int llext_map_sections(struct llext_loader *ldr, struct llext *ext)
{
@ -251,7 +252,7 @@ static int llext_map_sections(struct llext_loader *ldr, struct llext *ext)
*/
memcpy(region, shdr, sizeof(*region));
} else {
/* Make sure the sections are compatible before merging */
/* Make sure this section is compatible with the region */
if (shdr->sh_flags != region->sh_flags) {
LOG_ERR("Unsupported section flags for %s (region %d)",
name, mem_idx);
@ -269,9 +270,10 @@ static int llext_map_sections(struct llext_loader *ldr, struct llext *ext)
}
if (ldr->hdr.e_type == ET_DYN) {
/* In shared objects, sh_addr is the VMA. Before
* merging these sections, make sure the delta
* in VMAs matches that of file offsets.
/* In shared objects, sh_addr is the VMA.
* Before merging this section in the region,
* make sure the delta in VMAs matches that of
* file offsets.
*/
if (shdr->sh_addr - region->sh_addr !=
shdr->sh_offset - region->sh_offset) {
@ -282,7 +284,7 @@ static int llext_map_sections(struct llext_loader *ldr, struct llext *ext)
}
/*
* Extend the current section to include the new one
* Extend the current region to include the new section
* (overlaps are detected later)
*/
size_t address = MIN(region->sh_addr, shdr->sh_addr);
@ -297,7 +299,7 @@ static int llext_map_sections(struct llext_loader *ldr, struct llext *ext)
}
/*
* Test that no computed range overlaps. This can happen if sections of
* Test that no computed region overlaps. This can happen if sections of
* different llext_mem type are interleaved in the ELF file or in VMAs.
*/
for (i = 0; i < LLEXT_MEM_COUNT; i++) {
@ -307,7 +309,7 @@ static int llext_map_sections(struct llext_loader *ldr, struct llext *ext)
if (x->sh_type == SHT_NULL || x->sh_size == 0 ||
y->sh_type == SHT_NULL || y->sh_size == 0) {
/* Skip empty sections */
/* Skip empty regions */
continue;
}
@ -350,8 +352,8 @@ static int llext_map_sections(struct llext_loader *ldr, struct llext *ext)
}
/*
* Calculate each ELF section's offset inside its memory area. This is
* done as a separate pass so the final groups are already defined.
* Calculate each ELF section's offset inside its memory region. This
* is done as a separate pass so the final regions are already defined.
*/
for (i = 0; i < ldr->sect_cnt; ++i) {
elf_shdr_t *shdr = ldr->sect_hdrs + i;
@ -657,7 +659,7 @@ out:
/* Since the loading process failed, free the resources that
* were allocated for the lifetime of the extension as well,
* such as section data and exported symbols.
* such as regions and exported symbols.
*/
llext_free_regions(ext);
llext_free(ext->exp_tab.syms);

View file

@ -28,7 +28,7 @@ LOG_MODULE_DECLARE(llext, CONFIG_LLEXT_LOG_LEVEL);
K_HEAP_DEFINE(llext_heap, CONFIG_LLEXT_HEAP_SIZE * 1024);
/*
* Initialize the memory partition associated with the extension memory
* Initialize the memory partition associated with the specified memory region
*/
static void llext_init_mem_part(struct llext *ext, enum llext_mem mem_idx,
uintptr_t start, size_t len)
@ -70,6 +70,7 @@ static int llext_copy_section(struct llext_loader *ldr, struct llext *ext,
if (ldr->sects[mem_idx].sh_type != SHT_NOBITS &&
IS_ENABLED(CONFIG_LLEXT_STORAGE_WRITABLE)) {
/* Directly use data from the ELF buffer if peek() is supported */
ext->mem[mem_idx] = llext_peek(ldr, ldr->sects[mem_idx].sh_offset);
if (ext->mem[mem_idx]) {
llext_init_mem_part(ext, mem_idx, (uintptr_t)ext->mem[mem_idx],