[wasm] Export cDAC contract descriptor getter on non-emscripten wasm (wasi-sdk) - #131241
Conversation
…(wasi-sdk)
On non-emscripten wasm (wasi-sdk), the cDAC contract descriptor getter
GetDotNetRuntimeContractDescriptor was not exported, so --gc-sections stripped
the descriptor from the final module, preventing a native host / the cDAC reader
from discovering the runtime data-contract descriptor on WASI. The emscripten
path already handles this via EMSCRIPTEN_KEEPALIVE.
Add an `#elif defined(EXPORT_CONTRACT) && defined(__wasm__)` branch that emits the
getter with __attribute__((export_name("Get" #CONTRACT_NAME))), which both exports
the symbol and roots it against --gc-sections. Hoist the GETTER_NAME token-paste
macros above the #if and add a GETTER_NAME_STR stringize pair shared by both branches.
Verified: WASI CoreCLR build (clr -os wasi -c Release) 0W/0E; the compiled object
exports GetDotNetRuntimeContractDescriptor with the no_strip flag.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 2902374a-f352-4c46-bcec-8a35c97733ae
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara |
There was a problem hiding this comment.
Pull request overview
This PR updates CoreCLR’s shared cDAC contract-descriptor generator to ensure the contract descriptor getter is exported (and thus retained by the linker) when building for non-Emscripten WebAssembly toolchains (e.g., WASI via wasi-sdk).
Changes:
- Hoists the getter-name token-paste macros so they can be shared across export implementations.
- Adds a non-Emscripten WebAssembly export path using
__attribute__((export_name(...)))to export the getter and keep the descriptor reachable under--gc-sections.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
jkoritzinsky
left a comment
There was a problem hiding this comment.
Is this something we can unify between Emscripten and WASI? Or does Emscripten not support the WASI mechanism?
possibly, the emscripten version wires up some things automatically. I will check how it is consumed. |
|
They could share the
So unifying now would risk the one proven path (browser discovery) for no functional gain in a WASI-scoped change. I'd rather unify as a follow-up gated on an explicit browser cDAC re-validation: build an emscripten CoreCLR with the emscripten branch switched to bare Note This reply was drafted with the assistance of GitHub Copilot. |
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
The non-emscripten wasm getter branch keyed on TARGET_WASM, a CoreCLR configurecompiler.cmake define that is gated on IGNORE_DEFAULT_TARGET_ARCH and is not guaranteed to reach every consumer of the shared datadescriptor-shared sources. The whole purpose of the branch is to root the contract descriptor getter against --gc-sections on any wasm toolchain, so it must key on a macro that is always defined when targeting wasm. Use the compiler-provided __wasm__ and document why the compiler builtin is deliberately preferred here over the TARGET_* define, so the choice isn't "corrected" back later. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 50ddfb2c-b6f8-4847-81e7-44d37d44a175
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
src/coreclr/debug/datadescriptor-shared/contract-descriptor.c.in:49
- Consider including the build-system WASM define in addition to the compiler-provided
__wasm__. The repo generally prefersHOST_*/TARGET_*defines over compiler macros (see.github/instructions/review-native.instructions.md), and other CoreCLR code already usesdefined(HOST_WASM) || defined(__wasm__)to cover both cases (e.g.src/coreclr/gc/init.cpp:1321). Using both here would keep the “works for all wasm toolchains” intent while matching established patterns.
#elif defined(EXPORT_CONTRACT) && defined(__wasm__)
// Non-emscripten wasm (e.g. wasi-sdk): export the getter with an explicit export name so the
// descriptor symbol is both reachable by a native host and, critically, kept alive by the linker.
// Without an export rooting it, --gc-sections removes the descriptor from the final module (the
// emscripten path above relies on EMSCRIPTEN_KEEPALIVE for the same reason).
Summary
On non-emscripten wasm (wasi-sdk), the cDAC contract descriptor getter
GetDotNetRuntimeContractDescriptoris not exported, so--gc-sectionsstrips the descriptor from the final module. This prevents a native host / the cDAC reader from discovering the runtime data-contract descriptor on WASI.The emscripten path already handles this via
EMSCRIPTEN_KEEPALIVE, which both exports the getter and keeps the descriptor alive. There was no equivalent for the wasi-sdk (__wasm__, non-emscripten) toolchain.Fix
Add an
#elif defined(EXPORT_CONTRACT) && defined(__wasm__)branch that emits the getter with__attribute__((export_name("Get" #CONTRACT_NAME))). The explicit wasm export both makes the symbol reachable by a native host and roots it so--gc-sectionsdoes not remove the descriptor — mirroring whatEMSCRIPTEN_KEEPALIVEdoes on the emscripten path.The
GETTER_NAMEtoken-paste macros are hoisted above the#if(shared by both branches) and aGETTER_NAME_STRstringize pair is added to produce the literal export name"GetDotNetRuntimeContractDescriptor".Validation
clr -os wasi -c Release): compiles clean (0W/0E).GetDotNetRuntimeContractDescriptorwith theno_stripflag, so it survives--gc-sections.This unblocks live cDAC discovery on WASI (non-emscripten) — the runtime-side counterpart to the cDAC-wasm validation work (#131161). Fixture-based cDAC tests do not depend on it.
Note
This PR was authored with the assistance of GitHub Copilot.