-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Force linker to link in exported symbols #95363
Conversation
r? @oli-obk (rust-highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
I have been experimenting a more advanced approach for ELF targets using a customly generated object file and it seems working well; though I didn't make much progress due to lack of time recently. |
There's kind of a race condition between our work, because this is almost exactly what I planned to implement today-tomorrow to address the question (2) from #93901 (comment). Except that I primarily care about dylibs (as described in the linked comment), so the issue with garbage-collecting
Generating a "root" object file with artificial references to all exported symbols may be the most general solution, because it looks like it should work for both dylib and executable cases (and would allow GCing |
Hmm I see this issue: #84161 at the same time. Given Is there anything wrong with mapping |
I'm going to implement these semantics right now, but I'm sure they'll be wrong somewhere.
I'm not actually going to touch the RFC 2841 part or dylibs, but I think those semantics should cover everything. |
Ok implemented the first part of the above. There's a lot of todos and fixmes thrown around here as there needs to be a refactor or two, but this uses implicit linker scripts (for GCC) and command files (for LINK) to forcibly link stuff. This is implemented for dylibs currently (and dylibs were the reason I had to switch to files and not args), but I've kept the whole-archive stuff in place so idk if it does anything. |
This comment has been minimized.
This comment has been minimized.
This is just heuristics, not a comprehensive fix, isn't it?
Mapping The best approach that I can think of so far is still a custom-generated object file. I think it could be a universal solution, without need of any heuristics or special handling of |
I feel like it's a comprehensive fix, but I'm not sure. I can't come up with a counterexample right now other than |
For binaries, this would still cause some statics (
It'll just need to use the same list of symbols that is used in version scripts. |
For executables this is ignored: https://github.com/rust-lang/rust/pull/95363/files#diff-3f87e69f5e21712681d6fca5b6b70542c10eaf49bf48ff16445ddd17f1ae6dadR666 |
This wasn't exactly correct before, but it is now. We forcefully link all
This has nothing to do with custom linker scripts I think, because those happen before any of this? The main use case I'm thinking of is this one and #47384 (comment), wherein symbols that are manually |
This comment has been minimized.
This comment has been minimized.
Let me give a concrete example, let's say we have #[no_mangle]
#[link_section = ".foo"]
fn foo() {
/* ... */
} and extern "C" {
fn bar();
}
fn main() {
unsafe { bar() };
} in different rlibs, and have
in my linker script, then function |
Would #85673 fix your usecase? |
Well, if you force export symbols in executables then unused |
Can I get a perf run now, or do I have to figure out this reproducible build error first? |
GC'ing |
@bors try @rust-timer queue |
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
⌛ Trying commit dcb04599563adea275423429e713281ce536a71a with merge 56920da24004deccd76240cb6a49806fd8cf0369... |
This comment has been minimized.
This comment has been minimized.
⌛ Trying commit 9a5e1ff2eead8ae7c03ce12420421fe7ff8197dc with merge 4ffb3425b6816cb1e2e5a9cb6ccd63c9ab15ff33... |
☀️ Try build successful - checks-actions |
Queued 4ffb3425b6816cb1e2e5a9cb6ccd63c9ab15ff33 with parent 99da9ae, future comparison URL. |
Finished benchmarking commit (4ffb3425b6816cb1e2e5a9cb6ccd63c9ab15ff33): comparison url. Summary:
If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR led to changes in compiler perf. @bors rollup=never Footnotes |
Performance is ok, but the |
I'll get to reviewing this next weekend most likely, I need to read #47384 and look at some code in rustc generating export lists, to understand what different cases exists. I'm also still interested in landing some simple solution addressing only dylibs sooner to unblock stabilization of the |
Yeah I'm not sure what to do for The reason is I have to inject a synthetic file that didn't previously exist: The actual contents of the file are identical however as the function that creates it is deterministic, so I don't think the output is still reproducible. I don't know what this is testing, nor can I reasonably put
|
Marking as blocked on #95604 for now, with an intent to close when/if it lands. |
9a5e1ff
to
d4acac9
Compare
Generate synthetic object file to ensure all exported and used symbols participate in the linking Fix rust-lang#50007 and rust-lang#47384 This is the synthetic object file approach that I described in rust-lang#95363 (comment), allowing all exported and used symbols to be linked while still allowing them to be GCed. Related rust-lang#93791, rust-lang#95363 r? `@petrochenkov` cc `@carbotaniuman`
Generate synthetic object file to ensure all exported and used symbols participate in the linking Fix rust-lang#50007 and rust-lang#47384 This is the synthetic object file approach that I described in rust-lang#95363 (comment), allowing all exported and used symbols to be linked while still allowing them to be GCed. Related rust-lang#93791, rust-lang#95363 r? ``@petrochenkov`` cc ``@carbotaniuman``
Generate synthetic object file to ensure all exported and used symbols participate in the linking Fix rust-lang#50007 and rust-lang#47384 This is the synthetic object file approach that I described in rust-lang#95363 (comment), allowing all exported and used symbols to be linked while still allowing them to be GCed. Related rust-lang#93791, rust-lang#95363 r? ```@petrochenkov``` cc ```@carbotaniuman```
Generate synthetic object file to ensure all exported and used symbols participate in the linking Fix rust-lang#50007 and rust-lang#47384 This is the synthetic object file approach that I described in rust-lang#95363 (comment), allowing all exported and used symbols to be linked while still allowing them to be GCed. Related rust-lang#93791, rust-lang#95363 r? `@petrochenkov` cc `@carbotaniuman`
Generate synthetic object file to ensure all exported and used symbols participate in the linking Fix rust-lang#50007 and rust-lang#47384 This is the synthetic object file approach that I described in rust-lang#95363 (comment), allowing all exported and used symbols to be linked while still allowing them to be GCed. Related rust-lang#93791, rust-lang#95363 r? `@petrochenkov` cc `@carbotaniuman`
Generate synthetic object file to ensure all exported and used symbols participate in the linking Fix rust-lang#50007 and rust-lang#47384 This is the synthetic object file approach that I described in rust-lang#95363 (comment), allowing all exported and used symbols to be linked while still allowing them to be GCed. Related rust-lang#93791, rust-lang#95363 r? `@petrochenkov` cc `@carbotaniuman`
The more surgical variant of #93791, which uses linker args
-u
on Unix and/INCLUDE
on Windows to forcefully include exported symbols.This allows statics like this to work (and get embedded in the final executable):
@nbdd0121 I've copied your test wholesale, feel free to review. I'm not sure if this handles all the edge cases, and I'd love a test for crate-type=bin.