Skip to content

Resolve WASM NativeAOT object relocations - #133537

Merged
jtschuster merged 8 commits into
dotnet:mainfrom
jtschuster:dev/jtschuster/wasm-nativeaot-relocs
Sep 15, 2026
Merged

jtschuster merged 8 commits into
dotnet:mainfrom
jtschuster:dev/jtschuster/wasm-nativeaot-relocs

Conversation

@jtschuster

Copy link
Copy Markdown
Member

Adds support for resolving IMAGE_REL_BASED_HIGHLOW relocations in the NativeAOT WASM object writer. This is only supported when the target is in a data segment that corresponds directly to an ObjectNodeSection (which most, if not all, will).

Also adds emission of export entries and handling of symbol aliases.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jtschuster jtschuster added this to the 12.0.0 milestone Sep 9, 2026
@jtschuster jtschuster self-assigned this Sep 9, 2026
Copilot AI lite review requested due to automatic review settings September 9, 2026 21:59
@jtschuster jtschuster added arch-wasm WebAssembly architecture area-NativeAOT-coreclr labels Sep 9, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @agocke, @dotnet/ilc-contrib
See info in area-owners.md if you want to be subscribed.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 6 pipeline(s).
10 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new export emission currently exports all functions (risking invalid/unloadable output) and the new HIGHLOW relocation handling has unchecked narrowing/unsupported-path exceptions that can produce incorrect output or unhelpful failures.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR extends the WASM NativeAOT object writer to resolve additional relocation types during emission, and adds initial plumbing for symbol aliases and export emission.

Changes:

  • Add alias support to the WASM symbol manager (lookup via alias map).
  • Resolve IMAGE_REL_BASED_HIGHLOW relocations in the WASM relocatable object writer.
  • Emit function exports from the WASM relocatable object writer and adjust section entry-count asserts for optional sections.
File summaries
File Description
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmSymbolManager.cs Adds alias storage and alias-aware symbol resolution.
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmRelocatableObjectWriter.cs Adds IMAGE_REL_BASED_HIGHLOW relocation resolution and emits exports; forces subsections-via-symbols as a temporary workaround.
src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs Makes section entry-count asserts conditional on section presence.
src/coreclr/jit/emitwasm.cpp Writes the correct relocation target for direct calls by passing params.addr into the relocatable constant descriptor.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 4
  • Review effort level: Lite

@pavelsavara

Copy link
Copy Markdown
Member

How much does this increase size of the module ?

@jtschuster

Copy link
Copy Markdown
Member Author

How much does this increase size of the module ?

We don't have a baseline size for a working NativeAOT module, so there's not really a good answer for that.

Copilot AI review requested due to automatic review settings September 10, 2026 21:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

One or more issues must be addressed before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (2)

