Skip to content

binfmt: parse application stacksize/priority from ELF symbols#19440

Merged
acassis merged 3 commits into
apache:masterfrom
anjiahao1:elf-attr-parse
Jul 15, 2026
Merged

binfmt: parse application stacksize/priority from ELF symbols#19440
acassis merged 3 commits into
apache:masterfrom
anjiahao1:elf-attr-parse

Conversation

@anjiahao1

@anjiahao1 anjiahao1 commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Allows an application's configured stack size and priority to be carried
    as absolute ELF symbols (nx_stacksize, nx_priority, and
    nx_uid/nx_gid/nx_mode under CONFIG_SCHED_USER_IDENTITY) and read
    back by the binary loader at exec time, instead of always falling back
    to CONFIG_ELF_STACKSIZE / SCHED_PRIORITY_DEFAULT.
  • Adds libelf_findsymbol() (a name-based symbol lookup over the ELF
    symbol table) in libs/libc/elf/elf_symbols.c and declares it in
    include/nuttx/lib/elf.h; binfmt/elf.c uses it to populate
    struct binary_s (binp->stacksize/priority/uid/gid/mode),
    falling back to the existing defaults when a symbol is absent.
  • cmake/nuttx_add_application.cmake emits the --defsym nx_* flags at
    link time.
  • posix_spawnattr_init() no longer pre-fills attr->stacksize and
    attr->priority (left at 0); nxtask_spawn_exec() fills the parent
    priority and CONFIG_POSIX_SPAWN_DEFAULT_STACKSIZE when a caller does
    not set them. This stops the spawnattr defaults from overriding the
    values parsed from the ELF, so the embedded symbols actually drive the
    spawned task.
  • Related NuttX Apps PR: Application.mk: emit application attribute as ELF symbols nuttx-apps#3641

Impact

  • Is new feature added? Is existing feature changed? YES — new feature:
    application attributes are parsed from ELF symbols and used by the
    binary loader.
  • Impact on user (will user need to adapt to change)? NO — the symbols
    are optional; when absent the loader keeps using the existing defaults
    (CONFIG_ELF_STACKSIZE, SCHED_PRIORITY_DEFAULT).
  • Impact on build (will build process change)? YES (minor) — the ELF app
    link now emits --defsym nx_stacksize/nx_priority (and nx_uid/
    nx_gid/nx_mode under CONFIG_SCHED_USER_IDENTITY); handled in the
    companion apps PR via Application.mk.
  • Impact on hardware (will arch(s) / board(s) / driver(s) change)? NO.
  • Impact on documentation (is update required / provided)? NO (not yet).
  • Impact on security (any sort of implications)? NO.
  • Impact on compatibility (backward/forward/interoperability)? NO —
    posix_spawnattr_init() callers that relied on the old stacksize/
    priority defaults still get them filled in by nxtask_spawn_exec() /
    the binary loader, so observable defaults are unchanged; only apps that
    embed the nx_* symbols change behavior (they now honor their own
    configured values).
  • Anything else to consider or add? The heapsize attribute from the
    original implementation is intentionally not included (it depends on
    the separate task-heap feature).

Testing

I confirm that changes are verified on local setup and works as intended:

  • Build Host(s): Ubuntu, arm-none-eabi-gcc 12.2.1
  • Target(s): qemu-armv7a:knsh (CONFIG_BUILD_KERNEL, CONFIG_ELF=y)
  • Build: ./tools/configure.sh qemu-armv7a:knsh && make && make export
    (apps built separately and mounted via hostfs as /system).
  • Run command: qemu-system-arm -semihosting -M virt -m 1024 -nographic -kernel ./nuttx

Testing logs before change (stock upstream/master nuttx; the getprime
app was built with --defsym nx_stacksize=8192 --defsym nx_priority=50,
but the symbol is not consulted, so the task uses the defaults — stack
4096, priority 100):

