Skip to content
Closed
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
56 changes: 45 additions & 11 deletions scripts/llext_link_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
# portable way to do that. Therefore we pass the linker path and all the command
# line parameters to this script and call the linker directly.

import os
import argparse
import subprocess
from elftools.elf.elffile import ELFFile
import re

args = None
def parse_args():
Expand All @@ -33,21 +35,53 @@ def main():
elf = ELFFile(open(args.file, 'rb'))

text_addr = int(args.text_addr, 0)
p = re.compile('(^lib|\.so$)')
module = p.sub('', args.file)

text_offset = elf.get_section_by_name('.text').header.sh_offset
rodata_offset = elf.get_section_by_name('.rodata').header.sh_offset
data_offset = elf.get_section_by_name('.data').header.sh_offset
if elf.get_section_by_name('.rodata') != None:
# A shared object type image, it contains segments
sections = ['.text', '.rodata', '.data', '.bss']
alignment = [0x1000, 0x1000, 0x10, 0x1000]
else:
# A relocatable object, need to handle all sections separately
sections = ['.text',
f'._log_const.static.log_const_{module}_',
'.static_uuids', '.z_init_APPLICATION90_0_', '.module',
'.mod_buildinfo', '.data', '.trace_ctx', '.bss']
alignment = [0x1000, 0x1000, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x1000]

upper = rodata_offset - text_offset + text_addr + 0xfff
rodata_addr = upper - (upper % 0x1000)
last_increment = 0

upper = data_offset - rodata_offset + rodata_addr + 0xf
data_addr = upper - (upper % 0x10)
command = [args.command]

for i in range(len(sections)):
try:
offset = elf.get_section_by_name(sections[i]).header.sh_offset
size = elf.get_section_by_name(sections[i]).header.sh_size
except:
continue

if last_increment == 0:
# first section must be .text and it must be successful
if i != 0 or sections[i] != '.text':
break

addresse = text_addr
elif alignment[i] != 0:
upper = offset + last_increment + alignment[i] - 1
addresse = upper - (upper % alignment[i])
else:
addresse = offset + last_increment

last_increment = addresse - offset

if sections[i] == '.text':
command.append(f'-Wl,-Ttext=0x{text_addr:x}')
elif sections[i] == '.data':
command.append(f'-Wl,-Tdata=0x{addresse:x}')
else:
command.append(f'-Wl,--section-start={sections[i]}=0x{addresse:x}')

command = [args.command,
f'-Wl,-Ttext=0x{text_addr:x}',
f'-Wl,--section-start=.rodata=0x{rodata_addr:x}',
f'-Wl,-Tdata=0x{data_addr:x}']
command.extend(args.params)

