Align manifest assembly MVID table to 4 bytes in composite R2R images#129017
Open
jtschuster wants to merge 1 commit into
Open
Align manifest assembly MVID table to 4 bytes in composite R2R images#129017jtschuster wants to merge 1 commit into
jtschuster wants to merge 1 commit into
Conversation
ManifestAssemblyMvidHeaderNode emitted the assembly MVID table (a packed array of 16-byte GUIDs) with alignment 1. The CoreCLR runtime reads each entry as a GUID by value, and GUID has a natural alignment of 4. When the table landed on a non-4-aligned RVA, 32-bit ARM faulted with BUS_ADRALN (SIGBUS) because it does not permit unaligned multi-word loads. Other architectures tolerated the unaligned access, so the crash only manifested on ARM32. The table's RVA depends on the size of the preceding Ordered ReadOnlyData node. In composites built with debug directory entries (e.g. --pdb), an odd-sized NativeDebugDirectoryEntryNode can precede the MVID table and push it off a 4-byte boundary. Setting the alignment to 4 pads the table to a valid boundary regardless of predecessor size. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Member
Author
|
/azp run runtime-coreclr crossgen2-composite |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the ReadyToRun (crossgen2) emitter for composite images so the manifest assembly MVID table is emitted with 4-byte alignment, preventing potential unaligned GUID loads by the CoreCLR runtime on alignment-sensitive architectures (notably 32-bit ARM).
Changes:
- Change
ManifestAssemblyMvidHeaderNodeoutput alignment from 1 to 4 bytes. - Add an explanatory comment documenting the runtime read pattern and the alignment requirement.
Comment on lines
+60
to
+65
| // The runtime reads each entry of this table as a GUID by value (see | ||
| // ReadyToRunInfo::ReadyToRunInfo in readytoruninfo.cpp). GUID has a natural | ||
| // alignment of 4, so the table must be at least 4-byte aligned. Without this, | ||
| // a misaligned base causes an alignment fault (SIGBUS) on architectures that | ||
| // do not permit unaligned multi-word loads, such as 32-bit ARM. | ||
| return new ObjectData(manifestAssemblyMvidTable, Array.Empty<Relocation>(), alignment: 4, new ISymbolDefinitionNode[] { this }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a 32-bit ARM
SIGBUS(alignment fault) when running composite Ready-to-Run images.ManifestAssemblyMvidHeaderNodeemits the assembly MVID table — a packed array of 16-byte GUIDs — withalignment: 1. The CoreCLR runtime reads each entry as aGUIDby value (ReadyToRunInfoinreadytoruninfo.cpp), andGUIDhas a natural alignment of 4. When the table landed on a non-4-aligned RVA, ARM32 faulted withBUS_ADRALNbecause it does not permit unaligned multi-word loads. x64/arm64 tolerate the unaligned access, so the crash only manifested on ARM32.Why the table could land unaligned
The table's RVA depends on the size of the preceding
OrderedReadOnlyDatanode. In composites built with debug directory entries (e.g.--pdb), an odd-sizedNativeDebugDirectoryEntryNode(RSDS record) sorts betweenRuntimeFunctionsTableNodeand the MVID table and can push it off a 4-byte boundary.The fix
Set the node alignment to 4 so the table is padded to a valid boundary regardless of predecessor size.
Validation
Reproduced on current
mainwith a controlled experiment (identical inputs and output name, so the predecessor node is byte-for-byte identical; the only variable is the alignment value):This matches the structure of a real failing ARM32 image, whose MVID table sat at RVA
0x28f49(&3 = 1), consistent with the fault'ssi_addrin the kernel core.Note
This pull request was authored with assistance from GitHub Copilot.