diff --git a/dsf/org.eclipse.cdt.dsf.ui/plugin.properties b/dsf/org.eclipse.cdt.dsf.ui/plugin.properties index b5a30947906..6dd13d5b1c8 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/plugin.properties +++ b/dsf/org.eclipse.cdt.dsf.ui/plugin.properties @@ -53,6 +53,8 @@ action.refreshAll.name=Refresh Debug Views action.refresh.label=Refresh +action.jumpToMemory.label=Jump to Memory + popup.addExpression.label=Add Watch Expression... popup.resumeAtLine.label=Resume At Li&ne popup.moveToLine.label=&Move To Line\u0020 @@ -67,6 +69,10 @@ command.addRegisters.name=Add Expression Group > Registers command.refreshAll.name=Refresh Debug Views command.refreshAll.description=Refresh all data in debug views +# jump to memory +command.jumpToMemory.name=Jump to Memory +command.jumpToMemory.description=Open memory view and add memory monitor for address + # Preferences StaleData.foreground.label=Stale data foreground color\u0020 diff --git a/dsf/org.eclipse.cdt.dsf.ui/plugin.xml b/dsf/org.eclipse.cdt.dsf.ui/plugin.xml index 4479e025382..9d638579552 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/plugin.xml +++ b/dsf/org.eclipse.cdt.dsf.ui/plugin.xml @@ -629,6 +629,12 @@ categoryId="org.eclipse.debug.ui.category.run" > + @@ -707,6 +713,12 @@ label="%action.toggleBreakpoint.label" menubarPath="debug"> + + diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyMessages.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyMessages.java index 5812994e0a8..e282e5fee95 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyMessages.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyMessages.java @@ -92,6 +92,10 @@ public final class DisassemblyMessages extends NLS { public static String Disassembly_action_AddBreakpoint_errorTitle; public static String Disassembly_action_AddBreakpoint_errorMessage; public static String Disassembly_action_ToggleBreakpoint_accelerator; + public static String Disassembly_action_JumpToMemory_label; + public static String Disassembly_action_JumpToMemory_tooltip; + public static String Disassembly_action_JumpToMemory_errorTitle; + public static String Disassembly_action_JumpToMemory_errorMessage; static { NLS.initializeMessages(DisassemblyMessages.class.getName(), DisassemblyMessages.class); diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyMessages.properties b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyMessages.properties index dea56eafa68..21ee653865a 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyMessages.properties +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyMessages.properties @@ -32,6 +32,10 @@ Disassembly_action_TrackExpression_label=Track Expression Disassembly_action_AddBreakpoint_label=Add Breakpoint... Disassembly_action_AddBreakpoint_errorTitle=Error Disassembly_action_AddBreakpoint_errorMessage=Unable to create breakpoint +Disassembly_action_JumpToMemory_label=Jump To Memory +Disassembly_action_JumpToMemory_tooltip=Open memory view and add memory monitor for address +Disassembly_action_JumpToMemory_errorTitle=Error on jump to memory +Disassembly_action_JumpToMemory_errorMessage=Unable to jump to memory location Disassembly_GotoAddressDialog_title=Go to Address Disassembly_GotoAddressDialog_label=Address expression: diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/RulerJumpToMemoryAction.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/RulerJumpToMemoryAction.java new file mode 100644 index 00000000000..8a2d21b6abe --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/RulerJumpToMemoryAction.java @@ -0,0 +1,182 @@ +/******************************************************************************* + * Copyright (c) 2021 Intel Corporation. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Intel Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions; + +import org.eclipse.cdt.core.IAddress; +import org.eclipse.cdt.debug.ui.CDebugUIPlugin; +import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.DisassemblyMessages; +import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.DisassemblySelection; +import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.IDisassemblyPart; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.model.IMemoryBlock; +import org.eclipse.debug.core.model.IMemoryBlockExtension; +import org.eclipse.debug.core.model.IMemoryBlockRetrievalExtension; +import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.debug.ui.memory.IMemoryRendering; +import org.eclipse.debug.ui.memory.IMemoryRenderingContainer; +import org.eclipse.debug.ui.memory.IMemoryRenderingSite; +import org.eclipse.debug.ui.memory.IMemoryRenderingType; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.text.source.IVerticalRulerInfo; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.PartInitException; + +/** + * Ruler action to jump to a memory location using the address of the last row selection. + */ +@SuppressWarnings("restriction") +public final class RulerJumpToMemoryAction extends AbstractDisassemblyRulerAction { + private static final String MEMORY_VIEW_ID = "org.eclipse.debug.ui.MemoryView"; //$NON-NLS-1$ + + public RulerJumpToMemoryAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo) { + super(disassemblyPart, rulerInfo); + setText(DisassemblyMessages.Disassembly_action_JumpToMemory_label); + setToolTipText(DisassemblyMessages.Disassembly_action_JumpToMemory_tooltip); + } + + @Override + public void run() { + if (getRulerInfo() == null || getDisassemblyPart() == null) { + reportException(new Exception("The current selection is invalid.")); //$NON-NLS-1$ + return; + } + + IAddress address = getAddress(); + if (address == null) { + reportException(new Exception("Failed to retrieve memory address.")); //$NON-NLS-1$ + return; + } + + IWorkbenchPartSite site = getDisassemblyPart().getSite(); + if (site == null) { + reportException(new Exception("No workbench site available. Disassembly view not initialized?")); //$NON-NLS-1$ + return; + } + IWorkbenchPage page = site.getPage(); + if (page == null) { + reportException(new Exception("No workbench page available. Disassembly view not initialized?")); //$NON-NLS-1$ + return; + } + IViewPart viewPart = page.findView(MEMORY_VIEW_ID); + if (viewPart != null) { + page.activate(viewPart); + } else { + try { + viewPart = page.showView(MEMORY_VIEW_ID); + } catch (PartInitException e) { + reportException(e); + return; + } + } + + if (!(viewPart instanceof IMemoryRenderingSite)) { + reportException(new Exception("Failed to open memory view.")); //$NON-NLS-1$ + return; + } + + addMemoryBlock((IMemoryRenderingSite) viewPart, address.toHexAddressString()); + } + + /** + * Add memory block for the given address. + * + * @param memoryView the memory view + * @param address the memory address to add the block for + */ + private void addMemoryBlock(IMemoryRenderingSite memoryView, String address) { + try { + IAdaptable debugContext = DebugUITools.getPartDebugContext(getDisassemblyPart().getSite()); + + IMemoryBlockRetrievalExtension memRetrieval = (IMemoryBlockRetrievalExtension) MemoryViewUtil + .getMemoryBlockRetrieval(debugContext); + + // get extended memory block with the expression entered + IMemoryBlockExtension memBlock = memRetrieval.getExtendedMemoryBlock(address, debugContext); + + // add block to memory block manager + if (memBlock == null) { + throw new Exception("Failed to retrieve memory block."); //$NON-NLS-1$ + } + IMemoryBlock[] memArray = new IMemoryBlock[] { memBlock }; + + DebugPlugin.getDefault().getMemoryBlockManager().addMemoryBlocks(memArray); + + IMemoryRenderingType renderingType = DebugUITools.getMemoryRenderingManager() + .getPrimaryRenderingType(memBlock); + + IMemoryRendering rendering = renderingType.createRendering(); + + IMemoryRenderingContainer container = memoryView.getContainer(IDebugUIConstants.ID_RENDERING_VIEW_PANE_1); + + rendering.init(container, memBlock); + container.addMemoryRendering(rendering); + } catch (Exception e) { + reportException(e); + } + } + + /** + * @return the address from the current selection, or null + */ + private IAddress getAddress() { + int lastLine = getRulerInfo().getLineOfLastMouseButtonActivity(); + if (lastLine < 0) { + return null; + } + ISelectionProvider provider = getDisassemblyPart().getSite().getSelectionProvider(); + if (provider == null) { + return null; + } + IDocument document = getDisassemblyPart().getTextViewer().getDocument(); + if (document == null) { + return null; + } + + IRegion region; + try { + region = document.getLineInformation(lastLine); + } catch (BadLocationException e) { + return null; + } + ITextSelection textSelection = new TextSelection(document, region.getOffset(), 0); + DisassemblySelection selection = new DisassemblySelection(textSelection, getDisassemblyPart()); + return selection.getStartAddress(); + } + + /** + * Report an error to the user. + * + * @param e underlying exception + */ + private void reportException(Exception e) { + IStatus status = new Status(IStatus.ERROR, CDebugUIPlugin.PLUGIN_ID, "Error on jump to memory: ", e); //$NON-NLS-1$ + ErrorDialog.openError(getDisassemblyPart().getSite().getShell(), + DisassemblyMessages.Disassembly_action_JumpToMemory_errorTitle, + DisassemblyMessages.Disassembly_action_JumpToMemory_errorMessage, status); + CDebugUIPlugin.log(status); + } +} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/RulerJumpToMemoryActionDelegate.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/RulerJumpToMemoryActionDelegate.java new file mode 100644 index 00000000000..227064522c5 --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/RulerJumpToMemoryActionDelegate.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2021 Intel Corporation. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Intel Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions; + +import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.IDisassemblyPart; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.text.source.IVerticalRulerInfo; + +/** + * Ruler jump to memory delegate for disassembly parts. + */ +public class RulerJumpToMemoryActionDelegate extends AbstractDisassemblyRulerActionDelegate { + + /* + * @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions.AbstractDisassemblyRulerActionDelegate#createAction(org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.IDisassemblyPart, org.eclipse.jface.text.source.IVerticalRulerInfo) + */ + @Override + protected IAction createAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo) { + return new RulerJumpToMemoryAction(disassemblyPart, rulerInfo); + } +} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/RulerJumpToMemoryHandler.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/RulerJumpToMemoryHandler.java new file mode 100644 index 00000000000..14f4ff10b17 --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/RulerJumpToMemoryHandler.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2021 Intel Corporation. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Intel Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions; + +import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.IDisassemblyPart; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.text.source.IVerticalRulerInfo; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.handlers.HandlerUtil; + +/** + * Default handler for the jump to memory command in the disassembly ruler. + * + * @since 2.10 + */ +public class RulerJumpToMemoryHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchPart part = HandlerUtil.getActivePartChecked(event); + if (part instanceof IDisassemblyPart) { + IDisassemblyPart disassemblyPart = (IDisassemblyPart) part; + final IVerticalRulerInfo rulerInfo = part.getAdapter(IVerticalRulerInfo.class); + if (rulerInfo != null) { + new RulerJumpToMemoryAction(disassemblyPart, rulerInfo).run(); + } + } + return null; + } +}