void MemoryViewWidget::ToggleRowBreakpoint(bool row) { TMemCheck check; const u32 addr = row ? GetContextAddress() & 0xFFFFFFF0 : GetContextAddress(); const auto length = row ? 16 : (16 / GetColumnCount(m_type)); if (!PowerPC::memchecks.OverlapsMemcheck(addr, length)) { check.start_address = addr; check.end_address = check.start_address + length - 1; check.is_ranged = length > 0; check.is_break_on_read = (m_bp_type == BPType::ReadOnly || m_bp_type == BPType::ReadWrite); check.is_break_on_write = (m_bp_type == BPType::WriteOnly || m_bp_type == BPType::ReadWrite); check.log_on_hit = m_do_log; check.break_on_hit = true; PowerPC::memchecks.Add(check); } else { PowerPC::memchecks.Remove(addr); } emit BreakpointsChanged(); Update(); }
void CodeViewWidget::ToggleBreakpoint() { if (PowerPC::debug_interface.IsBreakpoint(GetContextAddress())) PowerPC::breakpoints.Remove(GetContextAddress()); else PowerPC::breakpoints.Add(GetContextAddress()); emit BreakpointsChanged(); Update(); }
void CodeViewWidget::OnReplaceInstruction() { const u32 addr = GetContextAddress(); if (!PowerPC::HostIsInstructionRAMAddress(addr)) return; const PowerPC::TryReadInstResult read_result = PowerPC::TryReadInstruction(addr); if (!read_result.valid) return; bool good; QString name = QInputDialog::getText( this, tr("Change instruction"), tr("New instruction:"), QLineEdit::Normal, QStringLiteral("%1").arg(read_result.hex, 8, 16, QLatin1Char('0')), &good); u32 code = name.toUInt(&good, 16); if (good) { PowerPC::debug_interface.UnsetPatch(addr); PowerPC::debug_interface.SetPatch(addr, code); Update(); } }
void CodeViewWidget::AddBreakpoint() { PowerPC::breakpoints.Add(GetContextAddress()); emit BreakpointsChanged(); Update(); }
void CodeViewWidget::OnCopyCode() { const u32 addr = GetContextAddress(); QApplication::clipboard()->setText( QString::fromStdString(PowerPC::debug_interface.Disassemble(addr))); }
void CodeViewWidget::OnRestoreInstruction() { const u32 addr = GetContextAddress(); PowerPC::debug_interface.UnsetPatch(addr); Update(); }
void CodeViewWidget::OnAddFunction() { const u32 addr = GetContextAddress(); g_symbolDB.AddFunction(addr); emit SymbolsChanged(); Update(); }
void CodeViewWidget::OnRunToHere() { const u32 addr = GetContextAddress(); PowerPC::debug_interface.SetBreakpoint(addr); PowerPC::debug_interface.RunToBreakpoint(); Update(); }
void CodeViewWidget::OnCopyHex() { const u32 addr = GetContextAddress(); const u32 instruction = PowerPC::debug_interface.ReadInstruction(addr); QApplication::clipboard()->setText( QStringLiteral("%1").arg(instruction, 8, 16, QLatin1Char('0'))); }
void CodeViewWidget::OnContextMenu() { QMenu* menu = new QMenu(this); bool running = Core::GetState() != Core::State::Uninitialized; const u32 addr = GetContextAddress(); bool has_symbol = g_symbolDB.GetSymbolFromAddr(addr); auto* follow_branch_action = menu->addAction(tr("Follow &branch"), this, &CodeViewWidget::OnFollowBranch); menu->addSeparator(); menu->addAction(tr("&Copy address"), this, &CodeViewWidget::OnCopyAddress); auto* copy_address_action = menu->addAction(tr("Copy &function"), this, &CodeViewWidget::OnCopyFunction); auto* copy_line_action = menu->addAction(tr("Copy code &line"), this, &CodeViewWidget::OnCopyCode); auto* copy_hex_action = menu->addAction(tr("Copy &hex"), this, &CodeViewWidget::OnCopyHex); menu->addSeparator(); auto* symbol_rename_action = menu->addAction(tr("&Rename symbol"), this, &CodeViewWidget::OnRenameSymbol); auto* symbol_size_action = menu->addAction(tr("Set symbol &size"), this, &CodeViewWidget::OnSetSymbolSize); auto* symbol_end_action = menu->addAction(tr("Set symbol &end address"), this, &CodeViewWidget::OnSetSymbolEndAddress); menu->addSeparator(); menu->addAction(tr("Run &To Here"), this, &CodeViewWidget::OnRunToHere); auto* function_action = menu->addAction(tr("&Add function"), this, &CodeViewWidget::OnAddFunction); auto* ppc_action = menu->addAction(tr("PPC vs Host"), this, &CodeViewWidget::OnPPCComparison); auto* insert_blr_action = menu->addAction(tr("&Insert blr"), this, &CodeViewWidget::OnInsertBLR); auto* insert_nop_action = menu->addAction(tr("Insert &nop"), this, &CodeViewWidget::OnInsertNOP); auto* replace_action = menu->addAction(tr("Re&place instruction"), this, &CodeViewWidget::OnReplaceInstruction); auto* restore_action = menu->addAction(tr("Restore instruction"), this, &CodeViewWidget::OnRestoreInstruction); follow_branch_action->setEnabled(running && GetBranchFromAddress(addr)); for (auto* action : {copy_address_action, copy_line_action, copy_hex_action, function_action, ppc_action, insert_blr_action, insert_nop_action, replace_action}) action->setEnabled(running); for (auto* action : {symbol_rename_action, symbol_size_action, symbol_end_action}) action->setEnabled(has_symbol); restore_action->setEnabled(running && PowerPC::debug_interface.HasEnabledPatch(addr)); menu->exec(QCursor::pos()); Update(); }
void CodeViewWidget::OnFollowBranch() { const u32 addr = GetContextAddress(); u32 branch_addr = GetBranchFromAddress(addr); if (!branch_addr) return; SetAddress(branch_addr, SetAddressUpdate::WithUpdate); }
void MemoryViewWidget::OnCopyHex() { u32 addr = GetContextAddress(); const auto length = 16 / GetColumnCount(m_type); u64 value = PowerPC::HostRead_U64(addr); QApplication::clipboard()->setText( QStringLiteral("%1").arg(value, length * 2, 16, QLatin1Char('0')).left(length * 2)); }
void MemoryViewWidget::OnContextMenu() { auto* menu = new QMenu(this); menu->addAction(tr("Copy Address"), this, &MemoryViewWidget::OnCopyAddress); auto* copy_hex = menu->addAction(tr("Copy Hex"), this, &MemoryViewWidget::OnCopyHex); copy_hex->setEnabled(Core::GetState() != Core::State::Uninitialized && PowerPC::HostIsRAMAddress(GetContextAddress())); menu->addSeparator(); menu->addAction(tr("Show in code"), this, [this] { emit ShowCode(GetContextAddress()); }); menu->addSeparator(); menu->addAction(tr("Toggle Breakpoint"), this, &MemoryViewWidget::ToggleBreakpoint); menu->exec(QCursor::pos()); }
void CodeViewWidget::OnCopyFunction() { const u32 address = GetContextAddress(); const Common::Symbol* symbol = g_symbolDB.GetSymbolFromAddr(address); if (!symbol) return; std::string text = symbol->name + "\r\n"; // we got a function const u32 start = symbol->address; const u32 end = start + symbol->size; for (u32 addr = start; addr != end; addr += 4) { const std::string disasm = PowerPC::debug_interface.Disassemble(addr); text += StringFromFormat("%08x: ", addr) + disasm + "\r\n"; } QApplication::clipboard()->setText(QString::fromStdString(text)); }
void CodeViewWidget::OnRenameSymbol() { const u32 addr = GetContextAddress(); Common::Symbol* symbol = g_symbolDB.GetSymbolFromAddr(addr); if (!symbol) return; bool good; QString name = QInputDialog::getText(this, tr("Rename symbol"), tr("Symbol name:"), QLineEdit::Normal, QString::fromStdString(symbol->name), &good); if (good && !name.isEmpty()) { symbol->Rename(name.toStdString()); emit SymbolsChanged(); Update(); } }
void CodeViewWidget::OnSetSymbolSize() { const u32 addr = GetContextAddress(); Common::Symbol* symbol = g_symbolDB.GetSymbolFromAddr(addr); if (!symbol) return; bool good; int size = QInputDialog::getInt(this, tr("Rename symbol"), tr("Set symbol size (%1):").arg(QString::fromStdString(symbol->name)), symbol->size, 1, 0xFFFF, 1, &good); if (!good) return; PPCAnalyst::ReanalyzeFunction(symbol->address, *symbol, size); emit SymbolsChanged(); Update(); }
void CodeViewWidget::OnSetSymbolEndAddress() { const u32 addr = GetContextAddress(); Common::Symbol* symbol = g_symbolDB.GetSymbolFromAddr(addr); if (!symbol) return; bool good; QString name = QInputDialog::getText( this, tr("Set symbol end address"), tr("Symbol (%1) end address:").arg(QString::fromStdString(symbol->name)), QLineEdit::Normal, QStringLiteral("%1").arg(addr + symbol->size, 8, 16, QLatin1Char('0')), &good); u32 address = name.toUInt(&good, 16); if (!good) return; PPCAnalyst::ReanalyzeFunction(symbol->address, *symbol, address - symbol->address); emit SymbolsChanged(); Update(); }
void CodeViewWidget::OnInsertBLR() { const u32 addr = GetContextAddress(); ReplaceAddress(addr, 0); }
void CodeViewWidget::OnPPCComparison() { const u32 addr = GetContextAddress(); emit RequestPPCComparison(addr); }
void MemoryViewWidget::OnCopyAddress() { u32 addr = GetContextAddress(); QApplication::clipboard()->setText(QStringLiteral("%1").arg(addr, 8, 16, QLatin1Char('0'))); }
void CodeViewWidget::OnInsertNOP() { const u32 addr = GetContextAddress(); ReplaceAddress(addr, ReplaceWith::NOP); }