From fc3e44dab54e7e1c45316637ff38087b73b6554b Mon Sep 17 00:00:00 2001 From: Max Charlamb Date: Mon, 25 May 2026 17:32:32 -0400 Subject: [PATCH 1/2] [cDAC] Strip ARM32 thumb bit in GetFuncletStartAddress GetFuncletStartAddress returned 'range.Data.RangeBegin + runtimeFunction.BeginAddress' without stripping the ARM32 thumb bit. Since #128154, GetStartAddress returns a thumb-bit-stripped TargetPointer (matching native TADDR semantics). The mismatch caused IsFunclet to return true for every R2R method on ARM32, which made IsFilterFunclet call GetExceptionClauses for non-funclets and throw VirtualReadException when the R2R ExceptionInfo table data was not present in the dump. Run the sum through AddressFromCodePointer so the thumb bit is stripped, matching native RUNTIME_FUNCTION__BeginAddress (clrnt.h, ARM32 branch). Fixes #128292. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Contracts/ExecutionManager/ExecutionManagerCore.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.cs index 3fb14042e32419..4a460e6a240476 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerCore.cs @@ -260,7 +260,8 @@ TargetPointer IExecutionManager.GetFuncletStartAddress(CodeBlockHandle codeInfoH // TODO(cdac): EXCEPTION_DATA_SUPPORTS_FUNCTION_FRAGMENTS, implement iterating over fragments until finding // non-fragment RuntimeFunction - return range.Data.RangeBegin + runtimeFunction.BeginAddress; + return CodePointerUtils.AddressFromCodePointer( + new TargetCodePointer(range.Data.RangeBegin + runtimeFunction.BeginAddress), _target); } void IExecutionManager.GetMethodRegionInfo(CodeBlockHandle codeInfoHandle, out uint hotSize, out TargetPointer coldStart, out uint coldSize) From 2721fbe0fd56a081ed64f791d102e7cebaa2db97 Mon Sep 17 00:00:00 2001 From: Max Charlamb Date: Mon, 25 May 2026 22:50:40 -0400 Subject: [PATCH 2/2] Note ARM32 Thumb bit on RuntimeFunction.BeginAddress Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/design/datacontracts/ExecutionManager.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/design/datacontracts/ExecutionManager.md b/docs/design/datacontracts/ExecutionManager.md index da753bb8b08a43..84ddc5d20dcdfc 100644 --- a/docs/design/datacontracts/ExecutionManager.md +++ b/docs/design/datacontracts/ExecutionManager.md @@ -206,7 +206,7 @@ Data descriptors used: | `ReadyToRunHeader` | `MinorVersion` | ReadyToRun minor version | | `ImageDataDirectory` | `VirtualAddress` | Virtual address of the image data directory | | `ImageDataDirectory` | `Size` | Size of the data | -| `RuntimeFunction` | `BeginAddress` | Begin address of the function | +| `RuntimeFunction` | `BeginAddress` | Begin address of the function. On ARM32, bit 0 (the Thumb bit) is set. | | `RuntimeFunction` | `EndAddress` | End address of the function. Only exists on some platforms | | `RuntimeFunction` | `UnwindData` | Pointer to the unwind info for the function | | `HashMap` | `Buckets` | Pointer to the buckets of a `HashMap` |