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

cmake: add LATE_LINK to fix llext weak syscall definitions #79023

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

pillo79
Copy link
Collaborator

@pillo79 pillo79 commented Sep 25, 2024

Since 62b19ef LLEXT has gained the ability to export all syscalls automatically. The export is done for any syscall declared in the build, including those that are never actually defined - most commonly due to not enabling some Kconfig.
These undefined functions would normally cause a link error; the workaround has been to define, in an autogenerated file included by llext_export.c, weak implementations for all syscall symbols to the stock no_handler function, with the intention of providing a sensible default to link with.

However, during development I discovered that some of these symbols were actually defined in the final ELF as NULL. This has been traced to the llext_export.c file being included in the middle of the --whole-archive list, instead of at the end.

This PR adds a LATE_LINK property to Zephyr libraries (by default disabled). Libraries that have this feature enabled will be placed after all the ones that do not enable it in the linker command line; no other ordering is enforced between these two groups.

This feature is then used to split build the llext_exports.c file in its own separate library and move it to the end of the link list, fixing the symbol definition issue.

This patch adds a new property to Zephyr libraries called LATE_LINK.
When set to TRUE, the library will be linked after all other libraries
that are not marked "late".

Ordering between late libs is not guaranteed.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
The llext_export.c file defines weak symbols for any syscall; these are
intended to be overridden by the application if the implementation is
compiled in.  However, including this among all other libraries caused
the weak symbols to override the actual symbols defined in the following
libraries.

This commit moves the file to a separate library that is linked late to
prevent the weak symbols from overriding the actual symbols.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
@pillo79 pillo79 marked this pull request as ready for review September 26, 2024 06:54
@zephyrbot zephyrbot added area: Build System area: llext Linkable Loadable Extensions labels Sep 26, 2024
Copy link
Collaborator

@tejlmand tejlmand left a comment

Choose a reason for hiding this comment

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

to me this seems to add unneeded complexity to zephyr libraries.

Comment on lines +981 to +991
# Move the libraries that are supposed to be linked late in the link
# process to the end of their respective list.
foreach(zephyr_lib ${ZEPHYR_LATE_LIBS_PROPERTY})
if("${zephyr_lib}" IN_LIST WHOLE_ARCHIVE_LIBS)
list(REMOVE_ITEM WHOLE_ARCHIVE_LIBS ${zephyr_lib})
list(APPEND WHOLE_ARCHIVE_LIBS ${zephyr_lib})
elseif("${zephyr_lib}" IN_LIST NO_WHOLE_ARCHIVE_LIBS)
list(REMOVE_ITEM NO_WHOLE_ARCHIVE_LIBS ${zephyr_lib})
list(APPEND NO_WHOLE_ARCHIVE_LIBS ${zephyr_lib})
endif()
endforeach()
Copy link
Collaborator

Choose a reason for hiding this comment

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

let's not re-invent something already well handled by CMake.
Also this will become whac-a-mole in the future when order starts to matter and we then need to guarantee an order, ref:

Ordering between late libs is not guaranteed.

From the PR description, then I would like to ask, why is the llext-exports library a Zephyr library in the first place ?
From the looks of this PR then it seems to me that the llext-exports lib should be outside the --whole-archive and thus not be a Zephyr library.

Keeping the lib which needs this LATE LINKING control outside whole-archive allows to user regular target_link_libraries() to ensure correct link order.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Build System area: llext Linkable Loadable Extensions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants