tools/nxflat: Add an Apache-licensed NXFLAT converter - #20377
Merged
Merged
Conversation
casaroli
force-pushed
the
nxflat-ldnxflat-apache
branch
from
September 27, 2026 09:22
ed3a5b1 to
4a28b86
Compare
casaroli
force-pushed
the
nxflat-ldnxflat-apache
branch
from
September 27, 2026 09:39
4a28b86 to
d6c5e84
Compare
A module's D-Space is separate from its I-Space, so its read-only data is not at a fixed offset from its text. GCC assumes that it is and loads a string literal PC-relative, which reads I-Space at run time. A module could therefore carry no string and reach no static. lm3s6965-ek has had -mno-pic-data-is-text-relative in its own Make.defs since 2021 (issue apache#3737), and the CMake build gives it to every PIC configuration, so the flag moves to where it belonged and the board's copy goes. That copy also probed for GCC older than 4.9.4, which NuttX no longer supports. Clang has no such option, hence the guard. Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
casaroli
force-pushed
the
nxflat-ldnxflat-apache
branch
2 times, most recently
from
September 27, 2026 09:49
5ca9771 to
d93a63d
Compare
The converter that follows reads the same objects as mknxflat, so the reader goes into a file of its own before it gains a second user. nxflat_elf.c normalises the tables that describe the object -- the headers, the symbols, the relocation entries -- into the host's order, and leaves the section contents alone, because those are the target's bytes and the tools write them out again. A tool reads a field without knowing whose order it arrived in. The -d option goes with it. It chose a dynamic symbol table, which the ld -r object these tools convert does not have, and which the NXFLAT loader cannot use anyway: imports reach a module through the array mknxflat generates. The output is unchanged. The thunk mknxflat generates for each of the eleven modules of apps/examples/nxflat/tests is byte identical to the one the previous version generated. Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
ldnxflat is the last piece of the NXFLAT toolchain that NuttX cannot carry. It descends from elf2flt through four sets of copyright holders, so it is GPL by that descent and not merely by its libbfd dependency. This is a new implementation, written from include/nxflat.h, from what binfmt/libnxflat does with the container, and from the ELF specification. The relocation arithmetic is that of libs/libc/machine/arm/armv7-m/arch_elf.c, which the ELF loader runs on the target for the same relocations, and which brings R_ARM_TARGET1 with it. NXFLAT is not an ARM format. Its loader only adds a base to a 32-bit word, so the segments, the GOT, the relocation records and the header are common to every architecture. An architecture supplies a table entry, an entry-point convention and a relocation handler; an object for a machine with no entry is refused by name. The GOT is built here, because ld -r emits none: one entry per symbol that a GOT-relative reference names, at the start of D-Space, each with a relocation record of its own. An entry may hold a function, which is what makes a function pointer reached through the GOT work. Two defects of the out-of-tree tool do not survive. A GOT entry naming a .bss object lost its section's address and pointed at the start of D-Space, the GOT itself, so on lm3s6965-ek:qemu-nxflat the longjmp test panics with PC 0 and the five tests after it never run. The alignment gap before .bss went missing from h_bssend as well, leaving D-Space short. The tool is built and named like the rest of the toolchain. Makefile.host builds it, Unix.mk makes a configuration that sets CONFIG_NXFLAT depend on it beside mknxflat, and LDNXFLAT points at the tool in the tree rather than one on PATH. All eight C modules of apps/examples/nxflat/tests convert and run to completion under qemu-system-arm -M lm3s6965evb. Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
Building an NXFLAT module takes four tools in sequence, and there was no way to exercise them without a board. testsuite.sh builds every module of apps/examples/nxflat/tests for cortex-m3 against a configured tree's headers, and reports the stage each one stopped at and the relocations it carried. Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
Nine of the seventeen configurations that set CONFIG_NXFLAT are on the CI blacklist, and they are exactly the ones that build a module: the converter they need was not in the tree. ldnxflat is in it now, so eagle100:nxflat and lm3s6965-ek:qemu-nxflat come off the list. Both were built with the toolchain CI uses. The other seven stay off for reasons of their own. The thttpd configurations need CONFIG_BOARDCTL_ROMDISK, which their defconfigs do not set, and the older boards define their own CPICFLAGS without filtering --fixed-r9 out, so the compiler refuses r9 as the PIC register. Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
casaroli
force-pushed
the
nxflat-ldnxflat-apache
branch
from
September 27, 2026 09:57
d93a63d to
29e3aec
Compare
xiaoxiang781216
approved these changes
Sep 27, 2026
acassis
approved these changes
Sep 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ldnxflatis the last part of the NXFLAT toolchain that NuttX cannot carry, so a board that builds NXFLAT modules has to fetch a GPL tool from buildroot. This adds an Apache-2.0 replacement, and a driver that builds every test module through the toolchain.mknxflatcame in with #19600 and was relicensed with its author's agreement, because Gregory Nutt owned all of it.ldnxflatcannot follow: it descends fromelf2fltandobj-res.cthrough eleven sets of copyright holders reaching back to 1996, several of them companies that no longer exist. It is GPL by that descent rather than by itslibbfddependency, so no set of permissions can be assembled and a rewrite is the only route.NXFLAT is not an ARM format.
binfmt/Kconfigputs no architecture dependency on it and the loader only ever adds a base to a 32-bit word, so an architecture here supplies a table entry, an entry-point convention and a relocation handler, and an object for an unknown machine is refused by name rather than converted wrongly.Impact
Nothing changes for a configuration that does not set
CONFIG_NXFLAT. For one that does,LDNXFLATnames the tool in the tree instead of looking for one onPATH, andmknxflat's output is unchanged: the thunk it generates for each of the eleven test modules is byte identical to the one the merged version generates.Two defects of the old converter do not survive the rewrite. A GOT entry naming a
.bssobject now resolves to the object, where the old tool dropped the section's address and pointed it at the start of D-Space — the GOT itself — so a module reaching a static through the GOT read and wrote its own GOT. And the alignment gap before.bssno longer goes missing fromh_bssend.A module can also carry a string, which is a compiler flag rather than the converter, and not a new finding: lm3s6965-ek has had
-mno-pic-data-is-text-relativein its ownscripts/Make.defssince 2021 (issue #3737) and the CMake build applies it to every PIC configuration. The first commit moves it where it belonged; the other sixteen NXFLAT configurations were without it.Testing
Nine of the seventeen configurations that set
CONFIG_NXFLATare on the CI blacklist, and they are exactly the ones that build a module — the converter was not there to build them with.eagle100:nxflatandlm3s6965-ek:qemu-nxflatcome off it here, and both were built with the toolchain CI uses. The other seven stay off for reasons of their own: the thttpd configurations wantCONFIG_BOARDCTL_ROMDISK, which their defconfigs do not set, and some of those boards define their ownCPICFLAGSwithout filtering--fixed-r9, so the compiler refuses r9 as the PIC register.lm3s6965-ek:qemu-nxflatalso runs. Underqemu-system-arm -M lm3s6965evbits ROMFS modules execute toEnd-of-Test.. Exit-ing,structreportingpf = 0x13335— odd, so the Thumb bit survives — and thenIn dummyfunc() -- PASS. Built with the out-of-tree tool instead, the same image panics in the third test withPC: 00000000and the remaining five never run:longjmp'sjmp_bufis a static, its GOT entry lands on the GOT, andsetjmpoverwrites it.tools/nxflat/testsuite.shbuilds and converts every module ofapps/examples/nxflat/testsand reports the relocations each one carried. It needs no board: a module is built for cortex-m3 against a configured tree's headers.tools/checkpatch.sh -c -u -m -gpasses.Provenance
The container is defined by
include/nxflat.hand by whatbinfmt/libnxflatdoes with it, the segment layout bygnu-nxflat-gotoff.ld, and the relocation arithmetic is that oflibs/libc/machine/arm/armv7-m/arch_elf.c. Those files and the new one are Apache-2.0.No part of the out-of-tree tool is used. During development it was run on the same inputs to compare output against, which is how the conventions the container does not state — where the GOT sits, the order of its entries, the order of the relocation records — were matched. Six modules come out byte identical to it,
hello++3converts where it refusesR_ARM_TARGET1, and four differ where it is wrong. Two of its results are deliberately not matched, and the file says which.apache/nuttx-apps#3803 builds the test modules this exercises. It is not needed for this one to be correct.