nsh> getprime 4 &
  TID   PID  PPID PRI POLICY   TYPE    NPX STATE    EVENT     SIGMASK            STACK    USED FILLED COMMAND
    4     4     3 100 RR       Task      - Waiting  Semaphore 0000000000000000 0004048 0000776  19.1%  getprime 4

Testing logs after change (this PR; same getprime app — the ELF symbols
now drive the task: stack ≈ 8192, priority 50):

nsh> getprime 4 &
  TID   PID  PPID PRI POLICY   TYPE    NPX STATE    EVENT     SIGMASK            STACK    USED FILLED COMMAND
    4     4     3  50 RR       Task      - Waiting  Semaphore 0000000000000000 0008144 0000792   9.7%  getprime 4

hello, ostest, and NSH itself continue to load and run; no regression
observed on knsh.

PR verification Self-Check

  • This PR introduces only one functional change.
  • I have updated all required description fields above.
  • My PR adheres to Contributing Guidelines and Documentation (git commit title and message, coding standard, etc).
  • My PR is still work in progress (not ready for review).
  • My PR is ready for review and can be safely merged into a codebase.

Add libelf_findsymbol() to locate a symbol in the ELF symbol table by
name, reusing the existing libelf_findsymtab/libelf_readsym/libelf_symname
helpers, and expose its prototype in include/nuttx/lib/elf.h.

Signed-off-by: anjiahao <[email protected]>
Parse application attributes (stacksize, priority, and uid/gid/mode under
CONFIG_SCHED_USER_IDENTITY) from absolute symbols (nx_stacksize,
nx_priority, nx_uid, nx_gid, nx_mode) embedded in the ELF at link time,
falling back to defaults when the symbols are absent.

Signed-off-by: anjiahao <[email protected]>
posix_spawnattr_init() no longer pre-fills attr->stacksize and
attr->priority (it leaves them zero, as memset already does).  When a
caller does not set them, the binary loader supplies them from the
loaded ELF (binp->stacksize / binp->priority, parsed from the nx_*
symbols), and nxtask_spawn_exec() falls back to the parent priority and
CONFIG_POSIX_SPAWN_DEFAULT_STACKSIZE for the posix_spawn() function-task
path.

This lets an application's stack size and priority embedded as ELF
symbols actually drive the spawned task, instead of being overridden by
the spawnattr defaults.

Signed-off-by: anjiahao <[email protected]>
@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

arduino-mega2560

  • flash: .text +30 B (+0.0%, 67,248 B / 262,144 B, total: 26% used)

esp32-devkitc

  • ROM: .flash.text +8 B (+0.0%, 122,716 B / 4,194,272 B, total: 3% used)
  • irom0_0_seg: .flash.text +8 B (+0.0%, 87,084 B / 3,342,304 B, total: 3% used)

mirtoo

  • kseg0_progmem: .text +20 B (+0.0%, 67,152 B / 131,072 B, total: 51% used)

qemu-armv8a

  • Code: .text.posix_spawnattr_init -16 B, .text.task_spawn +36 B (+0.0%, 315,374 B)

qemu-intel64

  • Code: .text +48 B (+0.0%, 8,655,445 B)

rx65n-rsk2mb

  • ROM: .text +16 B (+0.0%, 85,656 B / 2,097,152 B, total: 4% used)

s698pm-dkit

  • Code: .text +736 B (+0.2%, 358,096 B)

stm32-nucleo-f103rb

  • flash: .text +20 B (+0.1%, 33,792 B / 131,072 B, total: 26% used)
    No memory changes detected for:
  • hifive1-revb

@acassis

acassis commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

@raiden00pl nucleo-f302r8/ihm07m1_b16 is overflowing again, maybe we need to remove this board, end of life for NuttX on it. :-(

@acassis acassis merged commit 745a6e5 into apache:master Jul 15, 2026
56 of 65 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: BINFMT Size: M The size of the change in this PR is medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants