File indexing completed on 2024-05-12 04:39:44

0001 /*
0002     SPDX-FileCopyrightText: 2013 Vlas Puhov <vlas.puhov@mail.ru>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "registersmanager.h"
0008 
0009 #include "registercontroller_arm.h"
0010 #include "registercontroller_x86.h"
0011 #include "registersview.h"
0012 
0013 #include "dbgglobal.h"
0014 #include "debuglog.h"
0015 #include "midebugsession.h"
0016 #include "mi/micommand.h"
0017 #include "modelsmanager.h"
0018 
0019 using namespace KDevMI::MI;
0020 using namespace KDevMI;
0021 
0022 void ArchitectureParser::parseArchitecture()
0023 {
0024     Architecture arch = other;
0025 
0026     for (const QString& reg : qAsConst(m_registerNames)) {
0027         if (reg == QLatin1String("rax")) {
0028             arch = x86_64;
0029             break;
0030         } else if (reg == QLatin1String("r0")) {
0031             arch = arm;
0032             break;
0033         } else if (reg == QLatin1String("eax")) {
0034             arch = x86;
0035             //we don't break because x86_64 contains eax too.
0036         }
0037     }
0038 
0039     emit architectureParsed(arch);
0040 }
0041 
0042 void ArchitectureParser::registerNamesHandler(const ResultRecord& r)
0043 {
0044     const Value& names = r[QStringLiteral("register-names")];
0045 
0046     m_registerNames.clear();
0047     for (int i = 0; i < names.size(); ++i) {
0048         const Value& entry = names[i];
0049         if (!entry.literal().isEmpty()) {
0050             m_registerNames << entry.literal();
0051         }
0052     }
0053 
0054     parseArchitecture();
0055 }
0056 
0057 void ArchitectureParser::determineArchitecture(MIDebugSession* debugSession)
0058 {
0059     if (!debugSession || debugSession->debuggerStateIsOn(s_dbgNotStarted | s_shuttingDown)) {
0060         return;
0061     }
0062 
0063     debugSession->addCommand(DataListRegisterNames, QString(), this, &ArchitectureParser::registerNamesHandler);
0064 }
0065 
0066 RegistersManager::RegistersManager(QWidget* parent)
0067 : QObject(parent), m_registersView(new RegistersView(parent)), m_registerController(nullptr), m_architectureParser(new ArchitectureParser(this)), m_debugSession(nullptr), m_modelsManager(new ModelsManager(this)), m_currentArchitecture(undefined), m_needToCheckArch(false)
0068 {
0069     connect(m_architectureParser, &ArchitectureParser::architectureParsed, this, &RegistersManager::architectureParsedSlot);
0070 
0071     m_registersView->setModel(m_modelsManager);
0072     setController(nullptr);
0073 }
0074 
0075 void RegistersManager::architectureParsedSlot(Architecture arch)
0076 {
0077     qCDebug(DEBUGGERCOMMON) << " Current controller: " << m_registerController << "Current arch " << m_currentArchitecture;
0078 
0079     if (m_registerController || m_currentArchitecture != undefined) {
0080         return;
0081     }
0082 
0083     switch (arch) {
0084     case x86:
0085         m_registerController.reset(new RegisterController_x86(m_debugSession)) ;
0086         qCDebug(DEBUGGERCOMMON) << "Found x86 architecture";
0087         break;
0088     case x86_64:
0089         m_registerController.reset(new RegisterController_x86_64(m_debugSession));
0090         qCDebug(DEBUGGERCOMMON) << "Found x86_64 architecture";
0091         break;
0092     case arm:
0093         m_registerController.reset(new RegisterController_Arm(m_debugSession));
0094         qCDebug(DEBUGGERCOMMON) << "Found Arm architecture";
0095         break;
0096     default:
0097         m_registerController.reset();
0098         qCWarning(DEBUGGERCOMMON) << "Unsupported architecture. Registers won't be available.";
0099         break;
0100     }
0101 
0102     m_currentArchitecture = arch;
0103 
0104     setController(m_registerController.data());
0105 
0106     if (m_registerController) {
0107         updateRegisters();
0108     }
0109 }
0110 
0111 void RegistersManager::setSession(MIDebugSession* debugSession)
0112 {
0113     qCDebug(DEBUGGERCOMMON) << "Change session " << debugSession;
0114     m_debugSession = debugSession;
0115     if (m_registerController) {
0116         m_registerController->setSession(debugSession);
0117     }
0118     if (!m_debugSession) {
0119         qCDebug(DEBUGGERCOMMON) << "Will reparse arch";
0120         m_needToCheckArch = true;
0121         setController(nullptr);
0122     }
0123 }
0124 
0125 void RegistersManager::updateRegisters()
0126 {
0127     if (!m_debugSession || m_debugSession->debuggerStateIsOn(s_dbgNotStarted | s_shuttingDown)) {
0128         return;
0129     }
0130 
0131     qCDebug(DEBUGGERCOMMON) << "Updating registers";
0132     if (m_needToCheckArch) {
0133         m_needToCheckArch = false;
0134         m_currentArchitecture = undefined;
0135         setController(nullptr);
0136     }
0137     if (m_currentArchitecture == undefined) {
0138         m_architectureParser->determineArchitecture(m_debugSession);
0139     }
0140 
0141     if (m_registerController) {
0142         m_registersView->updateRegisters();
0143     } else {
0144         qCDebug(DEBUGGERCOMMON) << "No registerController, yet?";
0145     }
0146 }
0147 
0148 ArchitectureParser::ArchitectureParser(QObject* parent)
0149 : QObject(parent) {}
0150 
0151 void RegistersManager::setController(IRegisterController* c)
0152 {
0153     m_registerController.reset(c);
0154     m_modelsManager->setController(c);
0155 
0156     m_registersView->enable(c ? true : false);
0157 }
0158 
0159 #include "moc_registersmanager.cpp"