Skip to content

[cDAC] X86 support HijackFrame #116829

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/design/datacontracts/StackWalk.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ This contract depends on the following descriptors:
| `HijackFrame` | `HijackArgsPtr` | Pointer to the Frame's stored HijackArgs |
| `HijackArgs` (amd64) | `CalleeSavedRegisters` | CalleeSavedRegisters data structure |
| `HijackArgs` (amd64 Windows) | `Rsp` | Saved stack pointer |
| `HijackArgs` (arm64) | For each register `r` saved in HijackArgs, `r` | Register names associated with stored register values |
| `HijackArgs` (arm64/x86) | For each register `r` saved in HijackArgs, `r` | Register names associated with stored register values |
| `CalleeSavedRegisters` | For each callee saved register `r`, `r` | Register names associated with stored register values |

Global variables used:
Expand Down
11 changes: 11 additions & 0 deletions src/coreclr/debug/runtimeinfo/datadescriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,17 @@ CDAC_TYPE_FIELD(HijackArgs, /*pointer*/, X28, offsetof(HijackArgs, X28))
CDAC_TYPE_FIELD(HijackArgs, /*pointer*/, Fp, offsetof(HijackArgs, X29))
CDAC_TYPE_FIELD(HijackArgs, /*pointer*/, Lr, offsetof(HijackArgs, Lr))

#elif defined(TARGET_X86)

CDAC_TYPE_FIELD(HijackArgs, /*pointer*/, Edi, offsetof(HijackArgs, Edi))
CDAC_TYPE_FIELD(HijackArgs, /*pointer*/, Esi, offsetof(HijackArgs, Esi))
CDAC_TYPE_FIELD(HijackArgs, /*pointer*/, Ebx, offsetof(HijackArgs, Ebx))
CDAC_TYPE_FIELD(HijackArgs, /*pointer*/, Edx, offsetof(HijackArgs, Edx))
CDAC_TYPE_FIELD(HijackArgs, /*pointer*/, Ecx, offsetof(HijackArgs, Ecx))
CDAC_TYPE_FIELD(HijackArgs, /*pointer*/, Eax, offsetof(HijackArgs, Eax))
CDAC_TYPE_FIELD(HijackArgs, /*pointer*/, Ebp, offsetof(HijackArgs, Ebp))
CDAC_TYPE_FIELD(HijackArgs, /*pointer*/, Eip, offsetof(HijackArgs, Eip))

#endif // Platform switch
CDAC_TYPE_END(HijackArgs)
#endif // FEATURE_HIJACK
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ void IPlatformFrameHandler.HandleHijackFrame(HijackFrame frame)

_holder.InstructionPointer = frame.ReturnAddress;

// The stack pointer is the address immediately following HijacksArgs
// The stack pointer is the address immediately following HijackArgs
uint hijackArgsSize = _target.GetTypeInfo(DataType.HijackArgs).Size ?? throw new InvalidOperationException("HijackArgs size is not set");
Debug.Assert(hijackArgsSize % 8 == 0, "HijackArgs contains register values and should be a multiple of 8");
// The stack must be multiple of 16. So if hijackArgsSize is not multiple of 16 then there must be padding of 8 bytes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ void IPlatformFrameHandler.HandleFaultingExceptionFrame(FaultingExceptionFrame f

void IPlatformFrameHandler.HandleHijackFrame(HijackFrame frame)
{
// TODO(cdacX86): Implement handling for HijackFrame
throw new NotImplementedException();
HijackArgsX86 args = _target.ProcessedData.GetOrAdd<HijackArgsX86>(frame.HijackArgsPtr);

// The stack pointer is the address immediately following HijackArgs
uint hijackArgsSize = _target.GetTypeInfo(DataType.HijackArgs).Size ?? throw new InvalidOperationException("HijackArgs size is not set");
_context.Context.Esp = (uint)frame.HijackArgsPtr + hijackArgsSize;

UpdateFromRegisterDict(args.Registers);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// 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;

namespace Microsoft.Diagnostics.DataContractReader.Data;

internal class HijackArgsX86 : IData<HijackArgsX86>
{
static HijackArgsX86 IData<HijackArgsX86>.Create(Target target, TargetPointer address)
=> new HijackArgsX86(target, address);

public HijackArgsX86(Target target, TargetPointer address)
{
Target.TypeInfo type = target.GetTypeInfo(DataType.HijackArgs);

Dictionary<string, TargetNUInt> registers = new Dictionary<string, TargetNUInt>(type.Fields.Count);
foreach ((string name, Target.FieldInfo field) in type.Fields)
{
TargetNUInt value = target.ReadNUInt(address + (ulong)field.Offset);
registers.Add(name, value);
}
Registers = registers;
}

public IReadOnlyDictionary<string, TargetNUInt> Registers { get; }
}
Loading