llvm-mingw icon indicating copy to clipboard operation
llvm-mingw copied to clipboard

[LLD] Support `--enable-long-section-names`

Open mati865 opened this issue 6 years ago • 12 comments

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.

mati865 avatar Oct 17 '19 12:10 mati865

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.

mstorsjo avatar Oct 17 '19 21:10 mstorsjo

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: https://github.com/rust-lang/rust/pull/66257

mati865 avatar Nov 13 '19 21:11 mati865

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.

mstorsjo avatar Nov 13 '19 21:11 mstorsjo

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

mati865 avatar Nov 18 '19 17:11 mati865

The flag in question was removed recently indeed, in https://github.com/rust-lang/rust/commit/d153f4f4936efc8039489083f5561070cf5de029

Longer section names are not used anymore, they were needed for the .note.rustc section but this was changed in https://github.com/rust-lang/rust/commit/f9846e902dae169255c2d2b1766e7b9846488a89 and https://github.com/rust-lang/rust/commit/1bb14445160329c2ca5ff9c202e791ca0098d944

ePirat avatar Nov 18 '19 20:11 ePirat

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?

mstorsjo avatar Nov 18 '19 20:11 mstorsjo

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

mati865 avatar Nov 18 '19 21:11 mati865

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.

mstorsjo avatar Nov 18 '19 21:11 mstorsjo

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?

mati865 avatar Nov 18 '19 21:11 mati865

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

mstorsjo avatar Nov 18 '19 21:11 mstorsjo

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.

mati865 avatar Nov 18 '19 21:11 mati865

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.

mstorsjo avatar Nov 18 '19 21:11 mstorsjo