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

[LLD] Support --enable-long-section-names #56

Open
mati865 opened this issue Oct 17, 2019 · 12 comments
Open

[LLD] Support --enable-long-section-names #56

mati865 opened this issue Oct 17, 2019 · 12 comments

Comments

@mati865
Copy link
Contributor

mati865 commented Oct 17, 2019

I don't know if it's required for LLD (maybe stub would suffice) but Rust hardcodes this flag for compatibility with older LD versions
since it's MinGW target early days.
It could be possible to drop this flag by now but it'd require a lot of testing. Maybe it'd make sense for LLD to implement this flag (or stub) for feature parity with LD?

This blocks usage of Rust MinGW target with LLD.

@mstorsjo
Copy link
Owner

Right, I do remember looking at this detail and discussing it with someone.

FWIW, LLD has got slightly different logic for short/truncated vs long section names. If linking stripped (-Wl,-s), i.e. removing debug info, it also always truncates section names. If keeping debug info, it normally keeps long section names, but with one exception. If the section is flagged as loaded at runtime (like normal code/data sections, contrary to debug info), the section is always stored with a truncated name. This, because the long section names aren't available at runtime if introspecting the loaded DLLs (which libunwind does, to find the unwind info - libgcc does it differently).

I do remember looking so far that the .note.rustc section isn't flagged as loaded at runtime (marked with the flag IMAGE_SCN_MEM_DISCARDABLE), so LLD would currently keep the long name, satisfying rust.

I guess I could hook up these options to further allow controlling the behaviour - or if there's opposition to that upstream, at least make them no-ops.

@mati865
Copy link
Contributor Author

mati865 commented Nov 13, 2019

FYI apparently Rust no longer emits .note* sections. We will see if somebody reports bugs but --enable-long-section-names is no longer hardcoded on nightly: rust-lang/rust#66257

@mstorsjo
Copy link
Owner

Hm, from what I remember from discussing this with others, was that the .note.* sections were only emitted for certain cases (dynamically linked crates maybe, if I remember correctly?). In any case, that option shouldn't be necessary with modern binutils iirc.

I could still of course try to implement those options in lld, but it hasn't gotten to the top of the todo stack yet.

@mati865
Copy link
Contributor Author

mati865 commented Nov 18, 2019

I haven't found .note.* in executables and libs built as *.dll so I think it's not important right now. Nightly Rust builds don't use this flag any more.

So far using LLD 9 from MSYS2 (coupled with GCC 9) was nice but when building cdylib crate types (those result in *.dll on Windows) it gives following error:

lld: error: unknown argument: --version-script=C:\Users\mateusz\AppData\Local\Temp\rustc9iAl8B\list

LLD supports version-script only in ELF backend.
Related Rust code: https://github.com/rust-lang/rust/blob/87cbf0a547aaf9e8a7fc708851ecf4bc2adab5fd/src/librustc_codegen_ssa/back/linker.rs#L467

@ePirat
Copy link

ePirat commented Nov 18, 2019

The flag in question was removed recently indeed, in rust-lang/rust@d153f4f

Longer section names are not used anymore, they were needed for the .note.rustc section but this was changed in rust-lang/rust@f9846e9 and rust-lang/rust@1bb1444

@mstorsjo
Copy link
Owner

So far using LLD 9 from MSYS2 (coupled with GCC 9) was nice but when building cdylib crate types (those result in *.dll on Windows) it gives following error:

lld: error: unknown argument: --version-script=C:\Users\mateusz\AppData\Local\Temp\rustc9iAl8B\list

LLD supports version-script only in ELF backend.
Related Rust code: https://github.com/rust-lang/rust/blob/87cbf0a547aaf9e8a7fc708851ecf4bc2adab5fd/src/librustc_codegen_ssa/back/linker.rs#L467

Yes, I've looked into version-script a couple times. Unfortunately, the existing code in LLD's ELF backend is very tightly entangled with the ELF linker. IIRC that parser is both used for the (fairly simple) version scripts and generic linker script (for controlling the output layout of the linker). Linker script in the COFF part of lld is pretty much "won'tfix", but I think it could be possible with a simpler standalone parser for version script for the COFF linker.

For ELF, version scripts allows you to set different symbol versions to different symbols. Since PE/COFF doesn't have symbol versions, the only effect version scripts have there is to allow you to provide pattern matched lists of symbols to export/hide.

What are the version scripts used for here? (I didn't invest enough time in trying to read the linked rust code right now...) In some cases I've seen, version scripts just exported the symbols * (but trying to set a symbol version, for ELF). In those cases, just leaving out the version script for COFF was totally justifiable.

As Rust does support linking with MS link.exe as well, which doesn't support version script, how is the same aspect handed there? Is it possible to somehow pick using that approach for mingw style linkers as well?

@mati865
Copy link
Contributor Author

mati865 commented Nov 18, 2019

What are the version scripts used for here?

I think their purpose is to distinguish local and global symbols.

As Rust does support linking with MS link.exe as well, which doesn't support version script, how is the same aspect handed there?

I don't precisely know about all this stuff but IIUC for MSVC it just creates simple *.def import library: https://github.com/rust-lang/rust/blob/87cbf0a547aaf9e8a7fc708851ecf4bc2adab5fd/src/librustc_codegen_ssa/back/linker.rs#L671-L698

Is it possible to somehow pick using that approach for mingw style linkers as well?

I think it's possible to reuse this code for mingw nonetheless version-script usage looks dead simple to me: https://github.com/rust-lang/rust/blob/87cbf0a547aaf9e8a7fc708851ecf4bc2adab5fd/src/librustc_codegen_ssa/back/linker.rs#L434-L451

@mstorsjo
Copy link
Owner

What are the version scripts used for here?

I think their purpose is to distinguish local and global symbols.

Sure - I meant does it use any fancy featuers like wildcards or so? But since it's only used for writing the same as can be written to def files, apparently not.

As Rust does support linking with MS link.exe as well, which doesn't support version script, how is the same aspect handed there?

I don't precisely know about all this stuff but IIUC for MSVC it just creates simple *.def import library: https://github.com/rust-lang/rust/blob/87cbf0a547aaf9e8a7fc708851ecf4bc2adab5fd/src/librustc_codegen_ssa/back/linker.rs#L671-L698

Is it possible to somehow pick using that approach for mingw style linkers as well?

I think it's possible to reuse this code for mingw

Ok, then that's probably the simplest path forward for making this work with lld.

nonetheless version-script usage looks dead simple to me: https://github.com/rust-lang/rust/blob/87cbf0a547aaf9e8a7fc708851ecf4bc2adab5fd/src/librustc_codegen_ssa/back/linker.rs#L434-L451

Writing them is dead simple, but parsing them is a different matter, as the version scripts still have a not completely trivial syntax in the generic form.

@mati865
Copy link
Contributor Author

mati865 commented Nov 18, 2019

I think it's possible to reuse this code for mingw

Ok, then that's probably the simplest path forward for making this work with lld.

I'm out of time to do it soon but I should find time before the new year.

Should we repurpose or close this issue?

@mstorsjo
Copy link
Owner

Maybe open another one; I might actually look at implementing some form of --enable-long-section-names still.

@mati865
Copy link
Contributor Author

mati865 commented Nov 18, 2019

What are the version scripts used for here?

I think their purpose is to distinguish local and global symbols.

Sure - I meant does it use any fancy featuers like wildcards or so? But since it's only used for writing the same as can be written to def files, apparently not.

Oh sorry, I missed this question.
I'm not sure but I really doubt it's something more than visibility + plain names.

Should we repurpose or close this issue?

Maybe open another one

On the second thought there is no reason to open issue for version-script if it's won't fix.

@mstorsjo
Copy link
Owner

Well, linker script in general is kinda won't fix. Version script is more of "I think it should be doable but I haven't had the direct need yet, it's always been possible to work around it pretty easily so far, but I would love to implement it at some point". Especially for codebases that work with MSVC, there's usually some other codepath available.

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