Skip to content

Disable TLS optimization for musl riscv64 - #121662

Merged
jkotas merged 4 commits into
dotnet:mainfrom
am11:patch-42
Nov 15, 2025
Merged

jkotas merged 4 commits into
dotnet:mainfrom
am11:patch-42

Conversation

@am11

@am11 am11 commented Nov 15, 2025 •

Copy link
Copy Markdown
Member

On linux-musl-riscv64, when corehost (dotnet) dlopen()s libcoreclr, we get:

# dotnet --version
Failed to load /root/.dotnet/shared/Microsoft.NETCore.App/10.0.0-rtm.25564.199/libcoreclr.so, error: Error relocating /root/.dotnet/shared/Microsoft.NETCore.App/10.0.0-rtm.25564.199/libcoreclr.so: Uq???&?J?N?R?V?Z? .????: initial-exec TLS resolves to dynamic definition in /root/.dotnet/shared/Microsoft.NETCore.App/10.0.0-rtm.25564.199/libcoreclr.so
Failed to bind to CoreCLR at '/root/.dotnet/shared/Microsoft.NETCore.App/10.0.0-rtm.25564.199/'
Failed to create CoreCLR, HRESULT: 0x80008088

musl maintainer described the issue on this golang thread: golang/go#54805 (comment). When I tried LD_PRELOAD=/root/.dotnet/shared/Microsoft.NETCore.App/10.0.0-rtm.25564.199/libcoreclr.so dotnet --version, the SDK started working.

By disabling the optimization as we have done for linux-musl-arm64 and removing la.tls.ie from binary works without the LD_PRELOAD hack.

@github-actions github-actions Bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Nov 15, 2025
@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Nov 15, 2025
@am11 am11 added area-PAL-coreclr only for closed issues arch-riscv Related to the RISC-V architecture and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Nov 15, 2025
@am11

am11 commented Nov 15, 2025 •

Copy link
Copy Markdown
Member Author

I tried using inline version (from src/coreclr/runtime/InlineTLS.inc), but that throws access violation because in this context, we need C calling convention and some registers unexpectedly gets clobbered, but I don't see how (we save/restore everything). I then tried using .gd variant inline without reusing InlineTls.inc:

-    la.tls.ie   a0, t_ThreadStatics
+    PROLOG_SAVE_REG_PAIR_INDEXED fp, ra, 16
+    la.tls.gd a0, t_ThreadStatics
+    call    __tls_get_addr
+    sub     a0, a0, tp
+    EPILOG_RESTORE_REG_PAIR_INDEXED fp, ra, 16

with just a0/t0 restore, that also ran into access violation.. so I gave up and took this easy (as good as linux-musl-arm64) route.

Unless someone has idea if I can try some other asm patch, I think this is good as is. Right now I'm testing it with long route (build VMR tarball in ~75m in GH actions and downloading on the device). Later I will setup a workbench and may find a way to reuse InlineTls.inc with quick hit-and-trial iterations 😅

@filipnavara, found it when testing VMR tarball in updated dotnet-riscv workfllow, once this is merged I will apply it as a patch in the workflow.

ps - nativeaot runtime works without issue because that uses .gd TLS model from InlineTls.inc.

@am11
am11 requested review from a team and filipnavara November 15, 2025 15:34
Comment thread src/coreclr/vm/riscv64/asmhelpers.S Resolved
Comment thread src/coreclr/vm/riscv64/asmhelpers.S Resolved
@jkotas

jkotas commented Nov 15, 2025

Copy link
Copy Markdown
Member

/ba-g deadletter

@jkotas
jkotas merged commit 01e9dbf into dotnet:main Nov 15, 2025
94 of 98 checks passed
am11 added a commit to am11/runtime that referenced this pull request Nov 16, 2025
On linux-musl-riscv64, when corehost (dotnet) dlopen()s libcoreclr, we
get:

> \# dotnet --version
> Failed to load
/root/.dotnet/shared/Microsoft.NETCore.App/10.0.0-rtm.25564.199/libcoreclr.so,
error: Error relocating
/root/.dotnet/shared/Microsoft.NETCore.App/10.0.0-rtm.25564.199/libcoreclr.so:
Uq???&?J?N?R?V?Z? .????: initial-exec TLS resolves to dynamic definition
in
/root/.dotnet/shared/Microsoft.NETCore.App/10.0.0-rtm.25564.199/libcoreclr.so
Failed to bind to CoreCLR at
'/root/.dotnet/shared/Microsoft.NETCore.App/10.0.0-rtm.25564.199/'
Failed to create CoreCLR, HRESULT: 0x80008088

musl maintainer described the issue on this golang thread:
golang/go#54805 (comment). When
I tried
`LD_PRELOAD=/root/.dotnet/shared/Microsoft.NETCore.App/10.0.0-rtm.25564.199/libcoreclr.so
dotnet --version`, it started working and SDK started working.

By disabling the optimization as we have done for linux-musl-arm64 and
removing `la.tls.ie` from binary works without the `LD_PRELOAD` hack.

---------

Co-authored-by: Jan Kotas <jkotas@microsoft.com>
@am11
am11 deleted the patch-42 branch November 17, 2025 08:03
@am11

am11 commented Dec 1, 2025

Copy link
Copy Markdown
Member Author

@ayakael, FYI: this patch https://gitlab.alpinelinux.org/alpine/aports/-/merge_requests/66014/diffs#diff-content-84ad62c1d49972d6a63cec7a7b4e07710114f286 can be replaced by the PR https://github.com/dotnet/runtime/pull/121662.patch.

Also, note that we have linux-musl-riscv64 release https://github.com/filipnavara/dotnet-riscv/releases/tag/10.0.100 and it seems to be working out fine (regular run, PublishSingleFile, PublishReadyToRun, PublishAot etc. are just working OOTB). Workflow is pretty simple these days https://github.com/filipnavara/dotnet-riscv/blob/2a2f6baa6d84a509399e4edfcdcca8a58fbba4a8/.github/workflows/build.yml#L52-L63 🙂

@ayakael

ayakael commented Dec 3, 2025

Copy link
Copy Markdown
Contributor

@ayakael, FYI: this patch https://gitlab.alpinelinux.org/alpine/aports/-/merge_requests/66014/diffs#diff-content-84ad62c1d49972d6a63cec7a7b4e07710114f286 can be replaced by the PR https://github.com/dotnet/runtime/pull/121662.patch.

Also, note that we have linux-musl-riscv64 release https://github.com/filipnavara/dotnet-riscv/releases/tag/10.0.100 and it seems to be working out fine (regular run, PublishSingleFile, PublishReadyToRun, PublishAot etc. are just working OOTB). Workflow is pretty simple these days https://github.com/filipnavara/dotnet-riscv/blob/2a2f6baa6d84a509399e4edfcdcca8a58fbba4a8/.github/workflows/build.yml#L52-L63 🙂

Thanks for the heads up!! That's terrific news, we've been wanting to enable riscv64 for a while!

@github-actions github-actions Bot locked and limited conversation to collaborators Jan 2, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-riscv Related to the RISC-V architecture area-PAL-coreclr only for closed issues community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants