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

LLEXT: support detached sections #79012

Merged
merged 5 commits into from
Sep 29, 2024

Conversation

lyakh
Copy link
Collaborator

@lyakh lyakh commented Sep 25, 2024

SOF loads LLEXT objects into slower IMR memory but they're partially pre-linked for SRAM, where objects will be copied to after linking by LLEXT core. But some sections should not be copied to SRAM and be used in IMR directly. This PR adds support for such sections.

@zephyrbot zephyrbot added area: llext Linkable Loadable Extensions area: Xtensa Xtensa Architecture labels Sep 25, 2024
teburd
teburd previously approved these changes Sep 25, 2024
Copy link
Collaborator

@pillo79 pillo79 left a comment

Choose a reason for hiding this comment

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

IMO some parts of this are very project specific. To improve this situation, I would suggest to pass the struct llext_load_params around, instead of expanding its fields, and add more fields and/or callbacks to that.

@@ -139,6 +139,7 @@ struct llext_load_param {

/** Default initializer for @ref llext_load_param */
#define LLEXT_LOAD_PARAM_DEFAULT { .relocate_local = true, }
const void *llext_loaded_sect_ptr(struct llext_loader *ldr, struct llext *ext, unsigned int sh_ndx);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I understand this was done to access this from code in arch/. That is fine, but please move this to a new llext_internal.h file in this folder, so it's explicitly not part of the public API.

Comment on lines 296 to 297
if (pre_located && shdr->sh_addr < LLEXT_SECTION_MIN_ADDR) {
continue;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do addresses below a certain value get ignored?
I think this is very project-specific. Should we have callback functions to provide this kind of customizations?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

this is basically a NULL area. I use 0 as a base for sections without pre-defined run-time location, but since there can be several such sections, some of them get other low addresses

const char *s_name = llext_string(ldr, ext, LLEXT_MEM_SHSTRTAB,
shdr->sh_name);

if (pre_located && section_addr >= LLEXT_SECTION_MIN_ADDR) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This also feels specific - although maybe a per-section flag could work (I assume they are the sections not ignored by the above check).

@@ -36,8 +36,21 @@ LOG_MODULE_DECLARE(llext, CONFIG_LLEXT_LOG_LEVEL);
* calls, taking into account if the load process was successful or not.
*/

#define LLEXT_SECTION_MIN_ADDR 0x10000
Copy link
Collaborator

@pillo79 pillo79 Sep 26, 2024

Choose a reason for hiding this comment

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

This hardcoded value is neither arch- nor even project- independent. If comparing addresses is required, then this must at least be customizable by the caller.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@pillo79 agree, yes, I was thinking about it too. Would it be ok for you to pass this as a value in struct llext_load_param? Otherwise we could add a platform callback to that structure to perform any testing and return true or false for whether the symbol is used where it's located or where it's linked for, but I think that would make it uglier, less transparent.

Copy link
Collaborator

@pillo79 pillo79 Sep 27, 2024

Choose a reason for hiding this comment

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

I personally see it as the opposite - it would neatly decouple the generic implementation from project-specific reasoning.
For example, I can already see places where I would add callbacks for:

  • "do we allocate a copy of a section?" <- would replace and extend STORAGE_WRITABLE, e.g. allow rodata from Flash
  • "how do we relocate a section?" <- would extend (or even replace!) pre_located and simplify the current PR
  • "what is the effective base address of this section?" <- would possibly replace link scripts and also be a first step for in-Flash XIP.

These would be entirely optional, at the app developer's discretion, to allow advanced users like SOF to customize the linking behavior while keeping the default unchanged.

Make llext_loaded_sect_ptr() a proper function to be able to call it
from platform LLEXT code.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
It's more common in the LLEXT code base to call elf_sym_t instances
"sym" and not "sym_tbl." Convert llext_link_plt() to follow this
convention.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
When building LLEXT for Xtensa with custom sections the compiler
can leave unresolved references in them. Then this has to be done by
the LLEXT core during linking. This commit adds linking support for
the L32R Xtensa instruction.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
To simplify LLEXT loader parameter extension pass the whole
struct llext_load_param to final consumers instead of extracting
individual fields from it in the caller function.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
Some LLEXT objects can include sections, that should not be merged
with other sections of the same type. E.g. when such sections should
be placed into locations, other than the default. Add support for
such sections.

Signed-off-by: Guennadi Liakhovetski <[email protected]>
Copy link
Collaborator

@pillo79 pillo79 left a comment

Choose a reason for hiding this comment

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

This looks awesome, and the basis for other improvements! Thanks!

@henrikbrixandersen henrikbrixandersen merged commit c6bf743 into zephyrproject-rtos:main Sep 29, 2024
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: llext Linkable Loadable Extensions area: Xtensa Xtensa Architecture
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants