Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Part 1 of #9013 #9024

Merged
merged 6 commits into from
Apr 16, 2024
Merged
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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this used in this commit?

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.num_segments() != 0:
# 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:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, just catch the exception you're expecting. Copy/paste its name from the stack trace, it should take seconds. Also, use pylint.

https://pylint.pycqa.org/en/latest/user_guide/messages/warning/broad-exception-caught.html

continue

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

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

last_increment = address - offset

if sections[i] == '.text':
command.append(f'-Wl,-Ttext=0x{text_addr:x}')
elif sections[i] == '.data':
command.append(f'-Wl,-Tdata=0x{address:x}')
else:
command.append(f'-Wl,--section-start={sections[i]}=0x{address: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;
Copy link
Collaborator

@marc-hb marc-hb Apr 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magic number. Needs at least a comment in the source.

/* 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")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a "FIXME: replace this hack with new add_llext_target() in 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