subprocess.run(command)
Expand Down
2 changes: 1 addition & 1 deletion src/library_manager/lib_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ static void lib_manager_update_sof_ctx(void *base_addr, uint32_t lib_id)
{
struct ext_library *_ext_lib = ext_lib_get();
/* Never freed, will panic if fails */
struct lib_manager_mod_ctx *ctx = rmalloc(SOF_MEM_ZONE_SYS, 0, SOF_MEM_CAPS_RAM,
struct lib_manager_mod_ctx *ctx = rzalloc(SOF_MEM_ZONE_SYS, 0, SOF_MEM_CAPS_RAM,
sizeof(*ctx));

ctx->base_addr = base_addr;
Expand Down
9 changes: 5 additions & 4 deletions src/library_manager/llext_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ static void __sparse_cache *llext_manager_get_bss_address(uint32_t module_id,
static int llext_manager_allocate_module_bss(uint32_t module_id,
const struct sof_man_module *mod)
{
/* FIXME: just map .bss together with .data and simply memset(.bss, 0) */
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
size_t bss_size = ctx->segment_size[SOF_MAN_SEGMENT_BSS];
void __sparse_cache *va_base = llext_manager_get_bss_address(module_id, mod);
Expand Down Expand Up @@ -170,13 +171,14 @@ static int llext_manager_link(struct sof_man_fw_desc *desc, struct sof_man_modul
uint32_t module_id, struct module_data *md, const void **buildinfo,
const struct sof_man_module_manifest **mod_manifest)
{
size_t mod_size = desc->header.preload_page_count * PAGE_SZ;
size_t mod_size = desc->header.preload_page_count * PAGE_SZ - 0x8000;
/* FIXME: where does the module begin?? */
struct llext_buf_loader ebl = LLEXT_BUF_LOADER((uint8_t *)desc -
SOF_MAN_ELF_TEXT_OFFSET + 0x8000,
mod_size);
struct llext_load_param ldr_parm = {false};
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
/* Identify if this is the first time loading this module */
struct llext_load_param ldr_parm = {!ctx->segment_size[SOF_MAN_SEGMENT_TEXT]};
int ret = llext_load(&ebl.loader, mod->name, &md->llext, &ldr_parm);

if (ret < 0)
Expand All @@ -199,8 +201,7 @@ static int llext_manager_link(struct sof_man_fw_desc *desc, struct sof_man_modul
mod->segment[SOF_MAN_SEGMENT_RODATA].file_offset =
(uintptr_t)md->llext->mem[LLEXT_MEM_RODATA] -
(uintptr_t)desc + SOF_MAN_ELF_TEXT_OFFSET;
ctx->segment_size[SOF_MAN_SEGMENT_RODATA] = mod_size -
ebl.loader.sects[LLEXT_MEM_TEXT].sh_size;
ctx->segment_size[SOF_MAN_SEGMENT_RODATA] = ebl.loader.prog_data_size;

tr_dbg(&lib_manager_tr, ".data: start: %#x size %#x offset %#x",
mod->segment[SOF_MAN_SEGMENT_RODATA].v_base_addr,
Expand Down
15 changes: 12 additions & 3 deletions src/samples/audio/smart_amp_llext/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,16 @@ target_compile_options(${MODULE} PRIVATE
-save-temps -O2
)

if("${ZEPHYR_TOOLCHAIN_VARIANT}" STREQUAL "zephyr")
set(MODULE_LINKER_PARAMS -nostdlib -nodefaultlibs)
set(EXTRA_LINKED_PARAMS -shared)
set(COPY_CMD ${CMAKE_STRIP} -R .xt.* -o ${MODULE}_out.so ${MODULE}_llext.so)
else()
set(MODULE_LINKER_PARAMS -nostdlib -nodefaultlibs -r)
set(EXTRA_LINKED_PARAMS)
set(COPY_CMD ${CMAKE_OBJCOPY} -R .xt.* ${MODULE}_llext.so ${MODULE}_out.so)
endif()

target_link_options(${MODULE} PRIVATE
${MODULE_LINKER_PARAMS}
)
Expand All @@ -62,9 +71,9 @@ add_custom_command(OUTPUT lib${MODULE}_out.so
DEPENDS ${MODULE}
COMMAND ${SOF_BASE}scripts/llext_link_helper.py
-f lib${MODULE}.so -t "0xa06ca000" ${CMAKE_C_COMPILER} --
${MODULE_LINKER_PARAMS} -shared -fPIC
-o lib${MODULE}_llext.so $<TARGET_OBJECTS:${MODULE}>
COMMAND ${CMAKE_STRIP} -R .xt.* -o lib${MODULE}_out.so lib${MODULE}_llext.so
${MODULE_LINKER_PARAMS} ${EXTRA_LINKED_PARAMS} -fPIC
-o ${MODULE}_llext.so $<TARGET_OBJECTS:${MODULE}>
COMMAND ${COPY_CMD}
COMMAND_EXPAND_LISTS
)

Expand Down
15 changes: 6 additions & 9 deletions tools/rimage/src/elf_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,15 +132,6 @@ static int elf_header_read(struct elf_file *elf)
if (elf->header.ehsize < sizeof(Elf32_Ehdr))
return elf_error(elf, "Invalid file header size.", EINVAL);

if (elf->header.phoff >= elf->file_size)
return elf_error(elf, "Invalid program header file offset.", EINVAL);

if (elf->header.phentsize < sizeof(Elf32_Phdr))
return elf_error(elf, "Invalid program header size.", EINVAL);

if (elf->header.phoff + elf->header.phnum * sizeof(Elf32_Phdr) > elf->file_size)
return elf_error(elf, "Invalid number of program header entries.", EINVAL);

if (elf->header.shoff >= elf->file_size)
return elf_error(elf, "Invalid section header file offset.", EINVAL);

Expand Down Expand Up @@ -250,6 +241,12 @@ static int elf_program_headers_read(struct elf_file *elf)
int i, ret;
size_t offset, count;

if (!elf->header.phnum) {
elf->programs = NULL;
elf->programs_count = 0;
return 0;
}

elf->programs = calloc(elf->header.phnum, sizeof(Elf32_Phdr));
if (!elf->programs)
return elf_error(elf, "Cannot allocate program array.", ENOMEM);
Expand Down
2 changes: 1 addition & 1 deletion west.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ manifest:

- name: zephyr
repo-path: zephyr
revision: 66b475a3aa4d73f4ddd5be5a7a1e0f3c7028e539
revision: pull/70793/head
remote: zephyrproject

# Import some projects listed in zephyr/west.yml@revision
Expand Down