src/coreclr/tools/Common/Compiler/ObjectWriter/WasmRelocatableObjectWriter.cs:172

  • This fallback is reachable for existing NativeAOT nodes: FatFunctionPointerNode emits IMAGE_REL_BASED_HIGHLOW for factory.MethodEntrypoint(...), and method bodies are placed in the WASM code section. Thus a valid fat function pointer causes object generation to throw here instead of resolving the relocation; other data nodes also emit pointer relocs to method entrypoints. Handle code/function targets with the appropriate WASM function/table relocation or keep them as link-time relocations.
                            else
                            {
                                throw new NotImplementedException();

src/coreclr/tools/Common/Compiler/ObjectWriter/WasmRelocatableObjectWriter.cs:205

  • These new TODOs document deferred relocation/COMDAT work but do not link a tracking issue or use a searchable issue-tagged TODO form. Please attach the follow-up issue to the TODO so this temporary workaround and the missing linker support do not become untracked.
        // TODO: This is a temporary workaround for the fact that we don't yet emit a COMDAT section (or any reloc / linking sections)
        private protected override bool UsesSubsectionsViaSymbols => true;
  • Files reviewed: 4/4 changed files
  • Comments generated: 1
  • Review effort level: Lite

Copilot AI review requested due to automatic review settings September 10, 2026 22:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

One or more issues must be addressed before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (1)

src/coreclr/tools/Common/Compiler/ObjectWriter/WasmRelocatableObjectWriter.cs:173

  • An unsupported HIGHLOW target reaches a bare NotImplementedException, so NativeAOT failures for code or other non-data symbols have no relocation type, symbol, or section context. This is especially difficult to diagnose because the default branch below already includes those details; throw a contextual NotSupportedException here as well.

[!NOTE] This review comment was created by GitHub Copilot.

                                throw new NotImplementedException();
  • Files reviewed: 5/5 changed files
  • Comments generated: 2
  • Review effort level: Lite

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 11, 2026 00:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

One or more issues must be addressed before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (1)

src/coreclr/tools/Common/Compiler/ObjectWriter/WasmSymbolManager.cs:85

  • Aliases and imports use separate dictionaries, and aliases are registered before WriteImports adds the default imports. Thus an export alias such as memory, table, or stackPointer can coexist with an imported symbol of the same name; GetEntry then prefers _entries, so WriteExports resolves the alias as the imported non-function and emits a function export with the wrong index space (the type check is only a Debug assertion). Enforce a single namespace across imports, definitions, and aliases, or reject collisions before emitting exports.
        Debug.Assert(!_entries.ContainsKey(alias), "Alias symbol name must not already exist.");
        Debug.Assert(_entries.ContainsKey(target), "Target symbol name must exist before adding an alias.");
        Entry entry = _entries[target];
        _aliases.Add(alias, entry with { Name = alias });
  • Files reviewed: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread src/coreclr/jit/emitwasm.cpp Resolved
We created a copy of the SymbolTable before WriteImorts had  a chance to define the imported symbols. If we copy after WriteImports, those show up in _definedSymbols.
Copilot AI review requested due to automatic review settings September 11, 2026 17:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

One or more issues must be addressed before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (2)

src/coreclr/jit/emitwasm.cpp:303

  • Passing params.addr here also exposes external direct-call targets to the new function-index relocation path. GetHelperFtnUncached returns ExternFunctionSymbol for helpers such as RhpNewFast, and those symbols are not registered by RecordMethodDeclaration or WasmSymbolManager; ResolveRelocations therefore fails at _definedSymbols[reloc.SymbolName] (or reports the symbol unregistered) instead of leaving the call for the linker/import table. Keep external calls as unresolved link-time relocations, or register them as function imports before self-resolving only defined methods.
            id  = emitNewInstrSC(EA_HANDLE_CNS_RELOC, (cnsval_ssize_t)params.addr);

src/coreclr/tools/Common/Compiler/ObjectWriter/WasmRelocatableObjectWriter.cs:168

  • This declaration is flush-left inside the switch case, unlike the surrounding C# code and the repository's indentation convention; format it at the same indentation level as the other statements in this block.
long targetAddress = segment.GetMemoryAddressOfOffset((int)(definedSymbol.Value + addend)) + reloc.Addend;
  • Files reviewed: 5/5 changed files
  • Comments generated: 2
  • Review effort level: Lite

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 11, 2026 20:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

One or more issues must be addressed before approval.

Get a fresh assessment by requesting another Copilot review.

Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Lite

Copilot AI review requested due to automatic review settings September 14, 2026 23:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

One or more issues must be addressed before approval.

Review details

Suppressed comments (3)

src/coreclr/tools/Common/Compiler/ObjectWriter/WasmRelocatableObjectWriter.cs:173

  • This new relocation path has no end-to-end NativeAOT/WASM coverage: the existing WASM assertions exercise WebCilObjectWriter, while NativeAOT selects WasmRelocatableObjectWriter (src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/ObjectWriter.Aot.cs:26-33). Add a WASM NativeAOT case that emits a data pointer relocation and verifies the patched linear-memory address, ideally also covering the new unmanaged alias/export, so regressions here cannot leave the existing suite green.
                        case RelocType.IMAGE_REL_BASED_HIGHLOW:
                        {
                            if (_sections[definedSymbol.SectionIndex] is WasmDataSegmentEmitter segment)
                            {
long targetAddress = segment.GetMemoryAddressOfOffset((int)(definedSymbol.Value + addend)) + reloc.Addend;

src/coreclr/tools/Common/Compiler/ObjectWriter/WasmRelocatableObjectWriter.cs:13

  • System.Linq is not used anywhere in this file; please remove the new using to avoid carrying an unnecessary import.
using System.Linq;

src/coreclr/tools/Common/Compiler/ObjectWriter/WasmRelocatableObjectWriter.cs:173

  • addend already contains the relocation delta read from the emitted bytes, and reloc.Addend is the same original delta passed by ObjectDataBuilder.EmitPointerReloc (for example, TypePreinit uses a nonzero field offset). Adding both shifts the pointer twice, so relocations to fields inside a data symbol resolve to the wrong address. Use the symbol value plus the decoded addend once when computing the segment offset.
long targetAddress = segment.GetMemoryAddressOfOffset((int)(definedSymbol.Value + addend)) + reloc.Addend;
  • Files reviewed: 5/5 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@jtschuster

Copy link
Copy Markdown
Member Author

/ba-g failures are #132950 and #133931

@jtschuster
jtschuster merged commit 18eafbd into dotnet:main Sep 15, 2026
132 of 137 checks passed
@github-project-automation github-project-automation Bot moved this to Done in AppModel Sep 15, 2026
jtschuster added a commit to jtschuster/runtime that referenced this pull request Sep 18, 2026
Adds support for resolving IMAGE_REL_BASED_HIGHLOW relocations in the
NativeAOT WASM object writer. This is only supported when the target is
in a data segment that corresponds directly to an ObjectNodeSection
(which most, if not all, will).

Also adds emission of export entries and handling of symbol aliases.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 15, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasm WebAssembly architecture area-NativeAOT-coreclr

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants