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

External linkage + hidden visibility support #61

Closed
bjorn3 opened this issue Feb 9, 2019 · 13 comments
Closed

External linkage + hidden visibility support #61

bjorn3 opened this issue Feb 9, 2019 · 13 comments

Comments

@bjorn3
Copy link
Contributor

bjorn3 commented Feb 9, 2019

Rustc wants to export some symbols to other object files, but keep them hidden from the resulting dynamic library or executable. I currently get linker errors for https://github.com/bjorn3/rustc_codegen_cranelift/blob/d20f54bb1a873a16681c687a58b7946dc6924913/example/alloc_example.rs because of this not being implemented yet.

@m4b
Copy link
Owner

m4b commented Feb 9, 2019

Which symbols are annotated how? Can you share the linker errors here ?

@bjorn3
Copy link
Contributor Author

bjorn3 commented Feb 10, 2019

All #[rustc_std_internal_symbol] annotated functions have external linkage and hidden visibility. They are made hidden at https://github.com/rust-lang/rust/blob/cb6fafbdf3b09da28b09fa7e87a24658d77dd02f/src/librustc_mir/monomorphize/partitioning.rs#L510-L529 and external at https://github.com/rust-lang/rust/blob/cb6fafbdf3b09da28b09fa7e87a24658d77dd02f/src/librustc_mir/monomorphize/partitioning.rs#L385. The are considered being a root at https://github.com/rust-lang/rust/blob/cb6fafbdf3b09da28b09fa7e87a24658d77dd02f/src/librustc_mir/monomorphize/collector.rs#L1018-L1030, which means

I only get linker errors with linux. Unfortunately I don't have access to a linux computer today. The linker error is something about a duplicate symbol.

@m4b
Copy link
Owner

m4b commented Feb 10, 2019

I read the first link but I didn’t really follow. I’ll probably need to examine some object files. Specifically I’m wondering what machine level linkage the symbols are given?

@bjorn3
Copy link
Contributor Author

bjorn3 commented Feb 10, 2019

I will upload an object file tomorrow.

@m4b
Copy link
Owner

m4b commented Feb 10, 2019

Ok if you have a mach-o that'll be helpful too. In meantime I can look at rustc output for a standard main.rs. At some point we should check in a test.rs similar to the test.c, to track feature parity for a rust/cranelift/faerie backend :)

@bjorn3
Copy link
Contributor Author

bjorn3 commented Feb 10, 2019

On macOS if I just use Linkage::Export it will just work, because the macOS linker has less problems with duplicate symbols.

@m4b
Copy link
Owner

m4b commented Feb 10, 2019

Hmmm; I'm not sure precisely what the issue is; at the machine linking level there isn't really a hidden visibility or external linkage afaik, and this isn't how the example __rust_realloc symbol is emitted either, we can see it's got regular undefined references, with a single global definition in libstd:

m4b@efrit ::  [ ~/projects/faerie ] for i in `ls ~/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/*.so`; do echo $i; nm $i | grep -i __rust_realloc; done
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/libarena-73c967088bc88ae0.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/libfmt_macros-749bb484a38ead5a.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/libgraphviz-19ee3751d73d50cd.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/libproc_macro-cc67010ab061aadb.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc-06d83498389a5f3a.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_allocator-527cf64d13bacd18.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_borrowck-8c92bf4592a099ed.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_codegen_utils-b3eb503026263b67.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_cratesio_shim-4072b440cedf4345.so
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_data_structures-f881aae1c2691900.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_driver-683df7c8f36ead3b.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_errors-c7f80ba6ab4d7ae8.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_fs_util-0d2e8e309b27cc9e.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_incremental-294a4dbdc3ed1e4a.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_lint-cda02bcdbd4c29ca.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_metadata-b8637c5a492909bd.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_metadata_utils-bdd5fa92f756d064.so
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_mir-2f501f10bfde7a44.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_passes-28eba4d8884b6b01.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_platform_intrinsics-df7f5d04e00c6e71.so
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_plugin-3ca3ec0f31e56212.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_privacy-c94e84b7e91c400f.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_resolve-e5533607385fb218.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_save_analysis-e853ad9627b85304.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_target-7220a6a311edd1c5.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_traits-e89df2945d98ac98.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/librustc_typeck-827b3bf4425692e2.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/libserialize-7a1ce8da097bba0c.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/libstd-4a59f2ef80606c7b.so
000000000007be40 T __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/libsyntax-bea7257cd3db87e2.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/libsyntax_ext-61b196fd6c0b9709.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/libsyntax_pos-ede36dc0d4c891e6.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/libterm-5ea78ff9f401d7f2.so
                 U __rust_realloc
/home/m4b/.rustup/toolchains//nightly-x86_64-unknown-linux-gnu/lib/libtest-3019c3e7c5622020.so

So my guess is that this isn't something that needs to happen at the faerie level (e.g., linker level), but probably in the backend codegen pipeline in cranelift? I'm not sure though, @sunfishcode do you have any insights on what should be done here?

@bjorn3
Copy link
Contributor Author

bjorn3 commented Feb 11, 2019

I can't reproduce the linker error anymore.

@bjorn3
Copy link
Contributor Author

bjorn3 commented Feb 11, 2019

Hmmm; I'm not sure precisely what the issue is; at the machine linking level there isn't really a hidden visibility or external linkage afaik

readelf calls it Bind and Vis.

$ readelf -sW ~/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/lib* |& grep -v DEFAULT | grep -v Error
[...]
Symbol table '.symtab' contains 68 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
    33: 0000000000000000     8 OBJECT  WEAK   HIDDEN    43 DW.ref.rust_eh_personality
    35: 0000000000000000   391 FUNC    GLOBAL HIDDEN     3 _ZN100_$LT$alloc..collections..btree..map..BTreeMap$LT$K$C$$u20$V$GT$$u20$as$u20$core..ops..drop..Drop$GT$4drop17h445f32ec9726b7c4E
    36: 0000000000000000   371 FUNC    GLOBAL HIDDEN     5 _ZN120_$LT$alloc..collections..btree..map..BTreeMap$LT$K$C$$u20$V$GT$$u20$as$u20$core..iter..traits..collect..IntoIterator$GT$9into_iter17h56895d6809ac1d22E.llvm.5537033169401752313
    37: 0000000000000000   340 FUNC    GLOBAL HIDDEN     6 _ZN127_$LT$alloc..collections..btree..map..Iter$LT$$u27$a$C$$u20$K$C$$u20$V$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$4next17hcd5904b687e9341fE
    38: 0000000000000000   367 FUNC    GLOBAL HIDDEN     7 _ZN135_$LT$$RF$$u27$a$u20$alloc..collections..btree..map..BTreeMap$LT$K$C$$u20$V$GT$$u20$as$u20$core..iter..traits..collect..IntoIterator$GT$9into_iter17ha75ef55f3c4fb59aE
    39: 0000000000000000     0 NOTYPE  GLOBAL HIDDEN   UND _ZN286_$LT$alloc..collections..btree..node..Handle$LT$alloc..collections..btree..node..NodeRef$LT$alloc..collections..btree..node..marker..Mut$LT$$u27$a$GT$$C$$u20$K$C$$u20$V$C$$u20$alloc..collections..btree..node..marker..Leaf$GT$$C$$u20$alloc..collections..btree..node..marker..Edge$GT$$GT$6insert17h518f2b04366cb669E
    40: 0000000000000000     0 NOTYPE  GLOBAL HIDDEN   UND _ZN290_$LT$alloc..collections..btree..node..Handle$LT$alloc..collections..btree..node..NodeRef$LT$alloc..collections..btree..node..marker..Mut$LT$$u27$a$GT$$C$$u20$K$C$$u20$V$C$$u20$alloc..collections..btree..node..marker..Internal$GT$$C$$u20$alloc..collections..btree..node..marker..Edge$GT$$GT$6insert17h5857059445c3fc22E
[...]

@pchickey
Copy link
Collaborator

I'm working on some changes that will make this possible.

According to https://www.uclibc.org/docs/elf-64-gen.pdf page 10, the "symbol binding" property can be local, global, or weak. My plan is to change the global :bool field in the relevant artifact::Decl variants to instead be scope: Scope where pub enum Scope { Local, Global, Weak }. I don't want to re-use the ELF term "binding" for this in the public API because its confusing, and there is already a concept of artifact::Binding in the library.

I don't know how weak symbols work in macho, so I'll make that case panic in my first pass at this, but I can learn how macho works next and implement that if needed.

@bjorn3
Copy link
Contributor Author

bjorn3 commented Feb 15, 2019

@pchickey did you mean to comment at #60? Thanks for working on it anyway.

@pchickey
Copy link
Collaborator

You're right, I was trying to figure out a way to solve both of these and typed my response in the wrong tab.

@pchickey
Copy link
Collaborator

For ELF, It looks like Decl would need an additional enum field for visbility - pub enum Visbility { Default, Protected, Hidden}. Like with the scope, I'm not sure what modes macho supports and whether exposing those options will work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants