llext: basic x86 support
Adds basic x86 support for LLEXT. Signed-off-by: Lauren Murphy <lauren.murphy@intel.com>
This commit is contained in:
parent
9941902e2c
commit
7bbe425fe4
@ -27,6 +27,8 @@ zephyr_library_sources_ifdef(CONFIG_X86_VERY_EARLY_CONSOLE early_serial.c)
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE tls.c)
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_LLEXT elf.c)
|
||||
|
||||
if(CONFIG_X86_64)
|
||||
include(intel64.cmake)
|
||||
else()
|
||||
|
||||
142
arch/x86/core/elf.c
Normal file
142
arch/x86/core/elf.c
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/llext/elf.h>
|
||||
#include <zephyr/llext/llext.h>
|
||||
#include <zephyr/llext/llext_internal.h>
|
||||
#include <zephyr/llext/loader.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
LOG_MODULE_REGISTER(elf, CONFIG_LLEXT_LOG_LEVEL);
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
#define R_X86_64_64 1
|
||||
#define R_X86_64_PC32 2
|
||||
#define R_X86_64_PLT32 4
|
||||
#define R_X86_64_32 10
|
||||
#define R_X86_64_32S 11
|
||||
|
||||
/**
|
||||
* @brief Architecture specific function for relocating shared elf
|
||||
*
|
||||
* Elf files contain a series of relocations described in multiple sections.
|
||||
* These relocation instructions are architecture specific and each architecture
|
||||
* supporting modules must implement this.
|
||||
*
|
||||
* The relocation codes are well documented:
|
||||
*
|
||||
* https://refspecs.linuxfoundation.org/elf/x86_64-abi-0.95.pdf (intel64)
|
||||
*/
|
||||
int arch_elf_relocate(struct llext_loader *ldr, struct llext *ext, elf_rela_t *rel,
|
||||
const elf_shdr_t *shdr)
|
||||
{
|
||||
int ret = 0;
|
||||
const uintptr_t loc = llext_get_reloc_instruction_location(ldr, ext, shdr->sh_info, rel);
|
||||
elf_sym_t sym;
|
||||
uintptr_t sym_base_addr;
|
||||
const char *sym_name;
|
||||
|
||||
ret = llext_read_symbol(ldr, ext, rel, &sym);
|
||||
|
||||
if (ret != 0) {
|
||||
LOG_ERR("Could not read symbol from binary!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
sym_name = llext_symbol_name(ldr, ext, &sym);
|
||||
|
||||
ret = llext_lookup_symbol(ldr, ext, &sym_base_addr, rel, &sym, sym_name, shdr);
|
||||
|
||||
if (ret != 0) {
|
||||
LOG_ERR("Could not find symbol %s!", sym_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sym_base_addr += rel->r_addend;
|
||||
|
||||
int reloc_type = ELF32_R_TYPE(rel->r_info);
|
||||
|
||||
switch (reloc_type) {
|
||||
case R_X86_64_PC32:
|
||||
case R_X86_64_PLT32:
|
||||
*(uint32_t *)loc = sym_base_addr - loc;
|
||||
break;
|
||||
case R_X86_64_64:
|
||||
case R_X86_64_32:
|
||||
case R_X86_64_32S:
|
||||
*(uint32_t *)loc = sym_base_addr;
|
||||
break;
|
||||
default:
|
||||
LOG_ERR("unknown relocation: %u\n", reloc_type);
|
||||
ret = -ENOEXEC;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#define R_386_32 1
|
||||
#define R_286_PC32 2
|
||||
|
||||
/**
|
||||
* @brief Architecture specific function for relocating shared elf
|
||||
*
|
||||
* Elf files contain a series of relocations described in multiple sections.
|
||||
* These relocation instructions are architecture specific and each architecture
|
||||
* supporting modules must implement this.
|
||||
*
|
||||
* The relocation codes are well documented:
|
||||
*
|
||||
* https://docs.oracle.com/cd/E19683-01/817-3677/chapter6-26/index.html (ia32)
|
||||
*/
|
||||
int arch_elf_relocate(struct llext_loader *ldr, struct llext *ext, elf_rela_t *rel,
|
||||
const elf_shdr_t *shdr)
|
||||
{
|
||||
int ret = 0;
|
||||
const uintptr_t loc = llext_get_reloc_instruction_location(ldr, ext, shdr->sh_info, rel);
|
||||
elf_sym_t sym;
|
||||
uintptr_t sym_base_addr;
|
||||
const char *sym_name;
|
||||
|
||||
/* x86 uses elf_rel_t records with no addends */
|
||||
uintptr_t addend = *(uintptr_t *)loc;
|
||||
|
||||
ret = llext_read_symbol(ldr, ext, rel, &sym);
|
||||
|
||||
if (ret != 0) {
|
||||
LOG_ERR("Could not read symbol from binary!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
sym_name = llext_symbol_name(ldr, ext, &sym);
|
||||
|
||||
ret = llext_lookup_symbol(ldr, ext, &sym_base_addr, rel, &sym, sym_name, shdr);
|
||||
|
||||
if (ret != 0) {
|
||||
LOG_ERR("Could not find symbol %s!", sym_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sym_base_addr += addend;
|
||||
|
||||
int reloc_type = ELF32_R_TYPE(rel->r_info);
|
||||
|
||||
switch (reloc_type) {
|
||||
case R_386_32:
|
||||
*(uint32_t *)loc = sym_base_addr;
|
||||
break;
|
||||
case R_286_PC32:
|
||||
*(uint32_t *)loc = sym_base_addr - loc;
|
||||
break;
|
||||
default:
|
||||
LOG_ERR("unknown relocation: %u\n", reloc_type);
|
||||
ret = -ENOEXEC;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
@ -15,6 +15,28 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Flags not supported by llext linker
|
||||
# (regexps are supported and match whole word)
|
||||
set(LLEXT_REMOVE_FLAGS
|
||||
-fno-pic
|
||||
-fno-pie
|
||||
-ffunction-sections
|
||||
-fdata-sections
|
||||
-g.*
|
||||
-Os
|
||||
)
|
||||
|
||||
# Force compiler and linker match
|
||||
if(CONFIG_X86_64)
|
||||
set(LLEXT_APPEND_FLAGS
|
||||
-m64
|
||||
)
|
||||
else()
|
||||
set(LLEXT_APPEND_FLAGS
|
||||
-m32
|
||||
)
|
||||
endif()
|
||||
|
||||
# GNU Assembler, by default on non-Linux targets, treats slashes as
|
||||
# start of comments on i386.
|
||||
# (https://sourceware.org/binutils/docs-2.33.1/as/i386_002dChars.html#i386_002dChars)
|
||||
|
||||
@ -389,7 +389,7 @@ static void llext_link_plt(struct llext_loader *ldr, struct llext *ext, elf_shdr
|
||||
int llext_link(struct llext_loader *ldr, struct llext *ext, const struct llext_load_param *ldr_parm)
|
||||
{
|
||||
uintptr_t sect_base = 0;
|
||||
elf_rela_t rel;
|
||||
elf_rela_t rel = {0};
|
||||
elf_word rel_cnt = 0;
|
||||
const char *name;
|
||||
int i, ret;
|
||||
|
||||
@ -7,3 +7,4 @@ CONFIG_ARM_MPU=n
|
||||
CONFIG_ARM_AARCH32_MMU=n
|
||||
CONFIG_RISCV_PMP=n
|
||||
CONFIG_ARC_MPU_ENABLE=n
|
||||
CONFIG_X86_MMU=n
|
||||
|
||||
@ -8,12 +8,25 @@
|
||||
* This code demonstrates syscall support.
|
||||
*/
|
||||
|
||||
/* This include directive must appear first in the file.
|
||||
*
|
||||
* On x86 platforms with demand paging on, Zephyr generates a
|
||||
* .pinned_text section containing syscalls. The LLEXT loader
|
||||
* requires .text-like sections to appear close to .text at the
|
||||
* start of the object file, before .rodata, so they can be
|
||||
* grouped into a contiguous text region.
|
||||
*
|
||||
* Including syscalls_ext.h first ensures the first instance of
|
||||
* data to be placed in .pinned_text appears before the first instance
|
||||
* of data for .rodata. As a result, .pinned_text will appear
|
||||
* before .rodata.
|
||||
*/
|
||||
#include "syscalls_ext.h"
|
||||
|
||||
#include <zephyr/llext/symbol.h>
|
||||
#include <zephyr/sys/printk.h>
|
||||
#include <zephyr/ztest_assert.h>
|
||||
|
||||
#include "syscalls_ext.h"
|
||||
|
||||
void test_entry(void)
|
||||
{
|
||||
int input = 41;
|
||||
|
||||
@ -39,6 +39,7 @@ tests:
|
||||
- arm
|
||||
- riscv
|
||||
- arc
|
||||
- x86
|
||||
filter: not CONFIG_MPU and not CONFIG_MMU
|
||||
extra_conf_files: ['no_mem_protection.conf']
|
||||
extra_configs:
|
||||
@ -56,6 +57,7 @@ tests:
|
||||
- arm64
|
||||
- arm
|
||||
- riscv
|
||||
- x86
|
||||
filter: CONFIG_MMU or CONFIG_RISCV_PMP
|
||||
integration_platforms:
|
||||
- qemu_cortex_a53 # ARM Cortex-A53 (ARMv8-A ISA)
|
||||
@ -68,6 +70,7 @@ tests:
|
||||
- xtensa
|
||||
- riscv
|
||||
- arc
|
||||
- x86
|
||||
integration_platforms:
|
||||
- qemu_xtensa/dc233c # Xtensa ISA
|
||||
filter: not CONFIG_MPU and not CONFIG_MMU
|
||||
@ -80,6 +83,7 @@ tests:
|
||||
- xtensa
|
||||
- riscv
|
||||
- arc
|
||||
- x86
|
||||
platform_exclude:
|
||||
- qemu_arc/qemu_arc_hs5x # See #80949
|
||||
- nsim/nsim_hs5x # See #80949
|
||||
@ -101,6 +105,7 @@ tests:
|
||||
- xtensa
|
||||
- riscv
|
||||
- arc
|
||||
- x86
|
||||
integration_platforms:
|
||||
- qemu_xtensa/dc233c # Xtensa ISA
|
||||
filter: not CONFIG_MPU and not CONFIG_MMU
|
||||
@ -114,6 +119,7 @@ tests:
|
||||
- xtensa
|
||||
- riscv
|
||||
- arc
|
||||
- x86
|
||||
platform_exclude:
|
||||
- qemu_arc/qemu_arc_hs5x # See #80949
|
||||
- nsim/nsim_hs5x # See #80949
|
||||
|
||||
Loading…
Reference in New Issue
Block a user