Skip to content

fix: provide newlib syscall stubs for GCC 15+ toolchains#841

Open
Fabian Gottstein (fabiangottstein) wants to merge 1 commit into
mainfrom
fix/syscalls
Open

fix: provide newlib syscall stubs for GCC 15+ toolchains#841
Fabian Gottstein (fabiangottstein) wants to merge 1 commit into
mainfrom
fix/syscalls

Conversation

@fabiangottstein

Copy link
Copy Markdown
Contributor

Newlib-nano does not implement the POSIX OS-interface subroutines (_close, _fstat, _getpid, _isatty, _kill, _lseek, _read, _write); they must be supplied by the application, a BSP, or via --specs=nosys.specs. The newlib manual lists these explicitly as stubs that a bare-metal target has to provide to allow libc to link [1][2].

libstdc++ enables precondition assertions via _GLIBCXX_ASSERTIONS, which is defined by default in unoptimized (Debug) builds [3]. With the bumped toolchain (arm-none-eabi-gcc 15) a failed assertion is reported through std::__glibcxx_assert_fail, whose implementation calls fprintf. This newly drags newlib's stdio backend into the image, which references the reentrant covers _read_r, _write_r, _close_r, etc.; those in turn reference the underlying _close, _fstat, _isatty, _lseek, _read and _write. Because the image did not pull in stdio before, the missing stubs went unnoticed; now linking fails with "undefined reference to _close/_lseek/_read/_write/_fstat/_isatty" and the accompanying "dangerous relocation: unsupported relocation" errors (caused by the undefined symbols resolving to absolute 0).

Add SysCallStubs.cpp providing weak, ENOSYS-returning implementations of these syscalls so the image links regardless of what drags in stdio. _getpid and _kill are included defensively (e.g. for the abort/raise path) though not currently referenced. The stubs are weak so applications can still override them with real implementations, and are only compiled for GCC 15 and newer.

[1] Newlib manual, "System Calls":
https://sourceware.org/newlib/libc.html#Syscalls
[2] Newlib manual, per-function "Supporting OS subroutines required"
(e.g. assert, printf/fprintf): https://sourceware.org/newlib/libc.html
[3] libstdc++ manual, "Macros" (_GLIBCXX_ASSERTIONS):
https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_macros.html

Newlib-nano does not implement the POSIX OS-interface subroutines
(_close, _fstat, _getpid, _isatty, _kill, _lseek, _read, _write); they
must be supplied by the application, a BSP, or via --specs=nosys.specs.
The newlib manual lists these explicitly as stubs that a bare-metal
target has to provide to allow libc to link [1][2].

libstdc++ enables precondition assertions via _GLIBCXX_ASSERTIONS, which
is defined by default in unoptimized (Debug) builds [3]. With the bumped
toolchain (arm-none-eabi-gcc 15) a failed assertion is reported through
std::__glibcxx_assert_fail, whose implementation calls fprintf. This
newly drags newlib's stdio backend into the image, which references the
reentrant covers _read_r, _write_r, _close_r, etc.; those in turn
reference the underlying _close, _fstat, _isatty, _lseek, _read and
_write. Because the image did not pull in stdio before, the missing
stubs went unnoticed; now linking fails with "undefined reference to
_close/_lseek/_read/_write/_fstat/_isatty" and the accompanying
"dangerous relocation: unsupported relocation" errors (caused by the
undefined symbols resolving to absolute 0).

Add SysCallStubs.cpp providing weak, ENOSYS-returning implementations of
these syscalls so the image links regardless of what drags in stdio.
_getpid and _kill are included defensively (e.g. for the abort/raise
path) though not currently referenced. The stubs are weak so
applications can still override them with real implementations, and are
only compiled for GCC 15 and newer.

[1] Newlib manual, "System Calls":
    https://sourceware.org/newlib/libc.html#Syscalls
[2] Newlib manual, per-function "Supporting OS subroutines required"
    (e.g. assert, printf/fprintf): https://sourceware.org/newlib/libc.html
[3] libstdc++ manual, "Macros" (_GLIBCXX_ASSERTIONS):
    https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_macros.html
@fabiangottstein Fabian Gottstein (fabiangottstein) changed the title Provide newlib syscall stubs for GCC 15+ toolchains fix: provide newlib syscall stubs for GCC 15+ toolchains Jul 7, 2026
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

⚠️MegaLinter analysis: Success with warnings

