Xilinx Zynq 7030 + Petalinux (Poky): Executable won't run

I've managed to compile rust-hello for the Xilinx Zynq platform. However, the resulting executable won't run on the target:

drwxr-xr-x    2 root     root          4096 Nov 18 15:18 .
drwx------    6 root     root          4096 Nov 18 15:15 ..
-rwxr-xr-x    1 root     root         11620 Nov 18 15:17 c_hello
-rwxr-xr-x    1 root     root       3154800 Nov 18 15:15 rust_hello
root@ctrl2019_1:~/rust# ./c_hello 
Hello world
root@ctrl2019_1:~/rust# ./rust_hello 
-sh: ./rust_hello: No such file or directory
root@ctrl2019_1:~/rust# 

My config.toml

[build]
target = "arm-unknown-linux-gnueabihf"

[target.arm-unknown-linux-gnueabihf]
linker = "arm-xilinx-linux-gnueabi-gcc"
ar = "arm-xilinx-linux-gnueabi-ar"
rustflags = [
  "-C","target-feature=a9,armv7-a,neon",
  "-C","target-cpu=cortex-a9",
  "-C","link-arg=-mcpu=cortex-a9",
  "-C","link-arg=-Wl,-soname=lib${NAME}.${VERSION}",
  "-C","link-arg=--sysroot=/home/vincent/local/sdk2019.1/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi"
]

Building and compiling go fine. What could be the problem?

Cheers,
Vincent

Such an error is pretty much always a matter of the dynamic linker / ELF interpreter not being present in the rootfs.

$ readelf -l $FILE | grep interpreter:
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]

Rust targets like arm-unknown-linux-gnueabihf expect a basic glibc linux environment with dynamic linking and C libraries.

1 Like

Thanks for your explanation. I now see indeed that it is requesting an interpreter I do not have.:

$ readelf -l target/arm-unknown-linux-gnueabihf/debug/rust_hello |grep interpreter
      [Requesting program interpreter: /lib/ld-linux.so.3]

on the target system:

root@ctrl2019_1:/lib# ls |grep linux
ld-linux-armhf.so.3

So, I created a symbolic link to ld-linux-armhf.so.3, and now it works! Apparently they're compatible. Thanks you for your great advise!

Final question: Am I using the wrong toolkit maybe? Why is it referring to a different library? I rather not want to add this symbolic link for production; I am not a 100% there two interpreters are compatible in every case. Any insight would be most helpful.

I think it would work as-is with rust target arm-unknown-linux-gnueabi instead of arm-unknown-linux-gnueabihf. I don't have any non-hf targets to check but most likely the dynamic linker name /lib/ld-linux.so.3 is the non-hardfloat one.

Careful: just because they link doesn't mean they're actually compatible at runtime. For example, if you build with a --target which includes gnu it's expecting that glibc will be present and will behave in certain ways. For example, rust on glibc gets its std::env::args from a nonstandard place, which is left as uninitialized memory in other libc implementation. This is just an example of what can go wrong; I'm sure there's others. However if your libc on the board is actually glibc, you might be ok! (There still might be differences between the headers you used at compile time and the built system which could bite you, though!)

The rust compiler will actually use the linker from poky, if you use it correctly.

The problem with the wrong linker is not just a rust problem, I had lots of issues with the poky SDK using the wrong dynamic linker name in some circumstances. C/C++ code using poky SDK is also using wrong linker name sometimes.

I did however not discover, why the poky linker fails to set the correct dynamic linker.

Tip:
Use rustc -Clink-args=--dynamic-linker=<CORRECT_LINKER>, and it will use the correct linker. You may want to add this linker argument to your .cargo/config.

Hi everyone,

I've now added the linker as @ruabmbua suggested. It now seems to work well and is actually using the correct dynamic linker reference.

For reference, this is now my .cargo/config:

[build]
target = "arm-unknown-linux-gnueabihf"

[target.arm-unknown-linux-gnueabihf]
linker = "arm-xilinx-linux-gnueabi-gcc"
ar = "arm-xilinx-linux-gnueabi-ar"
rustflags = [
  "-C","target-feature=a9,armv7-a,neon",
  "-C","target-cpu=cortex-a9",
  "-C","link-arg=-mcpu=cortex-a9",
  "-C","link-arg=-Wl,-soname=lib${NAME}.${VERSION}",
  "-C","link-arg=--sysroot=/home/vincent/local/sdk2019.1/sysroots/cortexa9t2hf-neon-xilinx-linux-gnueabi",
  "-C","link-arg=-Wl,--dynamic-linker=/lib/ld-linux-armhf.so.3"
]

[profile.release]
opt-level = "z"
lto = true
debug = false

Thanks for all the help! I'm open to any more suggestions for improvement, of course.

Cheers,
Vincent