Search code examples
rustarmtarget

Why am I getting a VFP register arguments while adding a custom target to rust (arm-unknown-linux-uclibceabihf)?


I am following the guide from the last rust newsletter: https://rust-embedded.github.io/embedonomicon/custom-target.html and encounter an issue related to soft/hard float configuration.

I created my new target by merging the mipsel-unknown-linux-uclibc.json with the arm-unknown-linux-gnueabihf.json to obtain the following result:

{
  "arch": "arm",
  "data-layout": "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
  "dynamic-linking": true,
  "env": "uclibc",
  "executables": true,
  "features": "+strict-align,+v6,+vfp2",
  "has-elf-tls": true,
  "has-rpath": true,
  "is-builtin": false,
  "linker-flavor": "gcc",
  "linker-is-gnu": true,
  "linker": "/home/ykoehler/work/tools/arm-5.3-uclibc-1.0.12/usr/bin/arm-buildroot-linux-uclibcgnueabihf-gcc",
  "llvm-target": "arm-unknown-linux-uclibceabihf",
  "max-atomic-width": 64,
  "os": "linux",
  "position-independent-executables": true,
  "pre-link-args": {
    "gcc": [
      "-Wl,--as-needed",
      "-Wl,-z,noexecstack"
    ]
  },
  "relro-level": "full",
  "target-c-int-width": "32",
  "target-endian": "little",
  "target-family": "unix",
  "target-mcount": "_mcount",
  "target-pointer-width": "32",
  "vendor": "unknown"
}

When I compile a no-std app with cargo using the new custom target:

cargo build -Z build-std=core --target arm-unknown-linux-uclibceabihf.json

I am getting the following error:

   Compiling app v0.1.0 (/home/ykoehler/work/app)
error: linking with `/home/ykoehler/work/tools/arm-5.3-uclibc-1.0.12/usr/bin/arm-buildroot-linux-uclibcgnueabihf-gcc` failed: exit code: 1
  |
  = note: "/home/ykoehler/work/tools/arm-5.3-uclibc-1.0.12/usr/bin/arm-buildroot-linux-uclibcgnueabihf-gcc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-Wl,--eh-frame-hdr" "-L" "/home/ykoehler/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/arm-unknown-linux-uclibceabihf/lib" "/home/ykoehler/work/app/target/arm-unknown-linux-uclibceabihf/release/deps/app-92459304df1651f0.app.2jjler86-cgu.0.rcgu.o" "-o" "/home/ykoehler/work/app/target/arm-unknown-linux-uclibceabihf/release/deps/app-92459304df1651f0" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro" "-Wl,-znow" "-Wl,-O1" "-nodefaultlibs" "-L" "/home/ykoehler/work/app/target/arm-unknown-linux-uclibceabihf/release/deps" "-L" "/home/ykoehler/work/app/target/release/deps" "-L" "/home/ykoehler/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/arm-unknown-linux-uclibceabihf/lib" "-Wl,-Bstatic" "/home/ykoehler/work/app/target/arm-unknown-linux-uclibceabihf/release/deps/librustc_std_workspace_core-375ea25c872246b5.rlib" "/home/ykoehler/work/app/target/arm-unknown-linux-uclibceabihf/release/deps/libcore-34e07d1b528fc142.rlib" "/home/ykoehler/work/app/target/arm-unknown-linux-uclibceabihf/release/deps/libcompiler_builtins-a34a2e58700fb5e5.rlib" "-Wl,-Bdynamic"
  = note: /home/ykoehler/work/tools/arm-5.3-uclibc-1.0.12/usr/bin/../lib/gcc/arm-buildroot-linux-uclibcgnueabihf/5.3.0/../../../../arm-buildroot-linux-uclibcgnueabihf/bin/ld: error: /home/ykoehler/work/app/target/arm-unknown-linux-uclibceabihf/release/deps/app-92459304df1651f0 uses VFP register arguments, /home/ykoehler/work/app/target/arm-unknown-linux-uclibceabihf/release/deps/app-92459304df1651f0.app.2jjler86-cgu.0.rcgu.o does not
          /home/ykoehler/work/tools/arm-5.3-uclibc-1.0.12/usr/bin/../lib/gcc/arm-buildroot-linux-uclibcgnueabihf/5.3.0/../../../../arm-buildroot-linux-uclibcgnueabihf/bin/ld: failed to merge target specific data of file /home/ykoehler/work/app/target/arm-unknown-linux-uclibceabihf/release/deps/app-92459304df1651f0.app.2jjler86-cgu.0.rcgu.o
          /home/ykoehler/work/tools/arm-5.3-uclibc-1.0.12/usr/arm-buildroot-linux-uclibcgnueabihf/sysroot/usr/lib/Scrt1.o: In function `_start':
          /var/tmp/tool-chains/buildroot-2016.02-5.3-arm/src/buildroot-2016.02/output/build/uclibc-1.0.12/libc/sysdeps/linux/arm/crt1.S:217: undefined reference to `__uClibc_main'
          /var/tmp/tool-chains/buildroot-2016.02-5.3-arm/src/buildroot-2016.02/output/build/uclibc-1.0.12/libc/sysdeps/linux/arm/crt1.S:235: undefined reference to `abort'
          /var/tmp/tool-chains/buildroot-2016.02-5.3-arm/src/buildroot-2016.02/output/build/uclibc-1.0.12/libc/sysdeps/linux/arm/crt1.S:235: undefined reference to `main'
          collect2: error: ld returned 1 exit status


error: aborting due to previous error

error: could not compile `app`.

To learn more, run the command again with --verbose.

This error indicate that some code is compiled with soft float usage when other part is using hard float, from reading over the net about the error message. Yet, both files specified by the error appears to have been generated by rust, and I am unclear why rust would generate any soft float code based on the information I provided inside the custom target definition file.

Any help appreciated.


Solution

  • I believe you just need to use arm-unknown-linux-gnueabihf for the llvm-target. The VFP error is related to the floating-point instruction set available (i.e. the hf in eabihf stands for Hard Float). I'm working on getting the armv7-unknown-linux-uclibceabihf target working in rust. I received the same VFP error while getting the armv7-unknown-linux-uclibceabihf target to work in rust and it turned out I just needed to use armv7-unknown-linux-gnueabihf for the llvm-target.

    Also, here's my spec file for armv7-unknown-linux-uclibceabihf for comparison:

    {
      "abi-blacklist": [
        "stdcall",
        "fastcall",
        "vectorcall",
        "thiscall",
        "win64",
        "sysv64"
      ],
      "arch": "arm",
      "data-layout": "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
      "dynamic-linking": true,
      "env": "uclibc",
      "executables": true,
      "features": "+v7,+vfp3,-d32,+thumb2,-neon",
      "has-elf-tls": true,
      "has-rpath": true,
      "linker-flavor": "gcc",
      "linker-is-gnu": true,
      "llvm-target": "armv7-unknown-linux-gnueabihf",
      "max-atomic-width": 64,
      "os": "linux",
      "position-independent-executables": true,
      "pre-link-args": {
        "gcc": [
          "-Wl,--as-needed",
          "-Wl,-z,noexecstack"
        ]
      },
      "relro-level": "full",
      "target-c-int-width": "32",
      "target-endian": "little",
      "target-family": "unix",
      "target-mcount": "\u0001__gnu_mcount_nc",
      "target-pointer-width": "32",
      "vendor": "unknown"
    }
    
    

    Cheers