-
-
Notifications
You must be signed in to change notification settings - Fork 4
Description
I'm running Fedora 40 in a UTM VM on MacOS, on an M1 chip.
The relevant software versions I have are:
binfmt-dispatcher-0.1.2-1.fc40.aarch64
fex-emu-2412-3.fc40.aarch64
To test my setup, I made a small ls
equivalent in standard C, and compiled it under Fedora 40 x86_64. I then copy it into my as /var/tmp/fexls
. The source code for that test is attached as fexls.c
. It expects a path argument on the command line and lists the files at that path like ls
would. Again this is just to test my fex setup.
When I run /var/tmp/fexls /var/tmp
from my shell, I get this:
[binfmt_dispatcher] Using FEX
argc = 4
argv[0] = '/var/tmp/fexls'
argv[1] = '/var/tmp/fexls'
argv[2] = '/var/tmp/fexls'
argv[3] = '/var/tmp/'
Usage: /var/tmp/fexls <target-directory>
Why is my argv mangled?
When I run directly (without binfmt-dispatcher) FEXInterpreter /var/tmp/fexls /var/tmp/
I get the correct output:
argc = 2
argv[0] = '/var/tmp/fexls'
argv[1] = '/var/tmp/'
drwxr-xr-x 1 abrt abrt 0 Apr 16 03:17 abrt
-rw-r--r-- 1 root root 2298 Apr 16 03:19 fstab
-rw-r--r-- 1 root root 280 Apr 22 20:14 .location
.... [more files] ...
My binfmt-dispatcher configuration file /etc/binfmt-dispatcher.toml
is standard (I just disabled muvm only):
[defaults]
interpreter = "fex"
log_level = "info"
[muvm]
path = "/usr/bin/muvm"
[interpreters.box64]
path = "/usr/bin/box64"
[interpreters.fex]
name = "FEX"
path = "/usr/bin/FEXInterpreter"
required_paths = ["/usr/share/fex-emu/RootFS/default.erofs"]
use_muvm = false
[interpreters.qemu]
name = "QEMU User space emulator"
path = "/usr/bin/qemu-x86_64"
[interpreters.qemu-static]
name = "QEMU User space emulator (static)"
path = "/usr/bin/qemu-x86_64-static"
Am I doing something wrong? Or is there a bug here?
The C code for fexls.c
:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <unistd.h>
void print_file_info(const char *path, const char *filename) {
char fullpath[4096];
snprintf(fullpath, sizeof(fullpath), "%s/%s", path, filename);
struct stat st;
if (lstat(fullpath, &st) == -1) {
perror("lstat");
return;
}
// File type and permissions
char perms[11] = "----------";
if (S_ISDIR(st.st_mode)) perms[0] = 'd';
else if (S_ISLNK(st.st_mode)) perms[0] = 'l';
else if (S_ISCHR(st.st_mode)) perms[0] = 'c';
else if (S_ISBLK(st.st_mode)) perms[0] = 'b';
else if (S_ISFIFO(st.st_mode)) perms[0] = 'p';
else if (S_ISSOCK(st.st_mode)) perms[0] = 's';
if (st.st_mode & S_IRUSR) perms[1] = 'r';
if (st.st_mode & S_IWUSR) perms[2] = 'w';
if (st.st_mode & S_IXUSR) perms[3] = 'x';
if (st.st_mode & S_IRGRP) perms[4] = 'r';
if (st.st_mode & S_IWGRP) perms[5] = 'w';
if (st.st_mode & S_IXGRP) perms[6] = 'x';
if (st.st_mode & S_IROTH) perms[7] = 'r';
if (st.st_mode & S_IWOTH) perms[8] = 'w';
if (st.st_mode & S_IXOTH) perms[9] = 'x';
// User and group names
struct passwd *pw = getpwuid(st.st_uid);
struct group *gr = getgrgid(st.st_gid);
// Modification time
char timebuf[64];
struct tm *mtm = localtime(&st.st_mtime);
strftime(timebuf, sizeof(timebuf), "%b %e %H:%M", mtm);
// Output format similar to ls -l
printf("%s %3lu %s %s %8ld %s %s\n",
perms,
st.st_nlink,
pw ? pw->pw_name : "???",
gr ? gr->gr_name : "???",
st.st_size,
timebuf,
filename);
}
int main(int argc, char *argv[]) {
printf("argc = %d\n", argc);
for (int i = 0; i < argc; ++i) {
printf("argv[%d] = '%s'\n", i, argv[i]);
}
if (argc != 2) {
fprintf(stderr, "Usage: %s <target-directory>\n", argv[0]);
return EXIT_FAILURE;
}
const char *dirpath = argv[1];
DIR *dir = opendir(dirpath);
if (!dir) {
perror("opendir");
return EXIT_FAILURE;
}
struct dirent *entry;
while ((entry = readdir(dir))) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
print_file_info(dirpath, entry->d_name);
}
closedir(dir);
return EXIT_SUCCESS;
}
and I compile it with: gcc -Wall -Wextra -O2 -o fexls fexls.c
.
I can confirm the ELF is indeed x86_64:
$ file /var/tmp/fexls
/var/tmp/fexls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=4efe18c6f1e3fa1fffbc8347a43cb3c48d4be70d, for GNU/Linux 3.2.0, not stripped