Skip to content

Attribute #[used(linker)] not affected from external crate #98406

New issue

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

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

Already on GitHub? # to your account

Closed
chabapok opened this issue Jun 22, 2022 · 3 comments
Closed

Attribute #[used(linker)] not affected from external crate #98406

chabapok opened this issue Jun 22, 2022 · 3 comments
Labels
C-bug Category: This is a bug.

Comments

@chabapok
Copy link

In current implementation #93798 of the #[used(linker)] work fine if the symbol placed in same module or in the child module. This has been discussed and fixed here: #47384. But if the #[used(linker)] marks symbol from another crate, this won't work.

I tried this code:

main.rs:

#![feature(used_with_arg)]

extern "C" {
    #[link_name = "__start_my_cool_section"]
    static START: u32;
    #[link_name = "__stop_my_cool_section"]
    static STOP: u32;
}

#[used(linker)]
#[link_section = "my_cool_section"]
pub static TEST: [u32; 0] = [];

fn main() {
    bar::bar(); // <--- try to comment this

    let a = unsafe{ &START as *const _ as usize};
    let b = unsafe{ &STOP as *const _ as usize};
    println!("{a} {b} b-a={}", b-a);
}

Cargo.toml of the main crate:

[package]
name = "foo"
version = "0.1.0"
edition = "2021"

[dependencies]
bar = { path = "bar" }

lib.rs of the bar crate:

#![feature(used_with_arg)]

#[used(linker)]
#[link_section = "my_cool_section"]
pub static TEST: [u32; 10] = [42; 10];

pub fn bar(){
    println!("-- bar --");
}

So, as well as #47384 we may view contents of my_cool_section section:

$ objdump -s -j"my_cool_section" ./foo

./foo:     file format elf64-x86-64

Contents of section my_cool_section:
 41128 2a000000 2a000000 2a000000 2a000000  *...*...*...*...
 41138 2a000000 2a000000 2a000000 2a000000  *...*...*...*...
 41148 2a000000 2a000000                    *...*...      ```

Comment out bar::bar() line of the main.rs and recompile. Then bar::TEST no longer exist in the output and no my_cool_section section in the compiled foo:

$ objdump -s -j"my_cool_section" ./foo

./foo:     file format elf64-x86-64

objdump: section 'my_cool_section' mentioned in a -j option, but not found in any input file

If you do not use START/STOP variables (but call bar::bar()) of the example, then there is no my_cool_section section either. Probably I understand that this is not correct too.

As far as I understand, if this is not fixed, then some crates (linkme, inventory...) will not work correctly in some cases.

Meta

$ rustc +nightly --version --verbose
rustc 1.63.0-nightly (dc80ca78b 2022-06-21)
binary: rustc
commit-hash: dc80ca78b6ec2b6bba02560470347433bcd0bb3c
commit-date: 2022-06-21
host: x86_64-unknown-linux-gnu
release: 1.63.0-nightly
LLVM version: 14.0.5
@chabapok chabapok added the C-bug Category: This is a bug. label Jun 22, 2022
@nikic
Copy link
Contributor

nikic commented Jun 23, 2022

cc @nbdd0121

@nbdd0121
Copy link
Contributor

This is expected. Rustc will not load (and thus, link) a crate if it is not considered used -- specify it in Cargo.toml will not make it automatically a dependency.

Adding extern crate bar; should fix the issue.

@chabapok
Copy link
Author

With extern crate bar; this works ok.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

3 participants