bool XmlDataSystemRegister::HandleMapSystemRegAccessCode()

in Exdi/exdigdbsrv/GdbSrvControllerLib/XmlDataHelpers.cpp [1315:1438]


bool XmlDataSystemRegister::HandleMapSystemRegAccessCode(_In_ TAG_ATTR_LIST* const pTagAttrList,
    _Inout_ ConfigExdiGdbSrvData * pConfigTable)
{
    HRESULT hr;
    bool isDone = false;

    ConfigSystemRegMapAccessCodeEntry systemRegMapData = { 0 };
    if (IsSystemRegistersTag(pTagAttrList->tagName))
    {
        hr = XmlDataHelpers::GetXmlTagAttributeValues(pTagAttrList, attrMapSystemRegisterAccessCode, ARRAYSIZE(attrMapSystemRegisterAccessCode),
            sizeof(ConfigSystemRegMapAccessCodeEntry), static_cast<void*>(&systemRegMapData));
        if (SUCCEEDED(hr))
        {
            TargetArchitecture arch = XmlDataHelpers::GetTargetGdbServerArchitecture(systemRegMapData.RegisterArchitecture);
            //  Process only map for architecture with the system registers have been created
            if (pConfigTable->gdbServerRegisters.spRegisterSystemSet == nullptr ||
                pConfigTable->gdbServerRegisters.spRegisterSystemSet->empty())
            {
                return isDone;
            }

            auto itVector = pConfigTable->gdbServerRegisters.spRegisterSystemSet->find(arch);
            if (itVector == pConfigTable->gdbServerRegisters.spRegisterSystemSet->end())
            {
                //  This is not the architecture of the current built system register map.
                return true;
            }

            pConfigTable->systemRegisterMap.systemRegArchitecture.push_back(arch);

            if (pConfigTable->systemRegisterMap.spSysRegisterMap.get() == nullptr)
            {
                pConfigTable->systemRegisterMap.spSysRegisterMap.reset(new(std::nothrow) SystemRegCodeMap());
                if (pConfigTable->systemRegisterMap.spSysRegisterMap == nullptr)
                {
                    throw _com_error(E_OUTOFMEMORY);
                }
                pConfigTable->systemRegisterMap.spSysRegisterMap->emplace(
                    pConfigTable->systemRegisterMap.systemRegArchitecture.back(),
                    new(std::nothrow) SystemRegistersMapType());
            }
            isDone = true;
        }
    }
    else if (IsSystemRegisterEntryTag(pTagAttrList->tagName))
    {
        hr = XmlDataHelpers::GetXmlTagAttributeValues(pTagAttrList, attrMapSystemRegisterAccessCode, ARRAYSIZE(attrMapSystemRegisterAccessCode),
            sizeof(ConfigSystemRegMapAccessCodeEntry), static_cast<void*>(&systemRegMapData));
        if (SUCCEEDED(hr))
        {
            if (pConfigTable->systemRegisterMap.spSysRegisterMap.get() == nullptr ||
                pConfigTable->systemRegisterMap.systemRegArchitecture.empty())
            {
                //  Ignore since the map has not been created for the current architecture
                return true;
            }

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

            std::vector<int> accessCodeVector;
            TargetArchitectureHelpers::TokenizeAccessCodeByArch(
                pConfigTable->systemRegisterMap.systemRegArchitecture.back(),
                systemRegMapData.AccessCode,
                L",", &accessCodeVector);
            if (accessCodeVector.size() != c_numberOfAccessCodeFields)
            {
                throw _com_error(E_INVALIDARG);
            }

            //  Encode accesscode 
            AddressType encodedValue = TargetArchitectureHelpers::EncodeAccessCode(
                pConfigTable->systemRegisterMap.systemRegArchitecture.back(),
                accessCodeVector[0],
                accessCodeVector[1],
                accessCodeVector[2],
                accessCodeVector[3],
                accessCodeVector[4]);
            if (encodedValue == c_InvalidAddress)
            {
                throw _com_error(E_INVALIDARG);
            }

            //  Generate the map entry pair taking into account the Register order as well
            SystemPairRegOrderNameType regNameOrder = {};
            regNameOrder.second = string(nameBuf);
            auto itVector = pConfigTable->gdbServerRegisters.spRegisterSystemSet->find(pConfigTable->systemRegisterMap.systemRegArchitecture.back());
            if (itVector == pConfigTable->gdbServerRegisters.spRegisterSystemSet->end())
            {
                throw _com_error(E_INVALIDARG);
            }

            auto itMap = pConfigTable->systemRegisterMap.spSysRegisterMap->find(pConfigTable->systemRegisterMap.systemRegArchitecture.back());
            if (itMap == pConfigTable->systemRegisterMap.spSysRegisterMap->end())
            {
                throw _com_error(E_INVALIDARG);
            }

            for (auto it = itVector->second->cbegin();
                 it != itVector->second->cend(); ++it)
            {
                if (it->name == regNameOrder.second &&
                    !IsRegisterPresent(it->nameOrder, itMap->second))
                {
                    regNameOrder.first = string(it->nameOrder);
                    break;
                }
            }

            if (regNameOrder.first.empty())
            {
                regNameOrder.first = string("n/a");
            }
            itMap->second->insert({(encodedValue & 0xffffffff), move(regNameOrder)});
            isDone = true;
        }
    }
    return isDone;
}