Descriptor Linter Files Fixed Errors Warnings Elapsed time
✅ ACTION actionlint 7 0 0 0.27s
✅ ACTION zizmor 7 0 0 0 2.55s
✅ CPP clang-format 15 2 0 0 0.36s
✅ CPP cppcheck 15 0 0 0.72s
✅ DOCKERFILE hadolint 1 0 0 0.02s
✅ JSON jsonlint 7 0 0 0.39s
✅ JSON prettier 7 2 0 0 0.57s
⚠️ MARKDOWN markdownlint 6 1 10 0 0.99s
✅ MARKDOWN markdown-table-formatter 6 1 0 0 0.39s
✅ REPOSITORY checkov yes no no 47.02s
✅ REPOSITORY git_diff yes no no 0.2s
✅ REPOSITORY grype yes no no 75.89s
✅ REPOSITORY ls-lint yes no no 0.01s
✅ REPOSITORY osv-scanner yes no no 0.93s
✅ REPOSITORY secretlint yes no no 85.5s
✅ REPOSITORY syft yes no no 1.89s
✅ REPOSITORY trivy yes no no 21.82s
✅ REPOSITORY trivy-sbom yes no no 1.97s
✅ REPOSITORY trufflehog yes no no 18.14s
⚠️ SPELL lychee 34 2 0 18.81s
✅ YAML prettier 10 1 0 0 0.6s
✅ YAML v8r 10 0 0 7.52s
✅ YAML yamllint 10 0 0 0.54s

Detailed Issues

⚠️ SPELL / lychee - 2 errors
📝 Summary
---------------------
🔍 Total..........249
🔗 Unique.........237
✅ Successful.....245
⏳ Timeouts.........0
🔀 Redirected.....114
👻 Excluded.........0
❓ Unknown..........0
🚫 Errors...........2
⛔ Unsupported......2

Errors in .github/ISSUE_TEMPLATE/add-or-update-hal-driver.md
[ERROR] http://mcd.rou.st.com/modules.php?name=mcu (at 28:60) | Connection failed. Check network connectivity and firewall settings

Errors in README.md
[ERROR] https://st.com/ (at 5:97) | HTTP/2 protocol error. Server may not support HTTP/2 properly | Followed 1 redirect. Redirects: https://st.com/ --[301]--> https://www.st.com/

Hint: Followed 114 redirects. You might want to consider replacing redirecting URLs with the resolved URLs. Use verbose mode (`-v`/`-vv`) to see redirection details.
⚠️ MARKDOWN / markdownlint - 10 errors
.github/ISSUE_TEMPLATE/add-or-update-hal-driver.md:10 error MD025/single-title/single-h1 Multiple top-level headings in the same document [Context: "How to import a HAL driver"]
CHANGELOG.md:83 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "⚠ BREAKING CHANGES"]
CHANGELOG.md:87 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Features"]
CHANGELOG.md:94 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Bug Fixes"]
CHANGELOG.md:103 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Features"]
CHANGELOG.md:122 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Bug Fixes"]
CHANGELOG.md:140 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "⚠ BREAKING CHANGES"]
CHANGELOG.md:144 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Features"]
CHANGELOG.md:151 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Features"]
CHANGELOG.md:162 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Bug Fixes"]

Notices

📣 MegaLinter 9.5.0 is out! Discover the new features and security recommendations in the release announcement. (Skip this info by defining SECURITY_SUGGESTIONS: false)

See detailed reports in MegaLinter artifacts

Your project could benefit from a custom flavor, which would allow you to run only the linters you need, and thus improve runtime performances. (Skip this info by defining FLAVOR_SUGGESTIONS: false)

  • Documentation: Custom Flavors
  • Command: npx mega-linter-runner@9.5.0 --custom-flavor-setup --custom-flavor-linters ACTION_ACTIONLINT,ACTION_ZIZMOR,CPP_CPPCHECK,CPP_CLANG_FORMAT,DOCKERFILE_HADOLINT,JSON_JSONLINT,JSON_PRETTIER,MARKDOWN_MARKDOWNLINT,MARKDOWN_MARKDOWN_TABLE_FORMATTER,REPOSITORY_CHECKOV,REPOSITORY_GIT_DIFF,REPOSITORY_GRYPE,REPOSITORY_LS_LINT,REPOSITORY_OSV_SCANNER,REPOSITORY_SECRETLINT,REPOSITORY_SYFT,REPOSITORY_TRIVY,REPOSITORY_TRIVY_SBOM,REPOSITORY_TRUFFLEHOG,SPELL_LYCHEE,YAML_PRETTIER,YAML_YAMLLINT,YAML_V8R

MegaLinter is graciously provided by OX Security
Show us your support by starring ⭐ the repository

@fabiangottstein

Fabian Gottstein (fabiangottstein) commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

@philips-software/awesome-embedded-projects
An alternative fix is to avoid pulling fprintf into the image by disabling the assertions for embedded targets in Debug configuration (define _GLIBCXX_NO_ASSERTIONS, which prevents the implicit definition of _GLIBCXX_ASSERTIONS in unoptimized builds).

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants