Skip to content

Alternative: Introduce TargetPointer type for cross-bitness pointer values#1422

Closed
max-charlamb wants to merge 3 commits intomicrosoft:mainfrom
max-charlamb:fix/cross-bitness-target-pointer
Closed

Alternative: Introduce TargetPointer type for cross-bitness pointer values#1422
max-charlamb wants to merge 3 commits intomicrosoft:mainfrom
max-charlamb:fix/cross-bitness-target-pointer

Conversation

@max-charlamb
Copy link
Copy Markdown
Contributor

Alternative approach: TargetPointer type for cross-bitness support

This branch builds on #1421 and introduces a TargetPointer readonly struct (inspired by the cDAC's TargetPointer) to make it clear at the type level when a value represents a target process pointer vs an arbitrary integer.

What's different from #1421

  • Adds TargetPointer readonly struct wrapping ulong with implicit conversions
  • IMemoryReader.ReadPointer returns TargetPointer instead of ulong
  • SpanExtensions.AsPointer returns TargetPointer instead of ulong
  • All internal callers updated to use TargetPointer
  • Public API stays source-compatible via implicit ulong <-> TargetPointer conversions

Benefits

  • Self-documenting: TargetPointer vs ulong makes intent clear
  • Harder to accidentally mix up a target pointer with an arbitrary number
  • Matches the pattern used by the cDAC in dotnet/runtime

Test results

  • x64: 379 pass, 1 pre-existing fail (FindAllPaths), 4 skip

Max Charlamb and others added 3 commits April 15, 2026 15:16
…erSize

Replace ~50 uses of IntPtr.Size (host pointer size) with the target process's
PointerSize so that dumps from a different architecture can be read correctly
(e.g. reading ARM64 dumps from an x64 host).

Changes across 14 files:
- ClrArray: array length offset, multi-dim detection, rank, element addressing
- ClrObject: boxed value header offset
- ClrInstanceField: field address calculation
- ClrField: GetSize accepts optional pointerSize parameter
- ClrException: all offset methods + stack trace parsing
- ClrHeap: string offsets, alignment, min object size, GC ref scanning,
  finalize queue walking, MemoryCache.ReadPointer
- ClrDacType: GC descriptor reading, array element type, base array offset
- ClrTypeFactory: string type StaticSize
- GCDesc: new constructor overload with explicit pointerSize; all internal
  methods converted
- DacHeap: frozen segment committed start
- DacThreadHelpers: IP/SP reads
- CommonMemoryReader: fix ReadPointer calling AsPointer(pointerSize) which
  bound to the 2-arg overload treating pointerSize as offset instead of size
- SpanExtensions: new 3-arg AsPointer overload (pointerSize, offset)
- SigParser: pointerSize field for PeekElemTypeSize

Bug fix: CommonMemoryReader.ReadPointer was calling AsPointer(pointerSize)
which resolved to the 2-arg overload (span, offset), treating the pointer
size as an offset. Changed to AsPointer(pointerSize, 0) to use the correct
3-arg overload.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…zed reads

Per review feedback from @leculver:

- SpanExtensions: Remove 0-arg and 1-arg AsPointer overloads that defaulted
  to IntPtr.Size. The ulong-offset overload now requires explicit pointerSize.
- SigParser: Remove 2-arg constructor defaulting to IntPtr.Size. All callers
  (ClrEnum, ClrField, MetadataImport) now pass explicit pointer size.
- GCDesc: Remove 1-arg constructor defaulting to IntPtr.Size.
- ClrField.GetSize: Remove pointerSize=0 fallback to IntPtr.Size; parameter
  is now required. Updated ClrPrimitiveType caller.

Additional fixes for host-sized target reads:
- ClrDelegate: Replace Read<UIntPtr> with ReadPointer (target-pointer-aware).
  Replace ReadValues<UIntPtr> loop with GetObjectValue iteration.
- ClrObject.AsRuntimeType: Replace ReadField<nint> with ReadPointer for
  m_handle/m_ptr fields.
- ClrArray.GetObjectValue: Replace ReadValue<nuint> with ReadPointer to
  read target-sized object references.
- ClrEnum: Replace *(nint*) and *(nuint*) with pointer-size-conditional
  reads using target PointerSize.
- ClrInstanceField: Add ReadPointer method for target-pointer-aware reads.
- MetadataImport: Accept pointerSize in constructors, pass to SigParser.
- SigParserBoundsTests: Updated to pass explicit pointer size.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add readonly struct TargetPointer wrapping ulong with implicit conversions
to make it clear at the type level when a value is a target pointer vs an
arbitrary integer. Updated IMemoryReader.ReadPointer, SpanExtensions.AsPointer,
and all internal callers to use TargetPointer.

Public API surface stays source-compatible via implicit conversions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@max-charlamb max-charlamb force-pushed the fix/cross-bitness-target-pointer branch from abf8557 to c54713c Compare April 16, 2026 19:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant