-
Notifications
You must be signed in to change notification settings - Fork 4.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
Write linker script for lld to enable gc-sections #84493
Write linker script for lld to enable gc-sections #84493
Conversation
Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas Issue DetailsThe gc-sections (size) optimization was disabled for llvm linker because we were getting the following link errors with Generating native code
ld.lld : error : undefined symbol: __start___modules [/exe1/exe1.csproj]
>>> referenced by main.cpp:182 (/__w/1/s/src/coreclr/nativeaot/Bootstrap/main.cpp:182)
>>> main.cpp.o:(main) in archive libbootstrapper.a
>>> referenced by main.cpp:182 (/__w/1/s/src/coreclr/nativeaot/Bootstrap/main.cpp:182)
>>> main.cpp.o:(main) in archive libbootstrapper.a
>>> the encapsulation symbol needs to be retained under --gc-sections properly; consider -z nostart-stop-gc (see https://lld.llvm.org/ELF/start-stop-gc)
ld.lld : error : undefined symbol: __stop___modules [/exe1/exe1.csproj]
>>> referenced by main.cpp:182 (/__w/1/s/src/coreclr/nativeaot/Bootstrap/main.cpp:182)
>>> main.cpp.o:(main) in archive libbootstrapper.a
>>> referenced by main.cpp:182 (/__w/1/s/src/coreclr/nativeaot/Bootstrap/main.cpp:182)
>>> main.cpp.o:(main) in archive libbootstrapper.a
clang : error : linker command failed with exit code 1 (use -v to see invocation) [/exe1/exe1.csproj]
There are (at least) three ways to fix this:
With --- main
+++ pr
- 1922376 (1.9M)
+ 1807688 (1.8M) TODO: revert the change in
|
eb2ec8f
to
15a45c9
Compare
15a45c9
to
853420d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thank you!
@am11 it looks like the OVERWRITE_SECTIONS command wasn't available until LLVM 13, so it's causing build failures in #84148. What is the minimum version of clang that we support when building NativeAot apps? The instructions of https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/#prerequisites say to install |
…)" This reverts commit 3ab663e.
Clang and lld are different things. #84148 is switching to linker to non-default against the platform convention, which is not recommended. So we shouldn't be doing that in first place because a) |
@am11 I understand - I'm just suggesting we decide on minimum We've been trying to move from binutils to llvm-based tools in our builds. This both reduces dependencies in our build images, and makes it easier to cross-compile, which is the approach we're using for the linux builds going forward. Using I understand that
Is there still a significant size regression with gc-sections? I plan to move to llvm 16 ASAP which should work fine with your OVERWRITE_SECTIONS fix. |
This linker script is not needed for lower version as all sections are retained with lld 12 and below. (as much as I dislike branching on version checks but since feature-detection would be too complex here) We can add the condition if we want to support older than v13: am11@04fb39b @Thefrank, is llvm < 13 scenario important enough for FreeBSD? Ports seem to have all versions of toolchain 10 to 15. FWIW, llvm 7 was the first version to support lld and gcc 9 was the first version to support
On linux-arm64 with latest daily build (includes this change): --- bfd
+++ lld
# size in bytes
# dotnet new console (~2.2 K diff)
- 1496072
+ 1498192
# dotnet new api -aot (~41 K diff)
- 12743672
+ 12785208 The difference is not fixed. It grows with the size of application. |
@am11 should be no need for a special check or case for older llvm on FreeBSD explanation: the current "meta" port (what you get when you type My CI system uses "old supported" which has been llvm10 and functional until Sunday. Moving forward I will start using llvm15 |
…tnet#84493)"" This reverts the revert of commit 3ab663e. The revert of that commit was included in 887c043.
* Revert "Revert "Write linker script for lld to enable gc-sections (#84493)"" This reverts the revert of commit 3ab663e. The revert of that commit was included in 887c043. * Lower the lld version requirement * Adjust dwarfdump baseline --------- Co-authored-by: Adeel <3840695+am11@users.noreply.github.com>
The gc-sections (size) optimization was disabled for llvm linker because we were getting the following link errors with
dotnet publish -p:PublishAot=true -p:LinkerFlavor=lld
lld
eagerly drops this section while the default linker,bfd
, sees it as effective and retains it. The differences are described in this article: https://maskray.me/blog/2020-12-19-lld-and-gnu-linker-incompatibilities. The weak sections are discarded by lld's--gc-sections
which are needed by live-sections and we don't get theDT_NEEDED
.There are (at least) three ways to fix this:
__attribute__((retain,used,section(__modules)))
.lld
, it breaksbfd
v2.39+.#ifdef __llvm
etc.) around those macros in code will not help.DT_NEEDED
for__modules
section to get the formal treatment.main
will do the trick or some other__attribute
?). If anyone else has insights, feel free to chime in.With
-p:LinkerFlavor=lld and -p:StripSymbols=true
, there is a noticeable difference in size of published binary due to gc-sections optimization: