This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 08c0cce0d964904e1b23b17589593e3405d9a1b0 Author: Marco Casaroli <[email protected]> AuthorDate: Mon Sep 28 14:11:30 2026 +0200 libs/libc: Define the NXFLAT ABI marker in libc. Every NXFLAT module imports __nxflat_abi_v2, and the loader resolves it against the symbol table exec() is given, like any other import. It was defined in binfmt/libnxflat, which is enough for a flat build, where the firmware and the applications are one image. In a protected build the table comes from the application, in the user image, which cannot see a kernel symbol: the user image fails to link with an undefined reference to __nxflat_abi_v2 as soon as an application generates its table from the modules' imports, as examples/nxflat does. A kernel build is the same, with one image per process. libc is linked into each of those images, so the marker is defined there now. Nothing else changes: its value is still never used. On mps3-an547:knsh under QEMU with CONFIG_NXFLAT and examples/nxflat, the user image links, and errno, hello, mutex, pthread and struct run. lm3s6965-ek:qemu-nxflat still runs every module to the end. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <[email protected]> --- Documentation/components/nxflat.rst | 6 +++-- binfmt/libnxflat/libnxflat_bind.c | 22 +++--------------- libs/libc/misc/CMakeLists.txt | 6 +++++ libs/libc/misc/Make.defs | 6 +++++ libs/libc/misc/lib_nxflat.c | 45 +++++++++++++++++++++++++++++++++++++ 5 files changed, 64 insertions(+), 21 deletions(-) diff --git a/Documentation/components/nxflat.rst b/Documentation/components/nxflat.rst index ec8e476a4eb..48a3a97a07f 100644 --- a/Documentation/components/nxflat.rst +++ b/Documentation/components/nxflat.rst @@ -346,8 +346,10 @@ The NXFLAT header carries no version field -- ``h_magic`` is written by ``ldnxflat``, which lives outside this repository and cannot be changed in step with the loader -- so the module ABI is declared through the import table instead. Every module built by ``mknxflat`` imports the symbol -``__nxflat_abi_v2``, the base firmware defines it, and the loader refuses a -module whose import table does not name it. The generation is bumped +``__nxflat_abi_v2``, libc defines it, and the loader refuses a module whose +import table does not name it. Being in libc, the marker is in every image +that can pass ``exec()`` a symbol table: the user image of a protected or +kernel build as well as the base firmware. The generation is bumped whenever the module ABI changes; v2 is the move of the PIC base register to r9, and a v1 module's thunks would add r10 and branch to a wild address on the first call into the base firmware. diff --git a/binfmt/libnxflat/libnxflat_bind.c b/binfmt/libnxflat/libnxflat_bind.c index 990f6f41a20..5185b0a4e38 100644 --- a/binfmt/libnxflat/libnxflat_bind.c +++ b/binfmt/libnxflat/libnxflat_bind.c @@ -61,22 +61,6 @@ # define nxflat_dumpbuffer(m,b,n) #endif -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/* The module ABI marker. Every module built by tools/nxflat/mknxflat - * imports this, and a board's exported symbol table picks it up the same - * way it picks up any other imported name, so nothing has to special-case - * it in the build. Its value is never used; only its presence matters. - * - * A module built against a newer ABI than the firmware therefore fails - * with "Exported symbol __nxflat_abi_vN not found", which names the - * problem, and a module built against an older one is caught below. - */ - -void *NXFLAT_ABI_MARKER; - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -480,9 +464,9 @@ static inline int nxflat_bindimports(FAR struct nxflat_loadinfo_s *loadinfo, (offset + loadinfo->ispace + sizeof(struct nxflat_hdr_s)); /* Note the ABI marker as it goes past. It resolves like any - * other import -- the base firmware defines it below -- so the - * only thing special about it is that its absence means the - * module was built before the ABI it names. + * other import -- libc defines it -- so the only thing special + * about it is that its absence means the module was built before + * the ABI it names. */ if (strcmp(symname, NXFLAT_ABI_SYMBOL) == 0) diff --git a/libs/libc/misc/CMakeLists.txt b/libs/libc/misc/CMakeLists.txt index cf34b650362..8820b1b2ebd 100644 --- a/libs/libc/misc/CMakeLists.txt +++ b/libs/libc/misc/CMakeLists.txt @@ -115,6 +115,12 @@ if(CONFIG_LIBC_SLCDCODEC) list(APPEND SRCS lib_slcdencode.c lib_slcddecode.c) endif() +# The NXFLAT module ABI marker + +if(CONFIG_NXFLAT) + list(APPEND SRCS lib_nxflat.c) +endif() + # Environment search path support if(CONFIG_LIBC_ENVPATH) diff --git a/libs/libc/misc/Make.defs b/libs/libc/misc/Make.defs index 98b896d4a68..b9ad85bc614 100644 --- a/libs/libc/misc/Make.defs +++ b/libs/libc/misc/Make.defs @@ -64,6 +64,12 @@ ifeq ($(CONFIG_LIBC_SLCDCODEC),y) CSRCS += lib_slcdencode.c lib_slcddecode.c endif +# The NXFLAT module ABI marker + +ifeq ($(CONFIG_NXFLAT),y) +CSRCS += lib_nxflat.c +endif + # Environment search path support ifeq ($(CONFIG_LIBC_ENVPATH),y) diff --git a/libs/libc/misc/lib_nxflat.c b/libs/libc/misc/lib_nxflat.c new file mode 100644 index 00000000000..79d6dab8d3b --- /dev/null +++ b/libs/libc/misc/lib_nxflat.c @@ -0,0 +1,45 @@ +/**************************************************************************** + * libs/libc/misc/lib_nxflat.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <nxflat.h> + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* The module ABI marker. Every module built by mknxflat imports it, so it + * must be in whatever image supplies the symbol table to exec(): in libc, + * both halves of a protected or kernel build have it. Only its presence + * matters. + */ + +void *NXFLAT_ABI_MARKER; + +/**************************************************************************** + * Public Functions + ****************************************************************************/
