general/other Linuxulator: Strange ELF64 cannot be executed due to “Bad Interpreter”

I have an ELF64 executable which I cannot execute in a Linuxulator environment; more precisely: a Linux jail.

In this jail, there is an Ubuntu 22.04, which was setup with sysutils/debootstrap.

The executable in question is called “patchelf-uninative” and fell out of a Yocto build. When trying to execute it, I get the following error:
Code:
$ ./patchelf-uninative
Invalid PT_INTERP
-bash: ./tmp/sysroots-uninative/x86_64-linux/usr/bin/patchelf-uninative: cannot execute binary file: Exec format error

Other executables from this Yocto build work just fine:
Code:
$ ./xz --help
Usage: ./tmp/work/x86_64-linux/libmpc-native/1.3.1/recipe-sysroot-native/usr/bin/xz [OPTION]... [FILE]...
Compress or decompress FILEs in the .xz format.

Mandatory arguments to long options are mandatory for short options too.

  -z, --compress      force compression
  -d, --decompress    force decompression
  -t, --test          test compressed file integrity
[…]

Both are ELF64 executables, which use the same interpreter:
Code:
$ file patchelf-uninative
./tmp/sysroots-uninative/x86_64-linux/usr/bin/patchelf-uninative: ELF 64-bit LSB pie executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /home/hsebert/yocto-quick/bitbake-builds/poky-whinlatter/build/tmp/sysroots-uninative/x86_64-linux/lib/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=fa6bb1aa57e4bf13cb8a2a871c517bb1175d2efe, stripped
respectively:
Code:
$ file xz
./tmp/work/x86_64-linux/libmpc-native/1.3.1/recipe-sysroot-native/usr/bin/xz: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /home/hsebert/yocto-quick/bitbake-builds/poky-whinlatter/build/tmp/sysroots-uninative/x86_64-linux/lib/ld-linux-x86-64.so.2, BuildID[sha1]=546d96d955e90e95033f5c5fdb7972184dbcdad2, for GNU/Linux 3.2.0, stripped

However, one is „version 1 (GNU/Linux)” and the other is „version 1 (SYSV)”. I have no clue what this means!

diff'ing the output of readelf yields the following:
Code:
--- readelf.patchelf_uninative.txt      2026-02-04 22:24:57.239546000 +0000
+++ readelf.xz.txt      2026-02-04 22:25:15.001554000 +0000
@@ -1,94 +1,90 @@
 ELF Header:
-  Magic:   7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00 
+  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
   Class:                             ELF64
   Data:                              2's complement, little endian
   Version:                           1 (current)
-  OS/ABI:                            UNIX - GNU
+  OS/ABI:                            UNIX - System V
   ABI Version:                       0
   Type:                              DYN (Position-Independent Executable file)
   Machine:                           Advanced Micro Devices X86-64
   Version:                           0x1
-  Entry point address:               0x5320
+  Entry point address:               0x5160
   Start of program headers:          64 (bytes into file)
-  Start of section headers:          253952 (bytes into file)
+  Start of section headers:          99152 (bytes into file)
   Flags:                             0x0
   Size of this header:               64 (bytes)
   Size of program headers:           56 (bytes)
-  Number of program headers:         15
+  Number of program headers:         13
   Size of section headers:           64 (bytes)
-  Number of section headers:         31
-  Section header string table index: 27
+  Number of section headers:         29
+  Section header string table index: 28

Does anyone know what is going on here?

PS: On native Ubuntu hosts both executables work fine, it's just in the Linuxulator environment.
 
I rebranded the ELF from outside the jail using brandelf -f 0 <path-to-file>.

The output of file does indeed change to “SYSV”, but I keep getting the same error:
Code:
$ file patchelf-uninative
/home/hsebert/yocto-quick/bitbake-builds/poky-whinlatter/build/tmp/sysroots-uninative/x86_64-linux/usr/bin/patchelf-uninative: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /home/hsebert/yocto-quick/bitbake-builds/poky-whinlatter/build/tmp/sysroots-uninative/x86_64-linux/lib/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=fa6bb1aa57e4bf13cb8a2a871c517bb1175d2efe, stripped

Code:
$ ./patchelf-uninative
Invalid PT_INTERP
-bash: /home/hsebert/yocto-quick/bitbake-builds/poky-whinlatter/build/tmp/sysroots-uninative/x86_64-linux/usr/bin/patchelf-uninative: cannot execute binary file: Exec format error

Edit: Could this be some security thing due to wrong checksums?

Edit: I played around with the kern.elf64.fallback_brand sysctl, but it didn't help.
 
Ok, I think I found the problem …

The two binaries patchelf-uninative and xz come from different sources. The latter is built properly by the Yocto build system. The former, however, comes from a binary tarball which is downloaded during the build process. It is called the “uninative binary shim”.

This tarball contains broken (sic!) executables which are supposed to be “fixed” by a Python script somewhere deep in the Yocto tree. This script is called relocate_sdk.py. This script fiddles around with the ELF64 header (sets INTERP and RPATH), but apparently no throughly enough. The result is that the binaries in this “shim” remain broken.

For some reason, Yocto avoids using patchelf from the Ubuntu host, which can easily be installed by apt install patchelf.

Anyway, the following two simple commands do correctly, what that dubious Python script should have been doing in the first place:
Code:
cd […]/bitbake-builds/poky-whinlatter/build/tmp/sysroots-uninative/x86_64-linux
patchelf --set-interpreter $(realpath ./lib/ld-linux-x86-64.so.2) ./usr/bin/patchelf-uninative
patchelf --set-rpath $(realpath ./lib):$(realpath ./usr/lib) ./usr/bin/patchelf-uninative

I wonder why this works on native Linux??

Anyway, next step would be to fix Yocto into using the host's patchelf command instead of some home-brewn Python nonsense.
 
Back
Top