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"