// // Returns the AppDomain that this assembly belongs to. // // Arguments: // ppAppDomain - a non-NULL pointer to store the AppDomain in. // // Return Value: // S_OK // // Notes: // On the debugger right-side we currently consider every assembly to belong // to a single AppDomain, and create multiple CordbAssembly instances (one // per AppDomain) to represent domain-neutral assemblies. // HRESULT CordbAssembly::GetAppDomain(ICorDebugAppDomain **ppAppDomain) { PUBLIC_API_ENTRY(this); FAIL_IF_NEUTERED(this); VALIDATE_POINTER_TO_OBJECT(ppAppDomain, ICorDebugAppDomain **); _ASSERTE(m_pAppDomain != NULL); *ppAppDomain = static_cast<ICorDebugAppDomain *> (m_pAppDomain); m_pAppDomain->ExternalAddRef(); return S_OK; }
/* * GetProcess returns the process containing the app domain */ HRESULT CordbAppDomain::GetProcess(ICorDebugProcess **ppProcess) { PUBLIC_REENTRANT_API_ENTRY(this); FAIL_IF_NEUTERED(this); VALIDATE_POINTER_TO_OBJECT(ppProcess,ICorDebugProcess **); _ASSERTE (m_pProcess != NULL); *ppProcess = static_cast<ICorDebugProcess *> (m_pProcess); m_pProcess->ExternalAddRef(); return S_OK; }
HRESULT CordbRegisterSet::GetRegisters(ULONG64 mask, ULONG32 regCount, CORDB_REGISTER regBuffer[]) { FAIL_IF_NEUTERED(this); UINT iRegister = 0; VALIDATE_POINTER_TO_OBJECT_ARRAY(regBuffer, CORDB_REGISTER, regCount, true, true); if( mask & SETBITULONG64(REGISTER_INSTRUCTION_POINTER) ) { regBuffer[iRegister++] = m_rd->PC; } _ASSERTE( iRegister <= regCount ); return S_OK; }
HRESULT CordbRegisterSet::GetRegisters(ULONG64 mask, ULONG32 regCount, CORDB_REGISTER regBuffer[]) { PUBLIC_REENTRANT_API_ENTRY(this); FAIL_IF_NEUTERED(this); ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess()); UINT iRegister = 0; VALIDATE_POINTER_TO_OBJECT_ARRAY(regBuffer, CORDB_REGISTER, regCount, true, true); // @ARM64TODO: floating point support for (int i = REGISTER_ARM64_X0; i <= REGISTER_ARM64_PC && iRegister < regCount; i++) { if (mask & SETBITULONG64(i)) { if ((i >= REGISTER_ARM64_X0) && (i <= REGISTER_ARM64_X28)) { regBuffer[iRegister++] = m_rd->X[i - REGISTER_ARM64_X0]; continue; } switch (i) { case REGISTER_ARM64_PC: regBuffer[iRegister++] = m_rd->PC; break; case REGISTER_ARM64_SP: regBuffer[iRegister++] = m_rd->SP; break; case REGISTER_ARM64_FP: regBuffer[iRegister++] = m_rd->FP; break; case REGISTER_ARM64_LR: regBuffer[iRegister++] = m_rd->LR; break; default: _ASSERTE(false); break; } } } _ASSERTE (iRegister <= regCount); return S_OK; }
HRESULT CordbRegisterSet::GetRegistersAvailable(ULONG64* pAvailable) { FAIL_IF_NEUTERED(this); VALIDATE_POINTER_TO_OBJECT(pAvailable, ULONG64 *); *pAvailable = SETBITULONG64(REGISTER_ARM64_PC) | SETBITULONG64(REGISTER_ARM64_SP) | SETBITULONG64(REGISTER_ARM64_X0) | SETBITULONG64(REGISTER_ARM64_X1) | SETBITULONG64(REGISTER_ARM64_X2) | SETBITULONG64(REGISTER_ARM64_X3) | SETBITULONG64(REGISTER_ARM64_X4) | SETBITULONG64(REGISTER_ARM64_X5) | SETBITULONG64(REGISTER_ARM64_X6) | SETBITULONG64(REGISTER_ARM64_X7) | SETBITULONG64(REGISTER_ARM64_X8) | SETBITULONG64(REGISTER_ARM64_X9) | SETBITULONG64(REGISTER_ARM64_X10) | SETBITULONG64(REGISTER_ARM64_X11) | SETBITULONG64(REGISTER_ARM64_X12) | SETBITULONG64(REGISTER_ARM64_X13) | SETBITULONG64(REGISTER_ARM64_X14) | SETBITULONG64(REGISTER_ARM64_X15) | SETBITULONG64(REGISTER_ARM64_X16) | SETBITULONG64(REGISTER_ARM64_X17) | SETBITULONG64(REGISTER_ARM64_X18) | SETBITULONG64(REGISTER_ARM64_X19) | SETBITULONG64(REGISTER_ARM64_X20) | SETBITULONG64(REGISTER_ARM64_X21) | SETBITULONG64(REGISTER_ARM64_X22) | SETBITULONG64(REGISTER_ARM64_X23) | SETBITULONG64(REGISTER_ARM64_X24) | SETBITULONG64(REGISTER_ARM64_X25) | SETBITULONG64(REGISTER_ARM64_X26) | SETBITULONG64(REGISTER_ARM64_X27) | SETBITULONG64(REGISTER_ARM64_X28) | SETBITULONG64(REGISTER_ARM64_FP) | SETBITULONG64(REGISTER_ARM64_LR); return S_OK; }
HRESULT CordbAppDomain::EnumerateBreakpoints(ICorDebugBreakpointEnum **ppBreakpoints) { PUBLIC_API_ENTRY(this); FAIL_IF_NEUTERED(this); ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess()); VALIDATE_POINTER_TO_OBJECT(ppBreakpoints, ICorDebugBreakpointEnum **); HRESULT hr = S_OK; EX_TRY { RSInitHolder<CordbHashTableEnum> pEnum; CordbHashTableEnum::BuildOrThrow( this, GetProcess()->GetContinueNeuterList(), // ownership &m_breakpoints, IID_ICorDebugBreakpointEnum, pEnum.GetAddr()); pEnum.TransferOwnershipExternal(ppBreakpoints); } EX_CATCH_HRESULT(hr); return hr; }
HRESULT CordbRegisterSet::GetRegistersAvailable(ULONG64 *pAvailable) { FAIL_IF_NEUTERED(this); VALIDATE_POINTER_TO_OBJECT(pAvailable, ULONG64 *); *pAvailable = SETBITULONG64(REGISTER_INSTRUCTION_POINTER) | SETBITULONG64(REGISTER_STACK_POINTER) | SETBITULONG64(REGISTER_ARM_R0) | SETBITULONG64(REGISTER_ARM_R1) | SETBITULONG64(REGISTER_ARM_R2) | SETBITULONG64(REGISTER_ARM_R3) | SETBITULONG64(REGISTER_ARM_R4) | SETBITULONG64(REGISTER_ARM_R5) | SETBITULONG64(REGISTER_ARM_R6) | SETBITULONG64(REGISTER_ARM_R7) | SETBITULONG64(REGISTER_ARM_R8) | SETBITULONG64(REGISTER_ARM_R9) | SETBITULONG64(REGISTER_ARM_R10) | SETBITULONG64(REGISTER_ARM_R11) | SETBITULONG64(REGISTER_ARM_R12) | SETBITULONG64(REGISTER_ARM_LR); return S_OK; }
//----------------------------------------------------------------------------- // Get a ICorDebugValue for a static field on this class. // // Parameters: // fieldDef - metadata token for field on this class. Can not be from an // inherited class. // pFrame - frame used to resolve Thread-static, AppDomain-static, etc. // ppValue - OUT: gets value of the field. // // Returns: // S_OK on success. // CORDBG_E_STATIC_VAR_NOT_AVAILABLE //----------------------------------------------------------------------------- HRESULT CordbClass::GetStaticFieldValue(mdFieldDef fieldDef, ICorDebugFrame *pFrame, ICorDebugValue **ppValue) { PUBLIC_REENTRANT_API_ENTRY(this); FAIL_IF_NEUTERED(this); VALIDATE_POINTER_TO_OBJECT(ppValue, ICorDebugValue **); ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess()); HRESULT hr = S_OK; *ppValue = NULL; BOOL fEnCHangingField = FALSE; IMetaDataImport * pImport = NULL; EX_TRY { pImport = GetModule()->GetMetaDataImporter(); // throws // Validate the token. if (!pImport->IsValidToken(fieldDef) || (TypeFromToken(fieldDef) != mdtFieldDef)) { ThrowHR(E_INVALIDARG); } // Make sure we have enough info about the class. Init(); // Uninstantiated generics (eg, Foo<T>) don't have static data. Must use instantiated (eg Foo<int>) // But all CordbClass instances are uninstantiated. So this should fail for all generic types. // Normally, debuggers should be using ICorDebugType instead. // Though in the forward compat case, they'll hit this. if (HasTypeParams()) { ThrowHR(CORDBG_E_STATIC_VAR_NOT_AVAILABLE); } // Lookup the field given its metadata token. FieldData *pFieldData; hr = GetFieldInfo(fieldDef, &pFieldData); // This field was added by EnC, need to use EnC specific code path if (hr == CORDBG_E_ENC_HANGING_FIELD) { // Static fields added with EnC hang off the EnCFieldDesc hr = GetEnCHangingField(fieldDef, &pFieldData, NULL); if (SUCCEEDED(hr)) { fEnCHangingField = TRUE; } // Note: the FieldOffset in pFieldData has been cooked to produce // the correct address of the field in the syncBlock. // @todo: extend Debugger_IPCEFieldData so we don't have to cook the offset here } IfFailThrow(hr); { Instantiation emptyInst; hr = CordbClass::GetStaticFieldValue2(GetModule(), pFieldData, fEnCHangingField, &emptyInst, pFrame, ppValue); // Let hr fall through } } EX_CATCH_HRESULT(hr); // Translate Failure HRs. if (pImport != NULL) { hr = CordbClass::PostProcessUnavailableHRESULT(hr, pImport, fieldDef); } return hr; }
HRESULT CordbAppDomain::Terminate(unsigned int exitCode) { PUBLIC_API_ENTRY(this); FAIL_IF_NEUTERED(this); return E_NOTIMPL; }
HRESULT CordbAppDomain::Continue(BOOL fIsOutOfBand) { PUBLIC_API_ENTRY(this); FAIL_IF_NEUTERED(this); return m_pProcess->ContinueInternal(fIsOutOfBand); }
HRESULT CordbAppDomain::Stop(DWORD dwTimeout) { FAIL_IF_NEUTERED(this); PUBLIC_API_ENTRY(this); return (m_pProcess->StopInternal(dwTimeout, this->GetADToken())); }