HRESULT STDMETHODCALLTYPE CLiveExdiGdbSrvServer::GetContextEx()

in Exdi/exdigdbsrv/ExdiGdbSrv/LiveExdiGdbSrvServer.cpp [1146:1256]


HRESULT STDMETHODCALLTYPE CLiveExdiGdbSrvServer::GetContextEx(_In_ DWORD processorNumber, _Inout_ PCONTEXT_X86_64 pContext)
{
    if (pContext == nullptr)
    {
        return E_POINTER;
    }

    try
    {
        AsynchronousGdbSrvController * pController = GetGdbSrvController();
        if (pController == nullptr)
        {
            return E_POINTER;
        }
        pController->StopTargetAtRun();
        memset(pContext, 0, sizeof(CONTEXT_X86_64));

        //We do not fetch the actual descriptors, thus we mark them as invalid
        pContext->DescriptorCs.SegFlags = static_cast<DWORD>(-1);
        pContext->DescriptorSs.SegFlags = static_cast<DWORD>(-1);
        pContext->DescriptorGs.SegFlags = static_cast<DWORD>(-1);
        pContext->DescriptorFs.SegFlags = static_cast<DWORD>(-1);
        pContext->DescriptorEs.SegFlags = static_cast<DWORD>(-1);
        pContext->DescriptorDs.SegFlags = static_cast<DWORD>(-1);

        std::map<std::string, std::string> registers = pController->QueryAllRegisters(processorNumber);
        pContext->Rax = GdbSrvController::ParseRegisterValue(registers["rax"]);
        pContext->Rbx = GdbSrvController::ParseRegisterValue(registers["rbx"]);
        pContext->Rcx = GdbSrvController::ParseRegisterValue(registers["rcx"]);
        pContext->Rdx = GdbSrvController::ParseRegisterValue(registers["rdx"]);
        pContext->Rsi = GdbSrvController::ParseRegisterValue(registers["rsi"]);
        pContext->Rdi = GdbSrvController::ParseRegisterValue(registers["rdi"]);
        pContext->Rip = GdbSrvController::ParseRegisterValue(registers["rip"]);
        // Store the last 'pc' value in order to notify the engine with the last obtained 'pc' value, 
        // This is required for cases when the GdbServer responds with target unvailable packet.
        m_lastPcAddress = pContext->Rip;
        pContext->Rsp = GdbSrvController::ParseRegisterValue(registers["rsp"]);
        pContext->Rbp = GdbSrvController::ParseRegisterValue(registers["rbp"]);
        pContext->R8  = GdbSrvController::ParseRegisterValue(registers["r8"]);
        pContext->R9  = GdbSrvController::ParseRegisterValue(registers["r9"]);
        pContext->R10 = GdbSrvController::ParseRegisterValue(registers["r10"]);
        pContext->R11 = GdbSrvController::ParseRegisterValue(registers["r11"]);
        pContext->R12 = GdbSrvController::ParseRegisterValue(registers["r12"]);
        pContext->R13 = GdbSrvController::ParseRegisterValue(registers["r13"]);
        pContext->R14 = GdbSrvController::ParseRegisterValue(registers["r14"]);
        pContext->R15 = GdbSrvController::ParseRegisterValue(registers["r15"]);
        pContext->EFlags = GdbSrvController::ParseRegisterValue32(registers["eflags"]);
        pContext->RegGroupSelection.fIntegerRegs = TRUE;

        pContext->ModeFlags = AMD64_CONTEXT_AMD64 | AMD64_CONTEXT_CONTROL | 
                              AMD64_CONTEXT_INTEGER | AMD64_CONTEXT_SEGMENTS;

        //  Segment registers
        pContext->SegCs = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["cs"]));
        pContext->SegSs = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["ss"]));
        pContext->SegDs = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["ds"]));
        pContext->SegEs = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["es"]));
        pContext->SegFs = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["fs"]));
        pContext->SegGs = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["gs"]));
        pContext->RegGroupSelection.fSegmentRegs = TRUE;

        //   Control registers (System registers)
        pContext->RegCr0 = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["cr0"]));
        pContext->RegCr2 = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["cr2"]));
        pContext->RegCr3 = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["cr3"]));
        pContext->RegCr4 = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["cr4"]));
        pContext->RegCr8 = static_cast<DWORD>(GdbSrvController::ParseRegisterValue(registers["cr8"]));
        pContext->RegGroupSelection.fSystemRegisters = TRUE;

        //  get all floating point registers (FPU)
        pContext->ControlWord = static_cast<DWORD>(GdbSrvController::ParseRegisterValue32(registers["fctrl"]));
        pContext->StatusWord = static_cast<DWORD>(GdbSrvController::ParseRegisterValue32(registers["fstat"]));
        pContext->TagWord = static_cast<DWORD>(GdbSrvController::ParseRegisterValue32(registers["ftag"]));
        pContext->ErrorOffset = static_cast<DWORD>(GdbSrvController::ParseRegisterValue32(registers["fioff"]));
        pContext->ErrorSelector = static_cast<DWORD>(GdbSrvController::ParseRegisterValue32(registers["fiseg"]));
        pContext->DataOffset = static_cast<DWORD>(GdbSrvController::ParseRegisterValue32(registers["fooff"]));
        pContext->DataSelector = static_cast<DWORD>(GdbSrvController::ParseRegisterValue32(registers["foseg"]));

        //  x87 registers (FPU)
        for (int index = 0; index < s_numberFPRegList; ++index)
        {
            std::string regName(s_fpRegList[index]);
            GdbSrvController::ParseRegisterVariableSize(registers[regName],
                reinterpret_cast<BYTE*>(&pContext->RegisterArea[index * s_numberOfBytesCoprocessorRegister]),
                s_numberOfBytesCoprocessorRegister);
        }
        pContext->RegGroupSelection.fFloatingPointRegs = TRUE;

        //  Get X64 SSE registers if the x64 SSE context enabled?
        if (m_fEnableSSEContext)
        {
            registers = pController->QueryRegisters(processorNumber, s_sseX64RegList, s_numberOfSseX64Registers);
            const int numberOfBytesSseX64Registers = sizeof(pContext->RegSSE[0]);
            for (int index = 0; index < s_numberOfSseX64Registers; ++index)
            {
                std::string regName(s_sseX64RegList[index]);
                GdbSrvController::ParseRegisterVariableSize(registers[regName],
                    reinterpret_cast<BYTE*>(&pContext->RegSSE[index]),
                    numberOfBytesSseX64Registers);
            }
            pContext->RegMXCSR = static_cast<DWORD>(GdbSrvController::ParseRegisterValue32(registers["mxcsr"]));
            pContext->RegGroupSelection.fSSERegisters = TRUE;
        }

        pContext->RegGroupSelection.fSegmentDescriptors = FALSE;
        pContext->RegGroupSelection.fDebugRegs = FALSE;

        return S_OK;
    }
    CATCH_AND_RETURN_HRESULT;
}