Skip to content

Add NativeAOT support to Microsoft.FileFormats - #6103

Open
max-charlamb wants to merge 3 commits into
dotnet:mainfrom
max-charlamb:dev/max-charlamb/fileformats-nativeaot-registration
Open

max-charlamb wants to merge 3 commits into
dotnet:mainfrom
max-charlamb:dev/max-charlamb/fileformats-nativeaot-registration

Conversation

@max-charlamb

@max-charlamb max-charlamb commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

Summary

Add NativeAOT support to Microsoft.FileFormats while retaining the existing binary models, layout calculations, and legacy reflection-discovery APIs.

  • Add a modern net8.0 package target with AOT and trimming analysis enabled.
  • Add lazy, type-specific structure and pointer registration, plus generic array layouts and fixed-array allocation registration.
  • Use metadata field order for registered structures and retain the existing packing, alignment, inheritance, and conditional-field behavior.
  • Switch built-in PE, ELF, Mach-O, minidump, and PDB/MSFZ readers to explicit registrations under the existing setup helper names.
  • Annotate legacy reflection and dynamic-allocation paths with RequiresDynamicCode and RequiresUnreferencedCode.
  • Add registered-layout tests, a standalone NativeAOT verification executable, and a breaking-change migration notice.
  • Advance Microsoft.FileFormats to the 1.1 package series while preserving Arcade build-number patch versioning.

Breaking change: custom TStruct discovery on built-in readers

The only intentional parsing-behavior break is narrowly scoped: readers created by the built-in format parsers, and managers configured with the built-in format helpers, no longer automatically discover arbitrary user-defined TStruct models. Built-in structures remain registered and normal format parsing is unchanged.

For example, callers reading their own structure through PEFile.RelativeVirtualAddressReader or a reader returned by PDBFile.GetStream() must now register it before reading:

reader.LayoutManager.RegisterTStruct<MyHeader>();
MyHeader header = reader.Read<MyHeader>(position);

Without a registration or discovery provider, that custom read throws LayoutException. Untrimmed managed callers can opt back into legacy discovery with reader.LayoutManager.AddTStructTypes() (and AddPointerTypes() when needed), supplying any required conditional-field defines.

The default Reader(IAddressSpace, bool) constructor still supports automatic reflection discovery. It is not affected by this change. A public GitHub search found no confirmed consumer relying on custom-model discovery through the affected built-in readers; private and unindexed usage cannot be ruled out.

The existing generic GetArrayLayout<T>(count) retains its original array-type semantics, including GetArrayLayout<byte[]>(count). The new GetArrayLayoutForElement<T>(count) is additive.

Existing .NET Framework and .NET Standard package targets remain available.

See the breaking-change notice for details. Separately, legacy APIs now carry AOT/trimming annotations; consumers enabling those analyzers may receive new diagnostics, but ordinary managed discovery remains available.

Local validation

  • Forced net8.0 Release rebuild with AOT and trimming analyzers: zero warnings/errors.
  • Library builds across net462, netstandard2.0, and net8.0.
  • FileFormats managed unit suite: 97 passed, one existing Mach core fixture skip.
  • Added 16 custom-model regression cases comparing strongly typed registration and legacy reflection discovery across endianness, pointer sizes, conditional fields, mixed dependencies, and standalone arrays. Shared expected-value checks also run in the NativeAOT executable.
  • Published and ran the standalone win-x64 NativeAOT verification executable.
  • Temporary managed and native consumers produced identical 1,244-line results: 51 built-in models across 158 layout cases and 17 configurations; 15 binary fixtures, including ELF cores, nested minidump images, and PDB/MSFZ streams; PerfMap; custom models; and registration/allocation failure cases.
  • Packed the current library and published a separate NativeAOT consumer against the NuGet package. It selected lib/net8.0/Microsoft.FileFormats.dll and produced identical results.
  • Supported consumer APIs compile with warnings treated as errors. Representative legacy calls emit the expected IL3050 and IL2026 diagnostics.

Native execution was validated on Windows x64. Other host platforms and real big-endian Mach-O parsing are not claimed.

Max Charlamb and others added 2 commits October 9, 2026 00:35
Register built-in and custom binary layouts with statically preserved types. Retain annotated legacy discovery, add typed arrays and pointers, and document compatibility changes and native verification.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d3a2bca0-4757-4577-b682-c03acab64110
Compare registered custom models with legacy reflection layouts across endian, pointer-size, conditional-field, mixed-dependency and array cases. Reuse expected-value checks in the NativeAOT harness.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d3a2bca0-4757-4577-b682-c03acab64110
Restore legacy generic array-type semantics and expose typed allocation through GetArrayLayoutForElement<T>. Add compatibility regressions, advance FileFormats to the 1.1 series, and replace the general instructions with a breaking-change migration notice.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d3a2bca0-4757-4577-b682-c03acab64110
@max-charlamb
max-charlamb marked this pull request as ready for review October 9, 2026 14:27
@max-charlamb
max-charlamb requested a review from a team as a code owner October 9, 2026 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant