Skip to content

Support alternative symbol resolving implementations for elf_loader (AEGHB-1243)#588

Open
KenVanHoeylandt wants to merge 4 commits intoespressif:masterfrom
KenVanHoeylandt:elf_loader_symbol_resolver
Open

Support alternative symbol resolving implementations for elf_loader (AEGHB-1243)#588
KenVanHoeylandt wants to merge 4 commits intoespressif:masterfrom
KenVanHoeylandt:elf_loader_symbol_resolver

Conversation

@KenVanHoeylandt
Copy link

@KenVanHoeylandt KenVanHoeylandt commented Sep 26, 2025

Description

Allow override of the symbol mapping functionality. See proposal for details.

I also included a small fix for C++ compilers that error out here:

#define ESP_ELFSYM_EXPORT(_sym) { #_sym, &_sym }

The solution was to cast explicitly:

#define ESP_ELFSYM_EXPORT(_sym) { #_sym, (void*)&_sym }

Related

Testing

Tested on LilyGo T-Deck Plus with ESP-IDF 5.5 installed on Linux with Intel 64-bit.

Checklist

Before submitting a Pull Request, please ensure the following:

  • 🚨 This PR does not introduce breaking changes.
  • All CI checks (GH Actions) pass.
  • Documentation is updated as needed.
  • Tests are updated or added as necessary.
  • Code is well-commented, especially in complex areas.
  • Git history is clean — commits are squashed to the minimum necessary.

@CLAassistant
Copy link

CLAassistant commented Sep 26, 2025

CLA assistant check
All committers have signed the CLA.

@github-actions
Copy link

github-actions bot commented Sep 26, 2025

Warnings
⚠️

Some issues found for the commit messages in this PR:

  • the commit message "Remove extra line feed":
    • summary looks empty
    • type/action looks empty
  • the commit message "Update version and changelog":
    • summary looks empty
    • type/action looks empty

Please fix these commit messages - here are some basic tips:

  • follow Conventional Commits style
  • correct format of commit message should be: <type/action>(<scope/component>): <summary>, for example fix(esp32): Fixed startup timeout issue
  • allowed types are: change,ci,docs,feat,fix,refactor,remove,revert,test
  • sufficiently descriptive message summary should be between 20 to 72 characters and start with upper case letter
  • avoid Jira references in commit messages (unavailable/irrelevant for our customers)

TIP: Install pre-commit hooks and run this check when committing (uses the Conventional Precommit Linter).

Messages
📖 You might consider squashing your 4 commits (simplifying branch history).

👋 Hello KenVanHoeylandt, we appreciate your contribution to this project!


Click to see more instructions ...


This automated output is generated by the PR linter DangerJS, which checks if your Pull Request meets the project's requirements and helps you fix potential issues.

DangerJS is triggered with each push event to a Pull Request and modify the contents of this comment.

Please consider the following:
- Danger mainly focuses on the PR structure and formatting and can't understand the meaning behind your code or changes.
- Danger is not a substitute for human code reviews; it's still important to request a code review from your colleagues.
- Resolve all warnings (⚠️ ) before requesting a review from human reviewers - they will appreciate it.
- Addressing info messages (📖) is strongly recommended; they're less critical but valuable.
- To manually retry these Danger checks, please navigate to the Actions tab and re-run last Danger workflow.

Review and merge process you can expect ...


We do welcome contributions in the form of bug reports, feature requests and pull requests.

1. An internal issue has been created for the PR, we assign it to the relevant engineer.
2. They review the PR and either approve it or ask you for changes or clarifications.
3. Once the GitHub PR is approved we do the final review, collect approvals from core owners and make sure all the automated tests are passing.
- At this point we may do some adjustments to the proposed change, or extend it by adding tests or documentation.
4. If the change is approved and passes the tests it is merged into the default branch.

Generated by 🚫 dangerJS against 31b3cf7

