rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.34k stars 12.72k forks source link

Rust not specifying Tag_ABI_VFP_args on some objects #99542

Open darbysauter opened 2 years ago

darbysauter commented 2 years ago

I’m trying to compile a static lib for armv7 to link with a C project. Targeting cortex r5 with vfp3d16 and armv7r-none-eabihf. But it fails to link with the cproject citing an object from the static lib “has a Tag_ABI_VFP_args attribute “0” that is different than previously seen “1”

This happens because some of the objects don’t specify it. 248 of the objects do specify 1 and the rest of the 277 don’t specify any (defaults to 0) some of the files include udivmodsi4.o umodsi3.o switch16.o

My question is, is this an issue with the custom linker I am using (should it accept mismatched tags) or should rust be setting these all to 1? Or is it something I am doing wrong. My intuition thinks these objects should specify Tag_ABI_VFP_args = 1 since setting to none aka 0 is a different setting.

Meta

rustc --version --verbose:

rustc 1.51.0 (2fd73fabe 2021-03-23)
binary: rustc
commit-hash: 2fd73fabe469357a12c2c974c140f67e7cdd76d0
commit-date: 2021-03-23
host: x86_64-apple-darwin
release: 1.51.0
LLVM version: 11.0.1

workingjubilee commented 2 years ago

Some of the built objects in question may need to specify Tag_ABI_VFP_args = 3, which is a declaration that the flag should be ignored (implicitly: because it is irrelevant). I believe some of the objects you mention are integer-only objects, in which case emitting 3 would be correct.

darbysauter commented 2 years ago

yeah sounnds like a reasonable solution. I ended up going to nightly and there were less objects failing. And then i added the crate: https://github.com/rust-lang/compiler-builtins

And now my project compiles fine

workingjubilee commented 1 month ago

Arm's ABI-level ELF attrs: https://github.com/ARM-software/abi-aa/blob/a82eef0433556b30539c0d4463768d9feb8cfd0b/addenda32/addenda32.rst#336procedure-call-related-attributes

Tag_ABI_HardFP_use, (=27), uleb128
    0  The user intended that FP use should be implied by Tag_FP_arch
    1  The user intended this code to execute on the single-precision variant
       derived from Tag_FP_arch
    2  Reserved
    3  The user intended that FP use should be implied by Tag_FP_arch
       (Note: This is a deprecated duplicate of the default encoded by 0)

Tag_ABI_VFP_args, (=28), uleb128
    0  The user intended FP parameter/result passing to conform to AAPCS, base variant
    1  The user intended FP parameter/result passing to conform to AAPCS, VFP variant
    2  The user intended FP parameter/result passing to conform to toolchain-specific
       conventions
    3  Code is compatible with both the base and VFP variants; the user did not permit
       non-variadic functions to pass FP parameters/results

Tag_ABI_WMMX_args, (=29), uleb128
    0  The user intended WMMX parameter/result passing conform to the AAPCS, base variant
    1  The user intended WMMX parameter/result passing conform to Intel’s WMMX conventions
    2  The user intended WMMX parameter/result passing conforms to toolchain-specific
       conventions

Interesting note from here: https://github.com/ARM-software/abi-aa/blob/a82eef0433556b30539c0d4463768d9feb8cfd0b/addenda32/addenda32.rst#3113no-standard-compatibility-model

3.1.1.3 No standard compatibility model

This specification standardizes the meaning of build attributes, not the compatibility models within which they will be interpreted.

For the majority of build attributes there is only one reasonable interpretation of compatibility among their values, and it is an obvious one.

For a minority – mostly associated with procedure-call compatibility between functions – this is not the case and it is reasonable for different toolchains to take different positions according to the markets they serve.

Thus it is entirely reasonable that a relocatable file produced by toolchain A and accepted by toolchain B’s linker might be rejected by toolchain C’s linker when targeting exactly the same environment as toolchain B.

Our hope and intention for attributes is that they might prevent C’s linker from accepting the output of A and silently generating a non functioning executable file or failing in a mysterious and difficult to explain manner.