@@ -3406,6 +3406,201 @@ BOOL DacDbiInterfaceImpl::IsExceptionObject(MethodTable* pMT)
3406
3406
return FALSE ;
3407
3407
}
3408
3408
3409
+ HRESULT DacDbiInterfaceImpl::GetMethodDescPtrFromIpEx (TADDR funcIp, VMPTR_MethodDesc* ppMD)
3410
+ {
3411
+ DD_ENTER_MAY_THROW;
3412
+
3413
+ // The fast path is check if the code is jitted and the code manager has it available.
3414
+ CLRDATA_ADDRESS mdAddr;
3415
+ HRESULT hr = g_dacImpl->GetMethodDescPtrFromIP (TO_CDADDR (funcIp), &mdAddr);
3416
+ if (S_OK == hr)
3417
+ {
3418
+ ppMD->SetDacTargetPtr (CLRDATA_ADDRESS_TO_TADDR (mdAddr));
3419
+ return hr;
3420
+ }
3421
+
3422
+ // Otherwise try to see if a method desc is available for the method that isn't jitted by walking the code stubs.
3423
+ MethodDesc* pMD = MethodTable::GetMethodDescForSlotAddress (PINSTRToPCODE (funcIp));
3424
+
3425
+ if (pMD == NULL )
3426
+ return E_INVALIDARG;
3427
+
3428
+ ppMD->SetDacTargetPtr (PTR_HOST_TO_TADDR (pMD));
3429
+ return S_OK;
3430
+ }
3431
+
3432
+ BOOL DacDbiInterfaceImpl::IsDelegate (VMPTR_Object vmObject)
3433
+ {
3434
+ DD_ENTER_MAY_THROW;
3435
+
3436
+ if (vmObject.IsNull ())
3437
+ return FALSE ;
3438
+
3439
+ Object *pObj = vmObject.GetDacPtr ();
3440
+ return pObj->GetGCSafeMethodTable ()->IsDelegate ();
3441
+ }
3442
+
3443
+
3444
+ // -----------------------------------------------------------------------------
3445
+ // DacDbi API: GetDelegateType
3446
+ // Given a delegate pointer, compute the type of delegate according to the data held in it.
3447
+ // -----------------------------------------------------------------------------
3448
+ HRESULT DacDbiInterfaceImpl::GetDelegateType (VMPTR_Object delegateObject, DelegateType *delegateType)
3449
+ {
3450
+ DD_ENTER_MAY_THROW;
3451
+
3452
+ _ASSERTE (!delegateObject.IsNull ());
3453
+ _ASSERTE (delegateType != NULL );
3454
+
3455
+ #ifdef _DEBUG
3456
+ // ensure we have a Delegate object
3457
+ IsDelegate (delegateObject);
3458
+ #endif
3459
+
3460
+ // Ideally, we would share the implementation of this method with the runtime, or get the same information
3461
+ // we are getting from here from other EE methods. Nonetheless, currently the implementation is sharded across
3462
+ // several pieces of logic so this replicates the logic mostly due to time constraints. The Mainly from:
3463
+ // - System.Private.CoreLib!System.Delegate.GetMethodImpl and System.Private.CoreLib!System.MulticastDelegate.GetMethodImpl
3464
+ // - System.Private.CoreLib!System.Delegate.GetTarget and System.Private.CoreLib!System.MulticastDelegate.GetTarget
3465
+ // - coreclr!COMDelegate::GetMethodDesc and coreclr!COMDelegate::FindMethodHandle
3466
+ // - coreclr!COMDelegate::DelegateConstruct and the delegate type table in
3467
+ // - DELEGATE KINDS TABLE in comdelegate.cpp
3468
+
3469
+ *delegateType = DelegateType::kUnknownDelegateType ;
3470
+ PTR_DelegateObject pDelObj = dac_cast<PTR_DelegateObject>(delegateObject.GetDacPtr ());
3471
+ INT_PTR invocationCount = pDelObj->GetInvocationCount ();
3472
+
3473
+ if (invocationCount == -1 )
3474
+ {
3475
+ // We could get a native code for this case from _methodPtr, but not a methodDef as we'll need.
3476
+ // We can also get the shuffling thunk. However, this doesn't have a token and there's
3477
+ // no easy way to expose through the DBI now.
3478
+ *delegateType = kUnmanagedFunctionDelegate ;
3479
+ return S_OK;
3480
+ }
3481
+
3482
+ PTR_Object pInvocationList = OBJECTREFToObject (pDelObj->GetInvocationList ());
3483
+
3484
+ if (invocationCount == NULL )
3485
+ {
3486
+ if (pInvocationList == NULL )
3487
+ {
3488
+ // If this delegate points to a static function or this is a open virtual delegate, this should be non-null
3489
+ // Special case: This might fail in a VSD delegate (instance open virtual)...
3490
+ // TODO: There is the special signatures cases missing.
3491
+ TADDR targetMethodPtr = PCODEToPINSTR (pDelObj->GetMethodPtrAux ());
3492
+ if (targetMethodPtr == NULL )
3493
+ {
3494
+ // Static extension methods, other closed static delegates, and instance delegates fall into this category.
3495
+ *delegateType = kClosedDelegate ;
3496
+ }
3497
+ else {
3498
+ *delegateType = kOpenDelegate ;
3499
+ }
3500
+
3501
+ return S_OK;
3502
+ }
3503
+ }
3504
+ else
3505
+ {
3506
+ if (pInvocationList != NULL )
3507
+ {
3508
+ PTR_MethodTable invocationListMT = pInvocationList->GetGCSafeMethodTable ();
3509
+
3510
+ if (invocationListMT->IsArray ())
3511
+ *delegateType = kTrueMulticastDelegate ;
3512
+
3513
+ if (invocationListMT->IsDelegate ())
3514
+ *delegateType = kSecureDelegate ;
3515
+
3516
+ // Cases missing: Loader allocator, or dynamic resolver.
3517
+ return S_OK;
3518
+ }
3519
+
3520
+ // According to the table in comdelegates.cpp, there shouldn't be a case where .
3521
+ // Multicast falls outside of the table, so not
3522
+ }
3523
+
3524
+ _ASSERT (FALSE );
3525
+ *delegateType = kUnknownDelegateType ;
3526
+ return CORDBG_E_UNSUPPORTED_DELEGATE;
3527
+ }
3528
+
3529
+ HRESULT DacDbiInterfaceImpl::GetDelegateFunctionData (
3530
+ DelegateType delegateType,
3531
+ VMPTR_Object delegateObject,
3532
+ OUT VMPTR_DomainFile *ppFunctionDomainFile,
3533
+ OUT mdMethodDef *pMethodDef)
3534
+ {
3535
+ DD_ENTER_MAY_THROW;
3536
+
3537
+ #ifdef _DEBUG
3538
+ // ensure we have a Delegate object
3539
+ IsDelegate (delegateObject);
3540
+ #endif
3541
+
3542
+ HRESULT hr = S_OK;
3543
+ PTR_DelegateObject pDelObj = dac_cast<PTR_DelegateObject>(delegateObject.GetDacPtr ());
3544
+ TADDR targetMethodPtr = NULL ;
3545
+ VMPTR_MethodDesc pMD;
3546
+
3547
+ switch (delegateType)
3548
+ {
3549
+ case kClosedDelegate :
3550
+ targetMethodPtr = PCODEToPINSTR (pDelObj->GetMethodPtr ());
3551
+ break ;
3552
+ case kOpenDelegate :
3553
+ targetMethodPtr = PCODEToPINSTR (pDelObj->GetMethodPtrAux ());
3554
+ break ;
3555
+ default :
3556
+ return E_FAIL;
3557
+ }
3558
+
3559
+ hr = GetMethodDescPtrFromIpEx (targetMethodPtr, &pMD);
3560
+ if (hr != S_OK)
3561
+ return hr;
3562
+
3563
+ ppFunctionDomainFile->SetDacTargetPtr (dac_cast<TADDR>(pMD.GetDacPtr ()->GetModule ()->GetDomainFile ()));
3564
+ *pMethodDef = pMD.GetDacPtr ()->GetMemberDef ();
3565
+
3566
+ return hr;
3567
+ }
3568
+
3569
+ HRESULT DacDbiInterfaceImpl::GetDelegateTargetObject (
3570
+ DelegateType delegateType,
3571
+ VMPTR_Object delegateObject,
3572
+ OUT VMPTR_Object *ppTargetObj,
3573
+ OUT VMPTR_AppDomain *ppTargetAppDomain)
3574
+ {
3575
+ DD_ENTER_MAY_THROW;
3576
+
3577
+ #ifdef _DEBUG
3578
+ // ensure we have a Delegate object
3579
+ IsDelegate (delegateObject);
3580
+ #endif
3581
+
3582
+ HRESULT hr = S_OK;
3583
+ PTR_DelegateObject pDelObj = dac_cast<PTR_DelegateObject>(delegateObject.GetDacPtr ());
3584
+
3585
+ switch (delegateType)
3586
+ {
3587
+ case kClosedDelegate :
3588
+ {
3589
+ PTR_Object pRemoteTargetObj = OBJECTREFToObject (pDelObj->GetTarget ());
3590
+ ppTargetObj->SetDacTargetPtr (pRemoteTargetObj.GetAddr ());
3591
+ ppTargetAppDomain->SetDacTargetPtr (dac_cast<TADDR>(pRemoteTargetObj->GetGCSafeMethodTable ()->GetDomain ()->AsAppDomain ()));
3592
+ break ;
3593
+ }
3594
+
3595
+ default :
3596
+ ppTargetObj->SetDacTargetPtr (NULL );
3597
+ ppTargetAppDomain->SetDacTargetPtr (dac_cast<TADDR>(pDelObj->GetGCSafeMethodTable ()->GetDomain ()->AsAppDomain ()));
3598
+ break ;
3599
+ }
3600
+
3601
+ return hr;
3602
+ }
3603
+
3409
3604
void DacDbiInterfaceImpl::GetStackFramesFromException (VMPTR_Object vmObject, DacDbiArrayList<DacExceptionCallStackData>& dacStackFrames)
3410
3605
{
3411
3606
DD_ENTER_MAY_THROW;
0 commit comments