Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some mixes of Rust with C/C++ are broken for arm64 mac and windows #92885

Closed
glandium opened this issue Jan 14, 2022 · 10 comments · Fixed by #93269
Closed

Some mixes of Rust with C/C++ are broken for arm64 mac and windows #92885

glandium opened this issue Jan 14, 2022 · 10 comments · Fixed by #93269
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. P-high High priority regression-from-stable-to-beta Performance or correctness regression from stable to beta. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Milestone

Comments

@glandium
Copy link
Contributor

After #88354, Firefox builds fail with e.g:

LLVM ERROR: Function Import: link error: linking module flags 'branch-target-enforcement': IDs have conflicting behaviors in '/builds/worker/workspace/obj-build/aarch64-pc-windows-msvc/release/gkrust_gtest.libnsstring-be03ad04cbf7bb1a.nsstring.ce1e3b11-cgu.0.rcgu.o571656940' and '../../../dom/media/webrtc/jsapi/Unified_cpp_media_webrtc_jsapi0.obj'

This happens when targeting arm64 macos or arm64 windows.

Not only did the default change and now diverges from clang (causing the above error when mixing objects from clang and rust), but it's also apparently not possible to disable the feature.

Note this also now reached beta.

Cc: @jacobbramley, @Jmc18134, @nagisa

@glandium glandium added C-bug Category: This is a bug. regression-untriaged Untriaged performance or correctness regression. labels Jan 14, 2022
@rustbot rustbot added the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Jan 14, 2022
@jacobbramley
Copy link
Contributor

It should be off by default. My first guess is that the problem is that we set the module flag unconditionally, but with a true/false value, so perhaps a false value is not equivalent to an unset value.

If that is the problem then there might be something deeper to investigate here, like some BTI mismatch between the Rust and C/C++ code that wasn't previously spotted. It would be interesting to know if the C/C++ code is compiled with BTI enabled.

I don't have Firefox (or recent Rust) build environment on my M1 Mac so it'll take me a while to reproduce. I'll make a start, but if others can get there first and unblock this quickly, then please do! We could also revert #88354 from beta whilst we investigate. I'm not sure of the process there.

@glandium
Copy link
Contributor Author

It most probably involves linker-plugin-lto. A default firefox build wouldn't enable that. I suspect it's reproducible with a simple testcase that has both C and C++ code with linker-plugin-lto enabled.

@glandium
Copy link
Contributor Author

(beware of #60059 if you try to use linker-plugin-lto)

@glandium
Copy link
Contributor Author

Ok, I was also able to reproduce locally with a Linux aarch64 cross-build (modulo https://bugzilla.mozilla.org/show_bug.cgi?id=1749852) and it turns out the rust llvm-ir has:

1597 = !{i32 2, !"branch-target-enforcement", i32 0}
!1598 = !{i32 2, !"sign-return-address", i32 0}
!1599 = !{i32 2, !"sign-return-address-all", i32 0}
!1600 = !{i32 2, !"sign-return-address-with-bkey", i32 0}

while the clang llvm-ir has:

!6 = !{i32 1, !"branch-target-enforcement", i32 0}
!7 = !{i32 1, !"sign-return-address", i32 0}
!8 = !{i32 1, !"sign-return-address-all", i32 0}
!9 = !{i32 1, !"sign-return-address-with-bkey", i32 0}

llvm-ir from older versions of rust didn't have them at all.

@jacobbramley
Copy link
Contributor

jacobbramley commented Jan 14, 2022

llvm-ir from older versions of rust didn't have them at all.

Nor does the llvm-ir from older versions of clang — at least the one I have pre-built — so the simple idea of marking them as 1 (error-on-mismatch) to match the newer clang might cause different problems.

@Mark-Simulacrum Mark-Simulacrum added this to the 1.59.0 milestone Jan 14, 2022
@Mark-Simulacrum Mark-Simulacrum added regression-from-stable-to-beta Performance or correctness regression from stable to beta. and removed regression-untriaged Untriaged performance or correctness regression. labels Jan 14, 2022
@glandium
Copy link
Contributor Author

the simple idea of marking them as 1 (error-on-mismatch) to match the newer clang might cause different problems.

why do you think so? the llvm-ir that doesn't contain these flags at all links fine with the llvm-ir that does (even with behavior set to Error).

@jacobbramley
Copy link
Contributor

the simple idea of marking them as 1 (error-on-mismatch) to match the newer clang might cause different problems.

why do you think so? the llvm-ir that doesn't contain these flags at all links fine with the llvm-ir that does (even with behavior set to Error).

It was my own (naive) assumption, based on how BTI itself works: it's not correct to treat non-BTI machine code as BTI because if it lacks the BTI instructions it will be impossible to call any of its functions. However, that's not particularly relevant as this logic is all resolved before code generation.

That leaves two candidate solutions, then:

  1. Use error-on-mismatch for these flags. This is nice because it catches configuration mismatches, and will be compatible with Clang and LTO.
  2. Don't emit these flags at all if they aren't enabled. This most closely matches the existing (stable) behaviour but means that configuration mismatches (or compatibility issues like this one) may be missed.

Given the behaviour you described, and the LTO compatibility statement — "Best results are achieved by using a rustc and clang that are based on the exact same version of LLVM" — I think we can reasonably prefer option 1.

I'll start working on that today.

@apiraino apiraino added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 20, 2022
@apiraino
Copy link
Contributor

Assigning priority as discussed in the Zulip thread of the Prioritization Working Group.

@rustbot label -I-prioritize +P-high

@rustbot rustbot added P-high High priority and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Jan 22, 2022
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jan 25, 2022
…petrochenkov

Use error-on-mismatch policy for PAuth module flags.

This agrees with Clang, and avoids an error when using LTO with mixed
C/Rust. LLVM considers different behaviour flags to be a mismatch,
even when the flag value itself is the same.

This also makes the flag setting explicit for all uses of
LLVMRustAddModuleFlag.

----

I believe that this fixes rust-lang#92885, but have only reproduced it locally on Linux hosts so cannot confirm that it fixes the issue as reported.

I have not included a test for this because it is covered by an existing test (`src/test/run-make-fulldeps/cross-lang-lto-clang`). It is not without its problems, though:
* The test requires Clang and `--run-clang-based-tests-with=...` to run, and this is not the case on the CI.
   * Any test I add would have a similar requirement.
* With this patch applied, the test gets further, but it still fails (for other reasons). I don't think that affects rust-lang#92885.
@bors bors closed this as completed in 13b87d8 Jan 25, 2022
nagisa added a commit to nagisa/rust that referenced this issue Jan 31, 2022
@Mark-Simulacrum
Copy link
Member

Reopening to track beta fix (proposed in #93523).

bors added a commit to rust-lang-ci/rust that referenced this issue Feb 2, 2022
… r=Mark-Simulacrum

beta: Revert -Zbranch-protection

This reverts commit d331cb7, reversing
changes made to 78fd0f6.

This fixes rust-lang#92885 as discussed on Zulip[1].

[1] https://zulip-archive.rust-lang.org/stream/238009-t-compiler/meetings/topic/.5Bweekly.5D.202022-01-27.20.2354818.html#269588396

r? `@Mark-Simulacrum`
@pnkfelix
Copy link
Member

pnkfelix commented Feb 3, 2022

resolved by #93523 (on beta), #93269 on master

@pnkfelix pnkfelix closed this as completed Feb 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. P-high High priority regression-from-stable-to-beta Performance or correctness regression from stable to beta. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants