This is an automated email from the ASF dual-hosted git repository.
xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 844e0ac6f4e binfmt: Report the error of the loader that knew the
format.
844e0ac6f4e is described below
commit 844e0ac6f4e50ac7ef87bb646644b01373876430
Author: Marco Casaroli <[email protected]>
AuthorDate: Tue Nov 3 01:40:04 2026 +0100
binfmt: Report the error of the loader that knew the format.
load_absmodule() tries each binary format handler and returned the
error of the last one. This hid two errors:
When the ELF loader recognized a program and failed for another reason,
for example -ENOMEM for a program that does not fit, the next handler
said "not my format" and exec() failed with ENOEXEC ("Exec format
error").
When a file was not a program and the builtin handler was the last one,
exec() failed with ENOENT, as for a missing file. The builtin handler
said "not my format" with -ENOENT. It now gives -ENOEXEC, as the other
handlers do.
load_absmodule() now keeps the first error that is not -ENOEXEC and
returns it when no handler loads the file. When every handler gives
-ENOEXEC, it calls nx_stat(), because no handler may have looked at the
file: only the builtin handler is there in some builds. A file that no
handler knows gives -ENOEXEC, a missing file -ENOENT, a script with a
missing interpreter -ENOENT, and -EACCES still stops the search.
Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <[email protected]>
---
binfmt/binfmt_loadmodule.c | 37 +++++++++++++++++++++++++++++++++++--
binfmt/builtin.c | 4 ++--
2 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/binfmt/binfmt_loadmodule.c b/binfmt/binfmt_loadmodule.c
index 99480cef5f2..3cdbe142f10 100644
--- a/binfmt/binfmt_loadmodule.c
+++ b/binfmt/binfmt_loadmodule.c
@@ -26,6 +26,7 @@
#include <nuttx/config.h>
+#include <sys/stat.h>
#include <sched.h>
#include <nuttx/debug.h>
#include <errno.h>
@@ -36,6 +37,7 @@
#include <nuttx/sched.h>
#include <nuttx/kmalloc.h>
#include <nuttx/binfmt/binfmt.h>
+#include <nuttx/fs/fs.h>
#include "binfmt.h"
@@ -103,6 +105,8 @@ static int load_absmodule(FAR struct binary_s *bin, FAR
const char *filename,
FAR const struct symtab_s *exports, int nexports)
{
FAR struct binfmt_s *binfmt;
+ struct stat buf;
+ int first = -ENOEXEC;
int ret = -ENOENT;
binfo("Loading %s\n", filename);
@@ -142,7 +146,18 @@ static int load_absmodule(FAR struct binary_s *bin, FAR
const char *filename,
binfmt_dumpmodule(bin);
break;
}
- else if (ret == -EACCES)
+
+ /* -ENOEXEC is the "not my format" of a handler. Keep the first other
+ * error (a missing file, or -ENOMEM from a handler that knew the
+ * format): the next handlers must not hide it.
+ */
+
+ if (first == -ENOEXEC && ret != -ENOEXEC)
+ {
+ first = ret;
+ }
+
+ if (ret == -EACCES)
{
/* Access explicitly denied -- stop here; do not let a fallback
* loader bypass the execute-permission check that already ran.
@@ -152,7 +167,25 @@ static int load_absmodule(FAR struct binary_s *bin, FAR
const char *filename,
}
}
- return ret;
+ if (ret == OK)
+ {
+ return OK;
+ }
+
+ /* A handler that is not for this format need not look at the file, so
+ * only here do we know if a missing file is the reason.
+ */
+
+ if (first == -ENOEXEC)
+ {
+ ret = nx_stat(filename, &buf, 1);
+ if (ret < 0)
+ {
+ return ret;
+ }
+ }
+
+ return first;
}
/****************************************************************************
diff --git a/binfmt/builtin.c b/binfmt/builtin.c
index 04b5e4b3073..fa82eab54fb 100644
--- a/binfmt/builtin.c
+++ b/binfmt/builtin.c
@@ -92,8 +92,8 @@ static int builtin_loadbinary(FAR struct binary_s *binp,
ret = builtin_isavail(filename);
if (ret < 0)
{
- berr("ERROR: %s is not a builtin application\n", filename);
- return ret;
+ binfo("%s is not a builtin application\n", filename);
+ return -ENOEXEC;
}
/* Return the load information. NOTE: that there is no way to configure