Linkable Loadable Extensions (LLEXT)

The llext subsystem provides a toolbox for extending the functionality of an application at runtime with linkable loadable code.

Extensions can be loaded from precompiled ELF formatted data which is verified, loaded, and linked with other extensions. Extensions can be manipulated and introspected to some degree, as well as unloaded when no longer needed.

An extension may be loaded using any implementation of a llext_loader which has a set of function pointers that provide the necessary functionality to read the ELF data. A loader also provides some minimal context (memory) needed by the llext_load() function. An implementation over a buffer containing an ELF in addressable memory in memory is available as llext_buf_loader.

API Reference

group llext

Linkable loadable extensions.

Enums

enum llext_mem

Enum of memory regions for lookup tables.

Values:

enumerator LLEXT_MEM_TEXT
enumerator LLEXT_MEM_DATA
enumerator LLEXT_MEM_RODATA
enumerator LLEXT_MEM_BSS
enumerator LLEXT_MEM_SYMTAB
enumerator LLEXT_MEM_STRTAB
enumerator LLEXT_MEM_SHSTRTAB
enumerator LLEXT_MEM_COUNT

Functions

sys_slist_t *llext_list(void)

List head of loaded extensions.

struct llext *llext_by_name(const char *name)

Find an llext by name.

Parameters:
  • name[in] String name of the llext

Return values:
  • NULL – if no llext not found

  • llext – if llext found

int llext_load(struct llext_loader *loader, const char *name, struct llext **ext)

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).

Parameters:
  • loader[in] An extension loader that provides input data and context

  • name[in] A string identifier for the extension

  • ext[out] A pointer to a statically allocated llext struct

Return values:
  • 0 – Success

  • -ENOMEM – Not enough memory

  • -EINVAL – Invalid ELF stream

void llext_unload(struct llext *ext)

Unload an extension.

Parameters:
  • ext[in] Extension to unload

const void *const llext_find_sym(const struct llext_symtable *sym_table, const char *sym_name)

Find the address for an arbitrary symbol name.

Parameters:
  • sym_table[in] Symbol table to lookup symbol in, if NULL uses base table

  • sym_name[in] Symbol name to find

Return values:
  • NULL – if no symbol found

  • addr – Address of symbol in memory if found

int llext_call_fn(struct llext *ext, const char *sym_name)

Call a function by name.

Expects a symbol representing a void fn(void) style function exists and may be called.

Parameters:
  • ext[in] Extension to call function in

  • sym_name[in] Function name (exported symbol) in the extension

Return values:
  • 0 – success

  • -EINVAL – invalid symbol name

void arch_elf_relocate(elf_rela_t *rel, uintptr_t opaddr, uintptr_t opval)

Architecture specific function for updating op codes given a relocation.

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.

Parameters:
  • rel[in] Relocation data provided by elf

  • opaddr[in] Address of operation to rewrite with relocation

  • opval[in] Value of looked up symbol to relocate

struct llext
#include <llext.h>

Linkable loadable extension.

Public Members

char name[16]

Name of the llext.

void *mem[LLEXT_MEM_COUNT]

Lookup table of llext memory regions.

bool mem_on_heap[LLEXT_MEM_COUNT]

Memory allocated on heap.

size_t mem_size

Total size of the llext memory usage.

struct llext_symtable sym_tab

Exported symbols from the llext, may be linked against by other llext.

group llext_symbols

Linkable loadable extension symbol.

Defines

EXPORT_SYMBOL(x)

Export a constant symbol to a table of symbols.

Takes a symbol (function or object) by symbolic name and adds the name and address of the symbol to a table of symbols that may be used for linking.

Parameters:
  • x – Symbol to export

EXPORT_SYSCALL(x)

Export a system call to a table of symbols.

Takes a system call name and uses EXPORT_SYMBOL() to export the respective function.

Parameters:
  • x – System call to export

struct llext_const_symbol
#include <symbol.h>

Constant symbols are unchangeable named memory addresses.

Symbols may be named function or global objects that have been exported for linking. These constant symbols are useful in the base image as they may be placed in ROM.

Public Members

const char *const name

Name of symbol.

const void *const addr

Address of symbol.

struct llext_symbol
#include <symbol.h>

Symbols are named memory addresses.

Symbols may be named function or global objects that have been exported for linking. These are mutable and should come from extensions where the location may need updating depending on where memory is placed.

Public Members

const char *name

Name of symbol.

void *addr

Address of symbol.

struct llext_symtable
#include <symbol.h>

A symbol table.

An array of symbols

Public Members

size_t sym_cnt

Number of symbols in the table.

struct llext_symbol *syms

Array of symbols.

group llext_loader

Loader context for llext.

Enums

enum llext_section

Enum of sections for lookup tables.

Values:

enumerator LLEXT_SECT_TEXT
enumerator LLEXT_SECT_DATA
enumerator LLEXT_SECT_RODATA
enumerator LLEXT_SECT_BSS
enumerator LLEXT_SECT_REL_TEXT
enumerator LLEXT_SECT_REL_DATA
enumerator LLEXT_SECT_REL_RODATA
enumerator LLEXT_SECT_REL_BSS
enumerator LLEXT_SECT_SYMTAB
enumerator LLEXT_SECT_STRTAB
enumerator LLEXT_SECT_SHSTRTAB
enumerator LLEXT_SECT_COUNT

Functions

static inline int llext_read(struct llext_loader *l, void *buf, size_t len)
static inline int llext_seek(struct llext_loader *l, size_t pos)
static inline void *llext_peek(struct llext_loader *l, size_t pos)
struct llext_loader
#include <loader.h>

Linkable loadable extension loader context.

Public Members

int (*read)(struct llext_loader *ldr, void *out, size_t len)

Read (copy) from the loader.

Copies len bytes into buf from the current position of the loader.

Param ldr:

[in] Loader

Param out:

[in] Output location

Param len:

[in] Length to copy into the output location

Retval 0:

Success

Retval -errno:

Error reading (any errno)

int (*seek)(struct llext_loader *ldr, size_t pos)

Seek to a new absolute location.

Changes the location of the loader position to a new absolute given position.

Param ldr:

[in] Loader

Param pos:

[in] Position in stream to move loader

Retval 0:

Success

Retval -errno:

Error reading (any errno)

void *(*peek)(struct llext_loader *ldr, size_t pos)

Peek at an absolute location.

Return a pointer to the buffer at specified offset.

Param ldr:

[in] Loader

Param pos:

[in] Position to obtain a pointer to

Retval pointer:

into the buffer

group llext_buf_loader

LLEXT buffer loader.

Defines

LLEXT_BUF_LOADER(_buf, _buf_len)

Initialize an extension buf loader.

Parameters:
  • _buf – Buffer containing an ELF binary

  • _buf_len – Buffer length in bytes

struct llext_buf_loader
#include <buf_loader.h>

An extension loader from a provided buffer containing an ELF.

Public Members

struct llext_loader loader

Extension loader.