Skip to content

Conversation

@jkoritzinsky
Copy link
Member

Use ObjectNodePhase.Ordered + ObjectNodeOrder to identify "well-known" nodes that need to go into PE data directory entries.

Also provide a mechanism to fold together sections in the ObjectWriter so we can fold rdata into text and use the "managed code" section for managed code in general and only fold to text in emit.

In the process, fix some implicit dependencies that were hidden by "good" ClassCode choices.

Fixes #121416

Use ObjectNodePhase.Ordered + ObjectNodeOrder to identify "well-known" nodes that need to go into PE data directory entries.

Also provide a mechanism to fold together sections in the ObjectWriter so we can fold rdata into text and use the "managed code" section for managed code in general and only fold to text in emit.

In the process, fix some implicit dependencies that were hidden by "good" ClassCode choices.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR reduces the number of sections in R2R PE files by implementing a section folding mechanism and using ObjectNodePhase.Ordered with ObjectNodeOrder to identify well-known nodes that need to be referenced in PE data directory entries.

Key changes:

  • Introduces GetEmitSection method in ObjectWriter to allow PE files to fold rdata into text and use generic managed code sections that get mapped to text at emit time
  • Implements RecordWellKnownSymbol mechanism to track symbols that correspond to PE directory entries (Win32 resources, debug directory, CLR header, exception table)
  • Simplifies node section assignments by removing format-specific logic and relying on emit-time section folding

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
Win32ResourcesNode.cs Simplified to always return ReadOnlyDataSection, removing PE-specific logic
RuntimeFunctionsTableNode.cs Changed to return TextSection and added Phase/ClassCode to mark as well-known symbol
RuntimeFunctionsGCInfoNode.cs Simplified to return ReadOnlyDataSection and added Phase/ClassCode for ordering
MethodWithGCInfo.cs Updated to return ManagedCodeWindowsContentSection for PE (gets folded to TextSection at emit)
MethodColdCodeNode.cs Updated to return ManagedCodeWindowsContentSection for PE (gets folded to TextSection at emit)
DebugDirectoryNode.cs Changed to return TextSection and updated ClassCode to use enum value
CopiedStrongNameSignatureNode.cs Simplified to always return ReadOnlyDataSection, removing PE-specific logic
CopiedMethodILNode.cs Simplified to always return ReadOnlyDataSection, removing PE-specific logic
CopiedMetadataBlobNode.cs Simplified to always return ReadOnlyDataSection, removing PE-specific logic
CopiedManagedResourcesNode.cs Simplified to always return ReadOnlyDataSection, removing PE-specific logic
CopiedFieldRvaNode.cs Simplified to always return ReadOnlyDataSection, removing PE-specific logic
CopiedCorHeaderNode.cs Simplified to always return ReadOnlyDataSection, removing PE-specific logic
CoffObjectWriter.Aot.cs Defined local XDataSection and PDataSection constants to replace removed global constants
PEObjectWriter.cs Implemented GetEmitSection to fold sections and RecordWellKnownSymbol to track PE directory entries; refactored directory population to use symbol-based lookup
ObjectWriter.cs Added GetEmitSection virtual method and RecordWellKnownSymbol callback mechanism
CoffObjectWriter.cs Added handling for SectionType.UnwindData; removed special DebugDirectorySection handling
ObjectNodeSection.cs Removed unused section constants (XDataSection, DebugDirectorySection, CorMetaSection, Win32ResourcesSection, PDataSection)
SortableDependencyNode.cs Made ObjectNodePhase and ObjectNodeOrder enums internal; added new entries for DebugDirectoryNode, RuntimeFunctionsGCInfoNode, and RuntimeFunctionsTableNode

jkoritzinsky and others added 2 commits December 12, 2025 15:29
Remove now-invalid assert
@jkoritzinsky
Copy link
Member Author

I think we may have just pushed some reloc out of range on riscv. @am11 any ideas?

@am11
Copy link
Member

am11 commented Dec 13, 2025

This diff fixes the issue: gh-122511_riscv64.diff.txt. Perhaps @tomeksowi and @filipnavara would like to give their review on it. :)

On riscv64, RuyJIT primarily emits PC-relative call and address-materialization sequences using R_RISCV_CALL_PLT and R_RISCV_PCREL_HI20/LO12_* relocations. As with other architectures, although the ELF ABI defines a large number of relocation types, both system libraries and CoreCLR converge on a small, stable subset in practice.

RISC-V’s design separates address materialization from control transfer and treats linker relaxation as a first-class concept, which allows these generic PC-relative sequences to be reused across symbol classes and code models and adapted by the linker as needed. The main trade-off is that these sequences remain fundamentally limited to a ±2 GB PC-relative range.

@tomeksowi
Copy link
Member

This diff fixes the issue: gh-122511_riscv64.diff.txt. Perhaps @tomeksowi and @filipnavara would like to give their review on it. :)

LGTM, thanks :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Adjust PEObjectWriter to not emit data into separate sections for separate image data directories

3 participants