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

Support raw-dylib functions being used inside inlined functions #102988

Merged
merged 1 commit into from
Oct 25, 2022

Conversation

dpaoliello
Copy link
Contributor

Fixes #102714

Issue Details:
When generating the import library for raw-dylib symbols, we currently only use the functions and variables declared within the current crate. This works fine if all crates are static libraries or rlibs as the generated import library will be contained in the static library or rlib itself, but if a dependency is a dynamic library AND the use of a raw-dylib function or variable is inlined or part of a generic instantiation then the current crate won't see its dependency's import library and so linking will fail.

Fix Details:
Instead, when we generate the import library for a dylib or bin crate, we will now generate it for the symbols both for the current crate and all upstream crates. We do this in two steps so that the import library for the current crate is passed into the linker first, thus it is preferred if there are any ambiguous symbols.

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Oct 12, 2022
@rustbot
Copy link
Collaborator

rustbot commented Oct 12, 2022

Some changes occurred in compiler/rustc_codegen_gcc

cc @antoyo

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

@rust-highfive
Copy link
Collaborator

r? @davidtwco

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Oct 12, 2022
@dpaoliello
Copy link
Contributor Author

r? @michaelwoerister

@michaelwoerister
Copy link
Member

Thanks, @dpaoliello! I'm in the process of reviewing this.

@petrochenkov
Copy link
Contributor

petrochenkov commented Oct 20, 2022

This issue exists for all kinds on native libraries, not only raw dylibs.

If we have a tree like this

- Final executable
  - Rust dylib
    - Native dylib
    - Native raw dylib
    - Native staticlib

then the "Rust dylib" can leak symbols from all the native libs through inline/const/generic functions.

For this reason

  • Native dylibs have to be linked into the final binary even if they were already linked into the intermediate Rust dylib (rustc already does this for long time).
  • Native raw dylibs have to be linked into the final binary even if they were already linked into the intermediate Rust dylib (this PR implement it).
  • Not sure what happens with native staticlibs, does Rust dylib just always export their symbols so they are available from the Rust dylib in case of inlining?

Also, what happens with Rust dylib dependencies of the second order (Final executable -> Rust dylib -> Rust dylib -> Native libs)? Are they also always linked into the final binary (together with their native dependencies)? UPD: Yes, they are.

This all feels suboptimal.
Perhaps we need an analysis that determines which exactly native symbols are leaked through inline/const/generic functions, and which exactly libraries need to be linked into the final binary due to them.
We are already doing something similar when calculating export symbols sets.

@bjorn3
Copy link
Member

bjorn3 commented Oct 20, 2022

Not sure what happens with native staticlibs, does Rust dylib just always export their symbols so they are available from the Rust dylib in case of inlining?

I believe it exports all functions which you declared in extern "C" { ... } where you actually used #[link(name = "...")] to indicate what library it originated from.

@michaelwoerister
Copy link
Member

Perhaps we need an analysis that determines which exactly native symbols are leaked through inline/const/generic functions, and which exactly libraries need to be linked into the final binary due to them.

@petrochenkov, to make sure I understand this correctly: you propose to do pretty much the same as this PR, but generate import libraries that only contain the symbols that are actually needed?

@petrochenkov
Copy link
Contributor

@michaelwoerister
Yes, and do the same thing for dylibs and staticlibs too.
Not in this PR, of course.

@rustbot rustbot added the A-testsuite Area: The testsuite used to check the correctness of rustc label Oct 20, 2022
@michaelwoerister
Copy link
Member

@michaelwoerister Yes, and do the same thing for dylibs and staticlibs too. Not in this PR, of course.

Yes, that sounds reasonable to me. Although there is a trade-off between the additional complexity this might introduce in rustc (not sure how complex it would actually be) and the gains we might expect from generating more targeted import libs. I'd guess, there's no way of telling without giving it a try.

But yes, not in this PR.

@michaelwoerister
Copy link
Member

Thanks for the PR, @dpaoliello! The implementation looks good to me :)

It would be great to add another test for the transitive case @petrochenkov mentions, i.e. executable -> dylib -> dylib -> native raw dylib. That should be achievable by adding another Rust dylib with a public #[inline] function that in turn calls inline_library_function().

@dpaoliello
Copy link
Contributor Author

Thanks for the PR, @dpaoliello! The implementation looks good to me :)

It would be great to add another test for the transitive case @petrochenkov mentions, i.e. executable -> dylib -> dylib -> native raw dylib. That should be achievable by adding another Rust dylib with a public #[inline] function that in turn calls inline_library_function().

Added this test case.

@rust-log-analyzer

This comment has been minimized.

@michaelwoerister
Copy link
Member

Thanks, @dpaoliello!
@bors r+

@bors
Copy link
Contributor

bors commented Oct 24, 2022

📌 Commit db52b64b672c489823d760e87faa48a6e33d34cd has been approved by michaelwoerister

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 24, 2022
@wesleywiser wesleywiser added the beta-nominated Nominated for backporting to the compiler in the beta channel. label Oct 24, 2022
@bors
Copy link
Contributor

bors commented Oct 24, 2022

⌛ Testing commit db52b64b672c489823d760e87faa48a6e33d34cd with merge 5edf6a1ac36d232f1e8be86f64d64bf79e92c9f9...

@bors
Copy link
Contributor

bors commented Oct 24, 2022

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Oct 24, 2022
@rust-log-analyzer

This comment has been minimized.

@wesleywiser
Copy link
Member

Looks like the added test just needs to be updated to account for raw-dylib being unstable on x86.

@bors delegate+

@bors
Copy link
Contributor

bors commented Oct 24, 2022

✌️ @dpaoliello can now approve this pull request

@dpaoliello
Copy link
Contributor Author

@bors r+

@bors
Copy link
Contributor

bors commented Oct 24, 2022

📌 Commit 3a1ef50 has been approved by dpaoliello

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 24, 2022
@bors
Copy link
Contributor

bors commented Oct 25, 2022

⌛ Testing commit 3a1ef50 with merge 31d754a...

@bors
Copy link
Contributor

bors commented Oct 25, 2022

☀️ Test successful - checks-actions
Approved by: dpaoliello
Pushing 31d754a to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Oct 25, 2022
@bors bors merged commit 31d754a into rust-lang:master Oct 25, 2022
@rustbot rustbot added this to the 1.66.0 milestone Oct 25, 2022
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (31d754a): comparison URL.

Overall result: ✅ improvements - no action needed

@rustbot label: -perf-regression

Instruction count

This is a highly reliable metric that was used to determine the overall result at the top of this comment.

mean1 range count2
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-1.1% [-1.1%, -1.1%] 1
All ❌✅ (primary) - - 0

Max RSS (memory usage)

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean1 range count2
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
3.9% [2.3%, 5.4%] 2
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) - - 0

Cycles

This benchmark run did not return any relevant results for this metric.

Footnotes

  1. the arithmetic mean of the percent change 2

  2. number of relevant changes 2

@pnkfelix
Copy link
Member

discussed in T-compiler meeting today

beta backport approved, with expectation that it will be part of Rust 1.65 that goes out in one week.

@rustbot label: beta-accepted

@rustbot rustbot added the beta-accepted Accepted for backporting to the compiler in the beta channel. label Oct 27, 2022
@Mark-Simulacrum Mark-Simulacrum modified the milestones: 1.66.0, 1.65.0 Oct 29, 2022
@Mark-Simulacrum Mark-Simulacrum removed the beta-nominated Nominated for backporting to the compiler in the beta channel. label Oct 29, 2022
bors added a commit to rust-lang-ci/rust that referenced this pull request Oct 29, 2022
…mulacrum

[beta] backport rollup

* poll_fn and Unpin: fix pinning rust-lang#102737
* Support raw-dylib functions being used inside inlined functions rust-lang#102988
* Fix line numbers for MIR inlined code rust-lang#103071
* Add architectures to fn create_object_file rust-lang#103240
* Add eval hack in super_relate_consts back rust-lang#103279
* Mark std::os::wasi::io::AsFd etc. as stable. rust-lang#103308
* Truncate thread names on Linux and Apple targets rust-lang#103379
* Do not consider repeated lifetime params for elision. rust-lang#103450
* rustdoc: add missing URL redirect rust-lang#103588
* Remove commit_if_ok probe from NLL type relation rust-lang#103601

Also includes a copy of the release notes.

r? `@ghost`
@dpaoliello dpaoliello deleted the inlinerawdylib branch January 16, 2024 18:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-testsuite Area: The testsuite used to check the correctness of rustc beta-accepted Accepted for backporting to the compiler in the beta channel. merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

raw-dylib imports not being linked when inlined from a dylib