From c7353eb3432c5ba1cb48138ab8857f9b691bfcf4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 29 Jul 2026 17:20:25 +0000 Subject: [PATCH 1/5] Restore allocation helper auxiliary symbols Co-authored-by: rcj1 <77995559+rcj1@users.noreply.github.com> --- docs/design/datacontracts/AuxiliarySymbols.md | 6 +- .../data-descriptor-meanings.json | 2 +- src/coreclr/vm/jitinterface.h | 2 +- src/coreclr/vm/jitinterfacegen.cpp | 31 +++++++++ .../DumpTests/AuxiliarySymbolsDumpTests.cs | 65 +++++++++++++++++++ 5 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 src/native/managed/cdac/tests/DumpTests/AuxiliarySymbolsDumpTests.cs diff --git a/docs/design/datacontracts/AuxiliarySymbols.md b/docs/design/datacontracts/AuxiliarySymbols.md index 654dce32c702d7..0712d2d7a5c4e6 100644 --- a/docs/design/datacontracts/AuxiliarySymbols.md +++ b/docs/design/datacontracts/AuxiliarySymbols.md @@ -1,7 +1,7 @@ # Contract AuxiliarySymbols -This contract provides name resolution for helper functions whose executing code -resides at dynamically-determined addresses. +This contract provides name resolution for helper functions for which we do not have or +do not wish to load symbols. ## APIs of contract @@ -20,7 +20,7 @@ bool TryGetAuxiliarySymbolName(TargetPointer ip, out string symbolName); | Data Descriptor | Field | Type | Meaning | | --- | --- | --- | --- | | `AuxiliarySymbolInfo` | *(type size)* | `uint32` | Size in bytes of each entry in the auxiliary symbol array | -| `AuxiliarySymbolInfo` | `Address` | `CodePointer` | Code pointer to the dynamically-located helper function | +| `AuxiliarySymbolInfo` | `Address` | `CodePointer` | Code pointer to the helper function | | `AuxiliarySymbolInfo` | `Name` | `pointer` | Pointer to a null-terminated char string with the helper name | ### Global variables used diff --git a/docs/design/datacontracts/data-descriptor-meanings.json b/docs/design/datacontracts/data-descriptor-meanings.json index 31c963045dd1a8..9465e6efc2a83b 100644 --- a/docs/design/datacontracts/data-descriptor-meanings.json +++ b/docs/design/datacontracts/data-descriptor-meanings.json @@ -22,7 +22,7 @@ "AsyncMethodData.Signature": "The async variant's signature (see `Signature`)", "AsyncMethodData.Size": "Size of the async method data, added when HasAsyncMethodData flag is set", "AsyncResumeInfo.DiagnosticIP": "Native IP into the resumed method used for diagnostics (may be null)", - "AuxiliarySymbolInfo.Address": "Code pointer to the dynamically-located helper function", + "AuxiliarySymbolInfo.Address": "Code pointer to the helper function", "AuxiliarySymbolInfo.Name": "Pointer to a null-terminated char string with the helper name", "AuxiliarySymbolInfo.Size": "Size in bytes of each entry in the auxiliary symbol array", "Bucket.Keys": "Array of keys of `HashMapSlotsPerBucket` length", diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index d84a9315fc0049..42c2847edb8b49 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -1008,7 +1008,7 @@ struct VMAUXILIARYSYMBOLDEF PTR_CSTR name; }; -#define MAX_AUXILIARY_SYMBOLS 7 +#define MAX_AUXILIARY_SYMBOLS 17 #if defined(DACCESS_COMPILE) diff --git a/src/coreclr/vm/jitinterfacegen.cpp b/src/coreclr/vm/jitinterfacegen.cpp index 349455c37de8dc..6556655b726311 100644 --- a/src/coreclr/vm/jitinterfacegen.cpp +++ b/src/coreclr/vm/jitinterfacegen.cpp @@ -11,6 +11,24 @@ #include "ecall.h" #include "writebarriermanager.h" +static void SetJitHelperAuxiliarySymbol(CorInfoHelpFunc ftnNum, const char* name) +{ + LIMITED_METHOD_CONTRACT; + + VMHELPDEF const& helperDef = hlpFuncTable[ftnNum]; + PCODE pfnHelper = helperDef.pfnHelper; + DynamicCorInfoHelpFunc dynamicFtnNum; + if (helperDef.IsDynamicHelper(&dynamicFtnNum)) + { + pfnHelper = hlpDynamicFuncTable[dynamicFtnNum].pfnHelper; + } + + if (pfnHelper != (PCODE)NULL) + { + SetAuxiliarySymbol((void*)pfnHelper, name); + } +} + void InitJITAllocationHelpers() { STANDARD_VM_CONTRACT; @@ -57,4 +75,17 @@ void InitJITAllocationHelpers() #endif } } + +#define SET_NEW_HELPER_AUXILIARY_SYMBOL(code) SetJitHelperAuxiliarySymbol(code, #code); + SET_NEW_HELPER_AUXILIARY_SYMBOL(CORINFO_HELP_NEWFAST) + SET_NEW_HELPER_AUXILIARY_SYMBOL(CORINFO_HELP_NEWFAST_MAYBEFROZEN) + SET_NEW_HELPER_AUXILIARY_SYMBOL(CORINFO_HELP_NEWSFAST) + SET_NEW_HELPER_AUXILIARY_SYMBOL(CORINFO_HELP_NEWSFAST_ALIGN8) + SET_NEW_HELPER_AUXILIARY_SYMBOL(CORINFO_HELP_NEWSFAST_ALIGN8_VC) + SET_NEW_HELPER_AUXILIARY_SYMBOL(CORINFO_HELP_NEWARR_1_DIRECT) + SET_NEW_HELPER_AUXILIARY_SYMBOL(CORINFO_HELP_NEWARR_1_MAYBEFROZEN) + SET_NEW_HELPER_AUXILIARY_SYMBOL(CORINFO_HELP_NEWARR_1_PTR) + SET_NEW_HELPER_AUXILIARY_SYMBOL(CORINFO_HELP_NEWARR_1_VC) + SET_NEW_HELPER_AUXILIARY_SYMBOL(CORINFO_HELP_NEWARR_1_ALIGN8) +#undef SET_NEW_HELPER_AUXILIARY_SYMBOL } diff --git a/src/native/managed/cdac/tests/DumpTests/AuxiliarySymbolsDumpTests.cs b/src/native/managed/cdac/tests/DumpTests/AuxiliarySymbolsDumpTests.cs new file mode 100644 index 00000000000000..04c9c102a188c4 --- /dev/null +++ b/src/native/managed/cdac/tests/DumpTests/AuxiliarySymbolsDumpTests.cs @@ -0,0 +1,65 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using Microsoft.Diagnostics.DataContractReader.Contracts; +using Microsoft.Diagnostics.DataContractReader.TestInfrastructure; +using Xunit; + +namespace Microsoft.Diagnostics.DataContractReader.DumpTests; + +public class AuxiliarySymbolsDumpTests : DumpTestBase +{ + protected override string DebuggeeName => "BasicThreads"; + protected override string DumpType => "full"; + + [ConditionalTheory] + [MemberData(nameof(TestConfigurations))] + [SkipOnVersion("net10.0", "Allocation helpers are not included in the .NET 10 auxiliary symbol table")] + public void NewJitHelpersAreReachableByAddress(TestConfiguration config) + { + InitializeDumpTest(config); + + HashSet expectedHelpers = + [ + "CORINFO_HELP_NEWFAST", + "CORINFO_HELP_NEWFAST_MAYBEFROZEN", + "CORINFO_HELP_NEWSFAST", + "CORINFO_HELP_NEWSFAST_ALIGN8", + "CORINFO_HELP_NEWSFAST_ALIGN8_VC", + "CORINFO_HELP_NEWARR_1_DIRECT", + "CORINFO_HELP_NEWARR_1_MAYBEFROZEN", + "CORINFO_HELP_NEWARR_1_PTR", + "CORINFO_HELP_NEWARR_1_VC", + "CORINFO_HELP_NEWARR_1_ALIGN8", + ]; + Dictionary helpersByAddress = []; + + TargetPointer table = Target.ReadGlobalPointer(Constants.Globals.AuxiliarySymbols); + uint count = Target.Read(Target.ReadGlobalPointer(Constants.Globals.AuxiliarySymbolCount)); + Target.TypeInfo typeInfo = Target.GetTypeInfo(DataType.AuxiliarySymbolInfo); + uint entrySize = typeInfo.Size!.Value; + int addressOffset = typeInfo.Fields["Address"].Offset; + int nameOffset = typeInfo.Fields["Name"].Offset; + + for (uint i = 0; i < count; i++) + { + TargetPointer entry = table + ((ulong)i * entrySize); + TargetPointer namePointer = Target.ReadPointer(entry + (ulong)nameOffset); + string name = Target.ReadUtf8String(namePointer); + if (expectedHelpers.Remove(name)) + { + TargetCodePointer address = Target.ReadCodePointer(entry + (ulong)addressOffset); + Assert.NotEqual(TargetCodePointer.Null, address); + helpersByAddress.TryAdd(address, name); + } + } + + Assert.Empty(expectedHelpers); + foreach ((TargetCodePointer address, string expectedName) in helpersByAddress) + { + Assert.True(Target.Contracts.AuxiliarySymbols.TryGetAuxiliarySymbolName(address.AsTargetPointer, out string? name)); + Assert.Equal(expectedName, name); + } + } +} From 9071b7f3218f0c535a71544338b110db0eb05a41 Mon Sep 17 00:00:00 2001 From: Rachel Jarvi Date: Wed, 29 Jul 2026 15:26:35 -0700 Subject: [PATCH 2/5] Update AuxiliarySymbolsDumpTests.cs --- .../managed/cdac/tests/DumpTests/AuxiliarySymbolsDumpTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/native/managed/cdac/tests/DumpTests/AuxiliarySymbolsDumpTests.cs b/src/native/managed/cdac/tests/DumpTests/AuxiliarySymbolsDumpTests.cs index 04c9c102a188c4..da2b1b76e558be 100644 --- a/src/native/managed/cdac/tests/DumpTests/AuxiliarySymbolsDumpTests.cs +++ b/src/native/managed/cdac/tests/DumpTests/AuxiliarySymbolsDumpTests.cs @@ -16,7 +16,7 @@ public class AuxiliarySymbolsDumpTests : DumpTestBase [ConditionalTheory] [MemberData(nameof(TestConfigurations))] [SkipOnVersion("net10.0", "Allocation helpers are not included in the .NET 10 auxiliary symbol table")] - public void NewJitHelpersAreReachableByAddress(TestConfiguration config) + public void JitHelpersAreReachableByAddress(TestConfiguration config) { InitializeDumpTest(config); From 974a748a36d5cfbd8b4ccc6974c6ec2a14859a2e Mon Sep 17 00:00:00 2001 From: Rachel Jarvi Date: Wed, 29 Jul 2026 16:11:36 -0700 Subject: [PATCH 3/5] Update AuxiliarySymbols.md --- docs/design/datacontracts/AuxiliarySymbols.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/design/datacontracts/AuxiliarySymbols.md b/docs/design/datacontracts/AuxiliarySymbols.md index 0712d2d7a5c4e6..0c06794a61f6c6 100644 --- a/docs/design/datacontracts/AuxiliarySymbols.md +++ b/docs/design/datacontracts/AuxiliarySymbols.md @@ -1,7 +1,8 @@ # Contract AuxiliarySymbols -This contract provides name resolution for helper functions for which we do not have or -do not wish to load symbols. +This contract provides name resolution for helper functions +* whose executing code resides at dynamically-determined addresses or +* that are native helpers used to implement new. ## APIs of contract From 8cfb940ccb68f637e50e3eb2699472b1f5396554 Mon Sep 17 00:00:00 2001 From: Rachel Jarvi Date: Wed, 29 Jul 2026 17:02:10 -0700 Subject: [PATCH 4/5] Update docs/design/datacontracts/AuxiliarySymbols.md Co-authored-by: Noah Falk --- docs/design/datacontracts/AuxiliarySymbols.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/design/datacontracts/AuxiliarySymbols.md b/docs/design/datacontracts/AuxiliarySymbols.md index 0c06794a61f6c6..49ce2212554b82 100644 --- a/docs/design/datacontracts/AuxiliarySymbols.md +++ b/docs/design/datacontracts/AuxiliarySymbols.md @@ -1,6 +1,6 @@ # Contract AuxiliarySymbols -This contract provides name resolution for helper functions +This contract provides name resolution for helper functions. It may include other functions in the future but at minimum it has functions: * whose executing code resides at dynamically-determined addresses or * that are native helpers used to implement new. From 55104059fccb4fd62b16ff97a8da77b4b61c3402 Mon Sep 17 00:00:00 2001 From: Rachel Jarvi Date: Mon, 3 Aug 2026 16:07:10 -0700 Subject: [PATCH 5/5] Add auxiliary symbols for new helper names --- src/coreclr/vm/jitinterfacegen.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coreclr/vm/jitinterfacegen.cpp b/src/coreclr/vm/jitinterfacegen.cpp index 6556655b726311..30a17975a93c49 100644 --- a/src/coreclr/vm/jitinterfacegen.cpp +++ b/src/coreclr/vm/jitinterfacegen.cpp @@ -76,6 +76,7 @@ void InitJITAllocationHelpers() } } +// Debugger depends on new helper names starting with CORINFO_HELP_NEW #define SET_NEW_HELPER_AUXILIARY_SYMBOL(code) SetJitHelperAuxiliarySymbol(code, #code); SET_NEW_HELPER_AUXILIARY_SYMBOL(CORINFO_HELP_NEWFAST) SET_NEW_HELPER_AUXILIARY_SYMBOL(CORINFO_HELP_NEWFAST_MAYBEFROZEN)