-
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
no_mangle
/used
static is only present in output when in reachable module
#47384
Comments
cc @oli-obk |
Doesn’t seem like a bug to me. The library In your scenario it is entirely up to Rust whether:
|
IIRC, @joshtriplett reported that lang team discussed this a few months ago and decided to make link-time visibility of |
@petrochenkov I recall that as well, and that sounds accurate. |
IIRC we tried both the used attribute and making it public and it gave us the same behaviour. |
Yes, // src/lib.rs
#![feature(used)]
pub mod foo {
#[no_mangle]
#[used]
pub static STATIC: [u32; 10] = [1; 10];
pub fn hello() {}
}
pub fn bar() {
foo::hello(); // STATIC not present if commented out
} Edit: I updated the title and the issue description to reflect this. |
no_mangle
static is only present in output when in reachable moduleno_mangle
/used
static is only present in output when in reachable module
So @japaric explained that this is a problem with our linker script and has nothing to do with the |
Reopening because people continue to have problems with |
FYI I managed to work around this in my case by doing the following:
Realistically, this is not a long-term solution - the first step is reasonable, but steps 2 and 3 are just hacks. There's no reason the symbol should have to be given an unmangled name, and definitely no reason the binary should have to pollute its own code to work around unusual linker behaviour. Additionally, some of the time
|
That should be fixed on master, can you confirm that it is fixed for you now? |
I ran into this issue today, and strangely only in debug builds. With [profile.dev]
incremental = false |
This issue is still present for me on rustc 1.45.1. It occurs in release mode both with and without LTO. Using Comment out the Declaration of the static: https://github.com/Shnatsel/rust-audit/blob/master/auditable/src/lib.rs |
If anyone read my last message, I think that's just my computer getting hit by cosmic rays/some hardware bug, because trying to reproduce the fix led to cascading failures across my Linux install, sigh, so much time wasted. Sorry for any noise. Running everything again on my laptop now and the case where you're including a static into the final |
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`
Fixes linker errors in an application that is linked to `r3_port_riscv` and does not use the `riscv-rt`-compatible startup routine provided by `r3_port_riscv::use_rt!`. Rust implements `rlib`s as static libraries (archives). Linkers treat archives differently from object files: all object files participate in linking, while archives will only participate in linking if they can satisfy at least one undefined reference (version scripts don't count). This means that in an application that does not use `use_rt!`, `libriscv_rt*.rlib` does not participate in linking at all. This behavior also causes `#[no_mangle]` and `#[used]` items to be ignored by the linker (`KEEP` in linker scripts can't keep them either), leading to a long-standing bug in Rust ([rust-lang/rust#47384][2]). The situation changed with the merge of [rust-lang/rust#95604][1]. To fix [rust-lang/rust#47384][2], this PR introduced a synthetic object file containing references to all symbols pertaining to `#[no_mangle]` and `#[used]` items. `libriscv_rt*.rlib` now participates in linking, but the expectation is that `--gc-sections` will remove unused items in the end, unless they are explicitly retained by `KEEP` in linker scripts or other means. This change unexpectedly caused breakage in the tests for `qemu_sifive_u _s_rv(64,32)` targets, which use a custom startup routine instead of `use_rt!`. For some reason, the linker didn't respect `--gc-sections` for some items from `libriscv_rt*.rlib` and decided to include them in the output binary. These items reference symbols that are defined by the `riscv-rt` linker script, which isn't used by `qemu_sifive_u_s_ rv(64,32)` targets, hence the linker error. The thing is, `riscv-rt` outputs these items in the `.init` section[3], which is one of the section names hard-coded in LLD[4] to be excluded from `--gc-sections`. As a result, these items were considered for inclusion despite being referenced from nowhere. This commit works around this problem by making `r3_port_riscv`'s `riscv-rt` dependency optional, ensuring that `riscv-rt` participates in linking only if needed by the application. [1]: rust-lang/rust#95604 [2]: rust-lang/rust#47384 [3]: https://github.com/rust-embedded/riscv-rt/blob/7de3d2744a465ad723519c04f13c56664e138cb9/asm.S#L20 [4]: https://github.com/llvm/llvm-project/blob/b86440ecde5c1dec5b898a3f1bc08ab9853d5ed9/lld/ELF/MarkLive.cpp#L183
Fixes linker errors in an application that is linked to `r3_port_riscv` and does not use the `riscv-rt`-compatible startup routine provided by `r3_port_riscv::use_rt!`. Rust implements `rlib`s as static libraries (archives). Linkers treat archives differently from object files: all object files participate in linking, while archives will only participate in linking if they can satisfy at least one undefined reference (version scripts don't count). This means that in an application that does not use `use_rt!`, `libriscv_rt*.rlib` does not participate in linking at all. This behavior also causes `#[no_mangle]` and `#[used]` items to be ignored by the linker (`KEEP` in linker scripts can't keep them either), leading to a long-standing bug in Rust ([rust-lang/rust#47384][2]). The situation changed with the merge of [rust-lang/rust#95604][1]. To fix [rust-lang/rust#47384][2], this PR introduced a synthetic object file containing references to all symbols pertaining to `#[no_mangle]` and `#[used]` items. `libriscv_rt*.rlib` now participates in linking, but the expectation is that `--gc-sections` will remove unused items in the end, unless they are explicitly retained by `KEEP` in linker scripts or other means. This change unexpectedly caused breakage in the tests for `qemu_sifive_u _s_rv(64,32)` targets, which use a custom startup routine instead of `use_rt!`. For some reason, the linker didn't respect `--gc-sections` for some items from `libriscv_rt*.rlib` and decided to include them in the output binary. These items reference symbols that are defined by the `riscv-rt` linker script, which isn't used by `qemu_sifive_u_s_ rv(64,32)` targets, hence the linker error. The thing is, `riscv-rt` outputs these items in the `.init` section[3], which is one of the section names hard-coded in LLD[4] to be excluded from `--gc-sections`. As a result, these items were considered for inclusion despite being referenced from nowhere. This commit works around this problem by making `r3_port_riscv`'s `riscv-rt` dependency optional, ensuring that `riscv-rt` participates in linking only if needed by the application. P.S. An exclamation mark (`!`) in the commit headline will be used to indicate breaking changes from now on, as per [Conventional Commits 1.0.0][5]. [1]: rust-lang/rust#95604 [2]: rust-lang/rust#47384 [3]: https://github.com/rust-embedded/riscv-rt/blob/7de3d2744a465ad723519c04f13c56664e138cb9/asm.S#L20 [4]: https://github.com/llvm/llvm-project/blob/b86440ecde5c1dec5b898a3f1bc08ab9853d5ed9/lld/ELF/MarkLive.cpp#L183 [5]: https://www.conventionalcommits.org/en/v1.0.0/
Fixes linker errors in an application that is linked to `r3_port_riscv` and does not use the `riscv-rt`-compatible startup routine provided by `r3_port_riscv::use_rt!`. Rust implements `rlib`s as static libraries (archives). Linkers treat archives differently from object files: all object files participate in linking, while archives will only participate in linking if they can satisfy at least one undefined reference (version scripts don't count). This means that in an application that does not use `use_rt!`, `libriscv_rt*.rlib` does not participate in linking at all. This behavior also causes `#[no_mangle]` and `#[used]` items to be ignored by the linker (`KEEP` in linker scripts can't keep them either), leading to a long-standing bug in Rust ([rust-lang/rust#47384][2]). The situation changed with the merge of [rust-lang/rust#95604][1]. To fix [rust-lang/rust#47384][2], this PR introduced a synthetic object file containing references to all symbols pertaining to `#[no_mangle]` and `#[used]` items. `libriscv_rt*.rlib` now participates in linking, but the expectation is that `--gc-sections` will remove unused items in the end, unless they are explicitly retained by `KEEP` in linker scripts or other means. This change unexpectedly caused breakage in the tests for `qemu_sifive_u _s_rv(64,32)` targets, which use a custom startup routine instead of `use_rt!`. For some reason, the linker didn't respect `--gc-sections` for some items from `libriscv_rt*.rlib` and decided to include them in the output binary. These items reference symbols that are defined by the `riscv-rt` linker script, which isn't used by `qemu_sifive_u_s_ rv(64,32)` targets, hence the linker error. The thing is, `riscv-rt` outputs these items in the `.init` section[3], which is one of the section names hard-coded in LLD[4] to be excluded from `--gc-sections`. As a result, these items were considered for inclusion despite being referenced from nowhere. This commit works around this problem by making `r3_port_riscv`'s `riscv-rt` dependency optional, ensuring that `riscv-rt` participates in linking only if needed by the application. P.S. I'll try to use an exclamation mark (`!`) in the commit headline to indicate breaking changes from now on, as per [Conventional Commits 1.0.0][5]. [1]: rust-lang/rust#95604 [2]: rust-lang/rust#47384 [3]: https://github.com/rust-embedded/riscv-rt/blob/7de3d2744a465ad723519c04f13c56664e138cb9/asm.S#L20 [4]: https://github.com/llvm/llvm-project/blob/b86440ecde5c1dec5b898a3f1bc08ab9853d5ed9/lld/ELF/MarkLive.cpp#L183 [5]: https://www.conventionalcommits.org/en/v1.0.0/
Statics that are marked
no_mangle
and/orused
only get to the linker if they are in a reachable module of a reachable crate. The static itself does not need to be used in code, only some function in the same module. This previously worked in our project, so this seems like a regression.Example
The issue is best explained with a small example crate named
bug_test
, which can be found here:src/lib.rs
:src/main.rs
:Linker script
linker.ld
:Build using:
Show contents of
.static
section:Comment out one of the
STATIC not present if commented out
lines and recompile. ThenSTATIC
no longer exist in the output and the.static
section is empty:Versions
Edit: Added the
used
attribute.The text was updated successfully, but these errors were encountered: