HRESULT XmlDataHelpers::HandleTagAttributeList()

in Exdi/exdigdbsrv/GdbSrvControllerLib/XmlDataHelpers.cpp [735:1032]


HRESULT XmlDataHelpers::HandleTagAttributeList(_In_ TAG_ATTR_LIST* const pTagAttrList,
    _Out_ ConfigExdiGdbSrvData* pConfigTable)
{
    assert(pTagAttrList != nullptr);
    HRESULT hr = E_FAIL;

    try
    {
        bool isSet = false;

        if (IsExdiGdbTargetsDataTag(pTagAttrList->tagName))
        {
            ConfigExdiGdbTargetsDataEntry selectTarget = {};
            hr = GetXmlTagAttributeValues(pTagAttrList, attrExdiTargetsHandlerMap, 
                ARRAYSIZE(attrExdiTargetsHandlerMap),
                sizeof(selectTarget), static_cast<void*>(&selectTarget));
            if (SUCCEEDED(hr))
            {
                wcscpy_s(pConfigTable->gdbCurrentTargetName.currentTargetName,
                    C_MAX_ATTR_LENGTH, selectTarget.currentGdbTargetName);
                isSet = true;
            }
        }
        else if (IsExdiGdbTargetDataTag(pTagAttrList->tagName))
        {
            ConfigExdiGdbTargetDataEntry target = {};
            hr = GetXmlTagAttributeValues(pTagAttrList, attrExdiTargetHandlerMap, 
                ARRAYSIZE(attrExdiTargetHandlerMap),
                sizeof(target), static_cast<void*>(&target));
            if (SUCCEEDED(hr))
            {
                if (IsCurrentTarget(target.gdbTargetName, pConfigTable->gdbCurrentTargetName.currentTargetName))
                {
                    pConfigTable->gdbTargetName.isTargetSelected = true;
                    wcscpy_s(pConfigTable->gdbTargetName.targetName, C_MAX_ATTR_LENGTH, target.gdbTargetName);
                }
                else
                {
                    pConfigTable->gdbTargetName.isTargetSelected = false;
                }
                isSet = true;
            }
        }
        else if (XmlDataGdbServerRegisterFile::IsTargetDescriptionFile(pTagAttrList->tagName) ||
            XmlDataGdbServerRegisterFile::IsRegisterFileReference(pTagAttrList->tagName))
        {
            isSet = XmlDataGdbServerRegisterFile::HandleTargetFileTags(pTagAttrList, pConfigTable);
        }
        else if (XmlDataGdbServerRegisterFile::IsFeatureRegisterFile(pTagAttrList->tagName) ||
            XmlDataGdbServerRegisterFile::IsRegisterFileEntry(pTagAttrList->tagName))
        {
            isSet = XmlDataGdbServerRegisterFile::SetRegistersByTargetFile(pTagAttrList, pConfigTable);
        }
        else if (XmlDataSystemRegister::IsSystemRegisterMapElement(pTagAttrList->tagName))
        {
            isSet = XmlDataSystemRegister::HandleMapSystemRegAccessCode(pTagAttrList, pConfigTable);
        }

        if (pConfigTable->gdbTargetName.isTargetSelected)
        {
            if (IsExdiGdbServerConfigDataTag(pTagAttrList->tagName))
            {
                ConfigExdiDataEntry exdiData = {};
                hr = GetXmlTagAttributeValues(pTagAttrList, attrExdiServerHandlerMap, ARRAYSIZE(attrExdiServerHandlerMap),
                    sizeof(ConfigExdiDataEntry), static_cast<void*>(&exdiData));
                if (SUCCEEDED(hr))
                {
                    pConfigTable->component.agentNamePacket = exdiData.agentNamePacket;
                    pConfigTable->component.uuid = exdiData.uuid;
                    pConfigTable->component.fDisplayCommPackets = (_wcsicmp(exdiData.fDisplayCommPackets, L"yes") == 0) ? true : false;
                    pConfigTable->component.fDebuggerSessionByCore = (_wcsicmp(exdiData.fDebuggerSessionByCore, L"yes") == 0) ? true : false;
                    pConfigTable->component.fExceptionThrowEnabled = (_wcsicmp(exdiData.fExceptionThrowEnabled, L"yes") == 0) ? true : false;
                    pConfigTable->component.qSupportedPacket = exdiData.qSupportedPacket;
                    pConfigTable->component.fTreatSwBpAsHwBp = (_wcsicmp(exdiData.fTreatSwBpAsHwBp, L"yes") == 0) ? true : false;
                    isSet = true;
                }
            }
            else if (IsExdiGdbServerTargetDataTag(pTagAttrList->tagName))
            {
                ConfigExdiTargetDataEntry targetData = {};
                hr = GetXmlTagAttributeValues(pTagAttrList, attrNameServerTarget, ARRAYSIZE(attrNameServerTarget),
                    sizeof(ConfigExdiTargetDataEntry), static_cast<void*>(&targetData));
                if (SUCCEEDED(hr))
                {
                    pConfigTable->target.targetArchitecture = GetTargetGdbServerArchitecture(targetData.targetArchitecture);
                    pConfigTable->target.targetFamily = GetTargetGdbServerFamily(targetData.targetFamily);
                    pConfigTable->target.numberOfCores = _wtoi(targetData.numberOfCores);
                    pConfigTable->target.fEnabledIntelFpSseContext = (_wcsicmp(targetData.fEnabledIntelFpSseContext, L"yes") == 0) ? true : false;
                    if (swscanf_s(targetData.heuristicChunkSize, L"%I64x", &pConfigTable->target.heuristicChunkSize) != 1)
                    {
                        throw _com_error(E_INVALIDARG);
                    }
                    pConfigTable->target.targetDescriptionFileName = targetData.targetDescriptionFileName;
                    isSet = true;
                }
            }
            else if (IsGdbServerConnectionParametersTag(pTagAttrList->tagName))
            {
                ConfigGdbServerDataEntry gdbServer = {};
                hr = GetXmlTagAttributeValues(pTagAttrList, attrExdiServerConnection, ARRAYSIZE(attrExdiServerConnection),
                    sizeof(ConfigGdbServerDataEntry), static_cast<void*>(&gdbServer));
                if (SUCCEEDED(hr))
                {
                    pConfigTable->gdbServer.fMultiCoreGdbServer = (_wcsicmp(gdbServer.fMultiCoreGdbServer, L"yes") == 0) ? true : false;
                    pConfigTable->gdbServer.maxServerPacketLength = _wtoi(gdbServer.maxServerPacketLength);
                    pConfigTable->gdbServer.maxConnectAttempts = _wtoi(gdbServer.maxConnectAttempts);
                    pConfigTable->gdbServer.sendTimeout = _wtoi(gdbServer.sendTimeout);
                    pConfigTable->gdbServer.receiveTimeout = _wtoi(gdbServer.receiveTimeout);
                    isSet = true;
                }
            }
            else if (IsGdbServerValueTag(pTagAttrList->tagName))
            {
                assert(pConfigTable->gdbServer.coreConnectionParameters.size() <= pConfigTable->target.numberOfCores);
                ConfigGdbServerDataEntry gdbServer = {};
                hr = GetXmlTagAttributeValues(pTagAttrList, attrExdiServerConnection, ARRAYSIZE(attrExdiServerConnection),
                    sizeof(gdbServer), static_cast<void*>(&gdbServer));
                if (SUCCEEDED(hr))
                {
                    pConfigTable->gdbServer.coreConnectionParameters.push_back(gdbServer.coreConnectionParameter);
                    isSet = true;
                }
            }
            else if (IsGdbServerMemoryCommands(pTagAttrList->tagName))
            {
                ConfigExdiGdbServerMemoryCommandsEntry gdbMemoryCmds = {};
                hr = GetXmlTagAttributeValues(pTagAttrList, attrExdiGdbServerMemoryCommands, ARRAYSIZE(attrExdiGdbServerMemoryCommands),
                    sizeof(ConfigExdiGdbServerMemoryCommandsEntry), static_cast<void*>(&gdbMemoryCmds));
                if (SUCCEEDED(hr))
                {
                    pConfigTable->gdbMemoryCommands.fGdbSpecialMemoryCommand = (_wcsicmp(gdbMemoryCmds.fGdbSpecialMemoryCommand, L"yes") == 0) ? true : false;
                    pConfigTable->gdbMemoryCommands.fGdbPhysicalMemoryCommand = (_wcsicmp(gdbMemoryCmds.fGdbPhysicalMemoryCommand, L"yes") == 0) ? true : false;
                    pConfigTable->gdbMemoryCommands.fGdbSupervisorMemoryCommand = (_wcsicmp(gdbMemoryCmds.fGdbSupervisorMemoryCommand, L"yes") == 0) ? true : false;
                    pConfigTable->gdbMemoryCommands.fGdbHypervisorMemoryCommand = (_wcsicmp(gdbMemoryCmds.fGdbHypervisorMemoryCommand, L"yes") == 0) ? true : false;
                    pConfigTable->gdbMemoryCommands.fGdbSpecialMemoryRegister = (_wcsicmp(gdbMemoryCmds.fGdbSpecialMemoryRegister, L"yes") == 0) ? true : false;
                    pConfigTable->gdbMemoryCommands.fGdbSystemRegistersGdbMonitor = (_wcsicmp(gdbMemoryCmds.fGdbSystemRegistersGdbMonitor, L"yes") == 0) ? true : false;
                    pConfigTable->gdbMemoryCommands.fGdbSystemRegisterDecoding = (_wcsicmp(gdbMemoryCmds.fGdbSystemRegisterDecoding, L"yes") == 0) ? true : false;
                    isSet = true;
                }
            }
            else if (IsGdbServerRegistersTag(pTagAttrList->tagName))
            {
                ConfigExdiGdServerRegistersEntry registerExdiGdbData = {};
                hr = GetXmlTagAttributeValues(pTagAttrList, attrGdbServerRegisters, ARRAYSIZE(attrGdbServerRegisters),
                    sizeof(ConfigExdiGdServerRegistersEntry), static_cast<void*>(&registerExdiGdbData));
                if (SUCCEEDED(hr))
                {
                    pConfigTable->gdbServerRegisters.registerSet.push_back(move(GetTargetGdbServerArchitecture(registerExdiGdbData.RegisterArchitecture)));
                    if (pConfigTable->gdbServerRegisters.featureNameSupported == nullptr)
                    {
                        pConfigTable->gdbServerRegisters.featureNameSupported.reset(new(std::nothrow) GdbServerRegFeatureSupportedMap());
                        if (pConfigTable->gdbServerRegisters.featureNameSupported == nullptr)
                        {
                            throw _com_error(E_OUTOFMEMORY);
                        }

                    }
                    pConfigTable->gdbServerRegisters.featureNameSupported->emplace(
                        pConfigTable->gdbServerRegisters.registerSet.back(),
                        new(std::nothrow) wstring(registerExdiGdbData.FeatureNameSupported));

                    if (pConfigTable->gdbServerRegisters.spRegisterCoreSet.get() == nullptr)
                    {
                        pConfigTable->gdbServerRegisters.spRegisterCoreSet.reset(new(std::nothrow) GdbServerRegisterMap());
                        if (pConfigTable->gdbServerRegisters.spRegisterCoreSet == nullptr)
                        {
                            throw _com_error(E_OUTOFMEMORY);
                        }
                    }
                    pConfigTable->gdbServerRegisters.spRegisterCoreSet->emplace(
                        pConfigTable->gdbServerRegisters.registerSet.back(),
                        new(std::nothrow) RegisterVector());

                    //  Are system registers available via Core registers?
                    if (registerExdiGdbData.SystemRegistersStart != nullptr &&
                        registerExdiGdbData.SystemRegistersEnd != nullptr &&
                        registerExdiGdbData.SystemRegistersStart[0] != '\x0' &&
                        registerExdiGdbData.SystemRegistersEnd[0] != '\x0')
                    {
                        if (pConfigTable->gdbServerRegisters.spRegisterSystemSet.get() == nullptr)
                        {
                            pConfigTable->gdbServerRegisters.spRegisterSystemSet.reset(new(std::nothrow) GdbServerRegisterMap());
                            if (pConfigTable->gdbServerRegisters.spRegisterSystemSet == nullptr)
                            {
                                throw _com_error(E_OUTOFMEMORY);
                            }
                            pConfigTable->gdbServerRegisters.spRegisterSystemSet->emplace(
                                pConfigTable->gdbServerRegisters.registerSet.back(),
                                new(std::nothrow) RegisterVector());

                            m_spSystemRegsRange.reset(new(std::nothrow) vector<size_t>());
                            if (m_spSystemRegsRange == nullptr)
                            {
                                throw _com_error(E_OUTOFMEMORY);
                            }
                            size_t rangeStart;
                            if (swscanf_s(registerExdiGdbData.SystemRegistersStart, L"%zx", &rangeStart) != 1)
                            {
                                throw _com_error(E_INVALIDARG);
                            }
                            size_t rangeEnd;
                            if (swscanf_s(registerExdiGdbData.SystemRegistersEnd, L"%zx", &rangeEnd) != 1)
                            {
                                throw _com_error(E_INVALIDARG);
                            }
                            m_spSystemRegsRange->push_back(rangeStart);
                            m_spSystemRegsRange->push_back(rangeEnd);
                        }
                    }
                    isSet = true;
                }
            }
            else if (IsGdbRegisterEntryTag(pTagAttrList->tagName))
            {
                ConfigExdiGdServerRegistersEntry registerData = {};
                hr = GetXmlTagAttributeValues(pTagAttrList, attrGdbServerRegisters, ARRAYSIZE(attrGdbServerRegisters),
                    sizeof(ConfigExdiGdServerRegistersEntry), static_cast<void*>(&registerData));
                if (SUCCEEDED(hr))
                {
                    char nameBuf[128] = {};
                    if (WideCharToMultiByte(CP_ACP, 0, registerData.RegisterName, static_cast<int>(wcslen(registerData.RegisterName)),
                        nameBuf, sizeof(nameBuf), nullptr, nullptr) == 0)
                    {
                        throw _com_error(E_INVALIDARG);
                    }

                    char nameOrderBuf[128] = {};
                    if (WideCharToMultiByte(CP_ACP, 0, registerData.RegisterOrder, static_cast<int>(wcslen(registerData.RegisterOrder)),
                        nameOrderBuf, sizeof(nameOrderBuf), nullptr, nullptr) == 0)
                    {
                        throw _com_error(E_INVALIDARG);
                    }

                    RegistersStruct registerSet = {};
                    registerSet.name = nameBuf;
                    registerSet.nameOrder = nameOrderBuf;
                    registerSet.registerSize = static_cast<size_t>(_wtoi(registerData.RegisterSize));
                    registerSet.group = "core";
                    auto it = pConfigTable->gdbServerRegisters.spRegisterCoreSet->find(pConfigTable->gdbServerRegisters.registerSet.back());
                    if (it == pConfigTable->gdbServerRegisters.spRegisterCoreSet->end())
                    {
                        throw _com_error(E_INVALIDARG);
                    }
                    it->second->push_back(move(registerSet));

                    //  check if there is a core register that needs to be reported as
                    //  system register
                    if (pConfigTable->gdbServerRegisters.spRegisterSystemSet != nullptr &&
                        m_spSystemRegsRange != nullptr)
                    {
                        auto itSystem = pConfigTable->gdbServerRegisters.spRegisterSystemSet->find(pConfigTable->gdbServerRegisters.registerSet.back());
                        if (itSystem != pConfigTable->gdbServerRegisters.spRegisterSystemSet->end())
                        {
                            size_t coreRegister;
                            if (swscanf_s(registerData.RegisterOrder, L"%zx", &coreRegister) != 1)
                            {
                                throw _com_error(E_INVALIDARG);
                            }

                            size_t rangeLow = (*m_spSystemRegsRange.get())[0];
                            size_t rangeHigh = (*m_spSystemRegsRange.get())[1];
                            if (rangeLow <= coreRegister && coreRegister <= rangeHigh)
                            {
                                RegistersStruct systemRegisterSet = {};
                                systemRegisterSet.name = nameBuf;
                                systemRegisterSet.nameOrder = nameOrderBuf;
                                systemRegisterSet.registerSize = static_cast<size_t>(_wtoi(registerData.RegisterSize));
                                systemRegisterSet.group = "system";
                                itSystem->second->push_back(move(systemRegisterSet));
                            }
                        }
                    }
                    isSet = true;
                }
            }
        }
        else
        {
            isSet = true;
            hr = S_OK;
        }

        if (!isSet)
        {
            ReportXmlError(L"Failed setting a value in ConfigExdiGdbServerHelperImpl::HandleTagAttributeList()\n");
            hr = E_FAIL;
        }
    }
    catch (exception& ex)
    {
        ReportExceptionError(ex.what());
    }
    catch (...)
    {
        ReportXmlError(L"Unrecognized exception happened in ConfigExdiGdbServerHelperImpl::ProcessAttributeList()\n");
    }
    return hr;
}