@github-actions github-actions bot changed the title Support alternative symbol resolving implementations for elf_loader Support alternative symbol resolving implementations for elf_loader (AEGHB-1243) Sep 26, 2025
@KenVanHoeylandt KenVanHoeylandt force-pushed the elf_loader_symbol_resolver branch from a304bcb to b51121b Compare September 26, 2025 22:03
@KenVanHoeylandt KenVanHoeylandt marked this pull request as ready for review September 26, 2025 22:05
@KenVanHoeylandt
Copy link
Author

Any feedback on this?

@cwespressif
Copy link
Contributor

Any feedback on this?

Hi @KenVanHoeylandt you can use the script to automatically add symbols for unlinked functions or variables from the required ELF application, this way, the functions and variables you need to look up will be automatically added to g_customer_elfsyms[], without requiring a custom elf_find_sym for lookup.
For usage, please refer to: https://github.com/espressif/esp-iot-solution/blob/master/examples/elf_loader/elf_loader_example/README.md#generate-symbols-table-based-on-elf-files.
Note that the configuration item CONFIG_ELF_LOADER_CUSTOMER_SYMBOLS must be enabled.

@KenVanHoeylandt
Copy link
Author

@cwespressif Thanks for the suggestion and my apologies for the slow response.

The usage example won't work if someone uses the dependency from the component registry.
Step 4 requires the developer to modify the library itself, which is not something you can do with a registry component:

image

That's why I propose to make the symbol resolving dynamic.

The script does work well, but it's not usable in my scenario: my application has 16500 symbols. Some of the application libraries have symbols that I can include fully, but some libraries only have a select amount of symbols that I want to export. Part of it works a bit like the linux kernel, where kernel modules define which functions they export.

I have about a dozen different lists of functions I need to export (e.g. C stdlib, C++ new/del/stl, LVGL, HAL/drivers, etc.) and having control the symbol resolving could easily facilitate that.

@cwespressif
Copy link
Contributor

Hi @KenVanHoeylandt thank you for submitting the PR, the implementation of this feature looks good.
Regarding the alternative symbol resolution implementation for elf_loader, it seems that using the esp_elf_register_symbol and esp_elf_unregister_symbol functions can achieve similar functionality, could you check whether this approach meets your requirements?

@KenVanHoeylandt
Copy link
Author

KenVanHoeylandt commented Feb 6, 2026

@cwespressif Thanks for responding!

Those functions solve a part of my problem. My use case (currently and future plans) has evolved a little bit, so I'll explain below why it's not sufficient for me.
project
1. Custom symbol format

I want to have my own platform-independent definition of symbols inside my project.
This way I can use elf_loader to map them, or some other 3rd party library.
This also allows me to create a symbol list later that is also compatible with Python, lua or Javascript.

Practically speaking, I have kernel modules that might export these symbols:

struct Module {
    const char* name;
    error_t (*start)(void);
    error_t (*stop)(void);
   const struct ModuleSymbols* symbols;
};

Example modules: LVGL, or a module that contains drivers.

2. Limiting exposure of symbols

My external ELF have a manifest file (manifest.properties).
This manifest specifies what's inside and how the app is compatible.
In the future, I want my ELF apps to declare which features they require. Some practical examples:

  • If an ELF doesn't require internet access, I intend to not map the symbols for that.
  • If an ELF contains a console app, I won't map the LVGL functions for 2D graphics
  • If an ELF only contains a driver, I won't need any of the app functionality.

Conclusion

Implementing a custom "find symbol" function is the simplest solution to go forward for my use cases, as it gives me full control on how to map functions and which ones to map for which app.

@cwespressif
Copy link
Contributor

@KenVanHoeylandt Please resolve the branch conflicts, modify the component version and the specific changes.

@KenVanHoeylandt
Copy link
Author

KenVanHoeylandt commented Feb 10, 2026

I fixed the conflicts and tested again on:

  • LilyGO T-Deck (ESP32 S3)
  • M5Stack Tab5 (ESP32 P4)

I've also updated the component version and the changelog.

Before this update, the code was tested on 20+ devices.

@KenVanHoeylandt
Copy link
Author

@cwespressif ping/reminder 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants