37
|
1 |
/*******************************************************************************
|
|
2 |
* Copyright (c) 2007, 2009 Wind River Systems and others.
|
|
3 |
* All rights reserved. This program and the accompanying materials
|
|
4 |
* are made available under the terms of the Eclipse Public License v1.0
|
|
5 |
* which accompanies this distribution, and is available at
|
|
6 |
* http://www.eclipse.org/legal/epl-v10.html
|
|
7 |
*
|
|
8 |
* Contributors:
|
|
9 |
* Wind River Systems - initial API and implementation
|
|
10 |
*******************************************************************************/
|
|
11 |
package org.eclipse.cdt.dsf.debug.internal.ui.disassembly;
|
|
12 |
|
|
13 |
import java.io.File;
|
|
14 |
import java.math.BigInteger;
|
|
15 |
import java.util.ArrayList;
|
|
16 |
import java.util.HashMap;
|
|
17 |
import java.util.Iterator;
|
|
18 |
import java.util.LinkedList;
|
|
19 |
import java.util.List;
|
|
20 |
import java.util.ListIterator;
|
|
21 |
import java.util.Map;
|
|
22 |
import java.util.concurrent.ExecutionException;
|
|
23 |
|
|
24 |
import org.eclipse.cdt.core.IAddress;
|
|
25 |
import org.eclipse.cdt.debug.core.CDIDebugModel;
|
|
26 |
import org.eclipse.cdt.debug.core.model.ICBreakpoint;
|
|
27 |
import org.eclipse.cdt.debug.core.model.ICBreakpointType;
|
|
28 |
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
|
29 |
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
|
|
30 |
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
|
31 |
import org.eclipse.cdt.dsf.concurrent.Query;
|
|
32 |
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
|
33 |
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
|
34 |
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions.AbstractDisassemblyAction;
|
|
35 |
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions.ActionGotoAddress;
|
|
36 |
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions.ActionGotoProgramCounter;
|
|
37 |
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions.ActionGotoSymbol;
|
|
38 |
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions.ActionOpenPreferences;
|
|
39 |
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions.TextOperationAction;
|
|
40 |
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.Addr2Line;
|
|
41 |
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.AddressRangePosition;
|
|
42 |
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.BreakpointsAnnotationModel;
|
|
43 |
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument;
|
|
44 |
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyPosition;
|
|
45 |
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.ErrorPosition;
|
|
46 |
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.LabelPosition;
|
|
47 |
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourceFileInfo;
|
|
48 |
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourcePosition;
|
|
49 |
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.preferences.DisassemblyPreferenceConstants;
|
|
50 |
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.presentation.DisassemblyIPAnnotation;
|
|
51 |
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.util.HSL;
|
|
52 |
import org.eclipse.cdt.dsf.debug.service.IDisassembly;
|
|
53 |
import org.eclipse.cdt.dsf.debug.service.IExpressions;
|
|
54 |
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
|
|
55 |
import org.eclipse.cdt.dsf.debug.service.IInstruction;
|
|
56 |
import org.eclipse.cdt.dsf.debug.service.IMixedInstruction;
|
|
57 |
import org.eclipse.cdt.dsf.debug.service.IRunControl;
|
|
58 |
import org.eclipse.cdt.dsf.debug.service.ISourceLookup;
|
|
59 |
import org.eclipse.cdt.dsf.debug.service.IStack;
|
|
60 |
import org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext;
|
|
61 |
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
|
|
62 |
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
|
|
63 |
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData;
|
|
64 |
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
|
|
65 |
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent;
|
|
66 |
import org.eclipse.cdt.dsf.debug.service.IRunControl.IResumedDMEvent;
|
|
67 |
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
|
|
68 |
import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext;
|
|
69 |
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
|
|
70 |
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMData;
|
|
71 |
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
|
|
72 |
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
|
|
73 |
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
|
|
74 |
import org.eclipse.cdt.dsf.service.DsfSession;
|
|
75 |
import org.eclipse.cdt.dsf.service.DsfSession.SessionEndedListener;
|
|
76 |
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
|
|
77 |
import org.eclipse.cdt.internal.ui.dnd.TextViewerDragAdapter;
|
|
78 |
import org.eclipse.cdt.utils.Addr64;
|
|
79 |
import org.eclipse.core.resources.IFile;
|
|
80 |
import org.eclipse.core.resources.IMarker;
|
|
81 |
import org.eclipse.core.resources.IResource;
|
|
82 |
import org.eclipse.core.resources.IStorage;
|
|
83 |
import org.eclipse.core.resources.ResourcesPlugin;
|
|
84 |
import org.eclipse.core.runtime.CoreException;
|
|
85 |
import org.eclipse.core.runtime.IAdaptable;
|
|
86 |
import org.eclipse.core.runtime.IPath;
|
|
87 |
import org.eclipse.core.runtime.IStatus;
|
|
88 |
import org.eclipse.core.runtime.ListenerList;
|
|
89 |
import org.eclipse.core.runtime.Platform;
|
|
90 |
import org.eclipse.core.runtime.Status;
|
|
91 |
import org.eclipse.debug.core.DebugPlugin;
|
|
92 |
import org.eclipse.debug.core.IBreakpointManager;
|
|
93 |
import org.eclipse.debug.core.model.IBreakpoint;
|
|
94 |
import org.eclipse.debug.core.model.ISuspendResume;
|
|
95 |
import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage;
|
|
96 |
import org.eclipse.debug.ui.DebugUITools;
|
|
97 |
import org.eclipse.debug.ui.actions.IRunToLineTarget;
|
|
98 |
import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget;
|
|
99 |
import org.eclipse.jface.action.Action;
|
|
100 |
import org.eclipse.jface.action.GroupMarker;
|
|
101 |
import org.eclipse.jface.action.IAction;
|
|
102 |
import org.eclipse.jface.action.IMenuListener;
|
|
103 |
import org.eclipse.jface.action.IMenuManager;
|
|
104 |
import org.eclipse.jface.action.IToolBarManager;
|
|
105 |
import org.eclipse.jface.action.MenuManager;
|
|
106 |
import org.eclipse.jface.action.Separator;
|
|
107 |
import org.eclipse.jface.commands.ActionHandler;
|
|
108 |
import org.eclipse.jface.dialogs.ErrorDialog;
|
|
109 |
import org.eclipse.jface.preference.IPreferenceStore;
|
|
110 |
import org.eclipse.jface.preference.PreferenceConverter;
|
|
111 |
import org.eclipse.jface.resource.JFaceResources;
|
|
112 |
import org.eclipse.jface.text.BadLocationException;
|
|
113 |
import org.eclipse.jface.text.BadPositionCategoryException;
|
|
114 |
import org.eclipse.jface.text.IFindReplaceTarget;
|
|
115 |
import org.eclipse.jface.text.IRegion;
|
|
116 |
import org.eclipse.jface.text.ITextOperationTarget;
|
|
117 |
import org.eclipse.jface.text.ITextPresentationListener;
|
|
118 |
import org.eclipse.jface.text.ITextSelection;
|
|
119 |
import org.eclipse.jface.text.ITextViewerExtension;
|
|
120 |
import org.eclipse.jface.text.IViewportListener;
|
|
121 |
import org.eclipse.jface.text.Position;
|
|
122 |
import org.eclipse.jface.text.Region;
|
|
123 |
import org.eclipse.jface.text.TextPresentation;
|
|
124 |
import org.eclipse.jface.text.source.Annotation;
|
|
125 |
import org.eclipse.jface.text.source.AnnotationModel;
|
|
126 |
import org.eclipse.jface.text.source.AnnotationRulerColumn;
|
|
127 |
import org.eclipse.jface.text.source.CompositeRuler;
|
|
128 |
import org.eclipse.jface.text.source.IAnnotationAccess;
|
|
129 |
import org.eclipse.jface.text.source.IAnnotationModel;
|
|
130 |
import org.eclipse.jface.text.source.IAnnotationModelExtension;
|
|
131 |
import org.eclipse.jface.text.source.IOverviewRuler;
|
|
132 |
import org.eclipse.jface.text.source.ISharedTextColors;
|
|
133 |
import org.eclipse.jface.text.source.ISourceViewer;
|
|
134 |
import org.eclipse.jface.text.source.IVerticalRuler;
|
|
135 |
import org.eclipse.jface.text.source.IVerticalRulerColumn;
|
|
136 |
import org.eclipse.jface.text.source.IVerticalRulerExtension;
|
|
137 |
import org.eclipse.jface.text.source.IVerticalRulerInfo;
|
|
138 |
import org.eclipse.jface.text.source.OverviewRuler;
|
|
139 |
import org.eclipse.jface.text.source.SourceViewerConfiguration;
|
|
140 |
import org.eclipse.jface.util.IPropertyChangeListener;
|
|
141 |
import org.eclipse.jface.util.PropertyChangeEvent;
|
|
142 |
import org.eclipse.jface.viewers.ISelection;
|
|
143 |
import org.eclipse.jface.viewers.ISelectionChangedListener;
|
|
144 |
import org.eclipse.jface.viewers.SelectionChangedEvent;
|
|
145 |
import org.eclipse.swt.SWT;
|
|
146 |
import org.eclipse.swt.custom.StyleRange;
|
|
147 |
import org.eclipse.swt.custom.StyledText;
|
|
148 |
import org.eclipse.swt.dnd.DND;
|
|
149 |
import org.eclipse.swt.dnd.DragSource;
|
|
150 |
import org.eclipse.swt.dnd.DropTarget;
|
|
151 |
import org.eclipse.swt.dnd.FileTransfer;
|
|
152 |
import org.eclipse.swt.dnd.TextTransfer;
|
|
153 |
import org.eclipse.swt.dnd.Transfer;
|
|
154 |
import org.eclipse.swt.events.MouseAdapter;
|
|
155 |
import org.eclipse.swt.events.MouseEvent;
|
|
156 |
import org.eclipse.swt.graphics.Color;
|
|
157 |
import org.eclipse.swt.graphics.Font;
|
|
158 |
import org.eclipse.swt.graphics.FontData;
|
|
159 |
import org.eclipse.swt.graphics.Point;
|
|
160 |
import org.eclipse.swt.graphics.RGB;
|
|
161 |
import org.eclipse.swt.graphics.Rectangle;
|
|
162 |
import org.eclipse.swt.layout.FillLayout;
|
|
163 |
import org.eclipse.swt.widgets.Composite;
|
|
164 |
import org.eclipse.swt.widgets.Control;
|
|
165 |
import org.eclipse.swt.widgets.Display;
|
|
166 |
import org.eclipse.swt.widgets.Menu;
|
|
167 |
import org.eclipse.ui.IActionBars;
|
|
168 |
import org.eclipse.ui.IPartListener2;
|
|
169 |
import org.eclipse.ui.IWorkbenchActionConstants;
|
|
170 |
import org.eclipse.ui.IWorkbenchCommandConstants;
|
|
171 |
import org.eclipse.ui.IWorkbenchPart;
|
|
172 |
import org.eclipse.ui.IWorkbenchPartReference;
|
|
173 |
import org.eclipse.ui.IWorkbenchPartSite;
|
|
174 |
import org.eclipse.ui.PlatformUI;
|
|
175 |
import org.eclipse.ui.actions.ActionFactory;
|
|
176 |
import org.eclipse.ui.contexts.IContextActivation;
|
|
177 |
import org.eclipse.ui.contexts.IContextService;
|
|
178 |
import org.eclipse.ui.editors.text.EditorsUI;
|
|
179 |
import org.eclipse.ui.handlers.IHandlerActivation;
|
|
180 |
import org.eclipse.ui.handlers.IHandlerService;
|
|
181 |
import org.eclipse.ui.ide.IGotoMarker;
|
|
182 |
import org.eclipse.ui.part.WorkbenchPart;
|
|
183 |
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
|
|
184 |
import org.eclipse.ui.texteditor.AnnotationPreference;
|
|
185 |
import org.eclipse.ui.texteditor.ChainedPreferenceStore;
|
|
186 |
import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;
|
|
187 |
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
|
|
188 |
import org.eclipse.ui.texteditor.IUpdate;
|
|
189 |
import org.eclipse.ui.texteditor.MarkerAnnotationPreferences;
|
|
190 |
import org.eclipse.ui.texteditor.SimpleMarkerAnnotation;
|
|
191 |
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
|
|
192 |
|
|
193 |
/**
|
|
194 |
* DisassemblyPart
|
|
195 |
*/
|
|
196 |
@SuppressWarnings("restriction")
|
|
197 |
public abstract class DisassemblyPart extends WorkbenchPart implements IDisassemblyPart, IViewportListener, ITextPresentationListener, SessionEndedListener {
|
|
198 |
|
|
199 |
private final static boolean DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.cdt.dsf.ui/debug/disassembly")); //$NON-NLS-1$//$NON-NLS-2$
|
|
200 |
|
|
201 |
/**
|
|
202 |
* Annotation model attachment key for breakpoint annotations.
|
|
203 |
*/
|
|
204 |
private final static String BREAKPOINT_ANNOTATIONS= "breakpoints"; //$NON-NLS-1$
|
|
205 |
|
|
206 |
private final static BigInteger PC_UNKNOWN = BigInteger.valueOf(-1);
|
|
207 |
private final static BigInteger PC_RUNNING = BigInteger.valueOf(-2);
|
|
208 |
|
|
209 |
/** Preference key for highlighting current line. */
|
|
210 |
private final static String CURRENT_LINE = AbstractDecoratedTextEditorPreferenceConstants.EDITOR_CURRENT_LINE;
|
|
211 |
/** Preference key for highlight color of current line. */
|
|
212 |
private final static String CURRENT_LINE_COLOR = AbstractDecoratedTextEditorPreferenceConstants.EDITOR_CURRENT_LINE_COLOR;
|
|
213 |
|
|
214 |
/** The width of the vertical ruler. */
|
|
215 |
protected final static int VERTICAL_RULER_WIDTH = 12;
|
|
216 |
|
|
217 |
/** High water mark for cache */
|
|
218 |
private final static int fgHighWaterMark = 500;
|
|
219 |
/** Low water mark for cache */
|
|
220 |
private final static int fgLowWaterMark = 100;
|
|
221 |
|
|
222 |
private static final String COMMAND_ID_GOTO_ADDRESS = "org.eclipse.cdt.dsf.debug.ui.disassembly.commands.gotoAddress"; //$NON-NLS-1$
|
|
223 |
private static final String COMMAND_ID_GOTO_PC = "org.eclipse.cdt.dsf.debug.ui.disassembly.commands.gotoPC"; //$NON-NLS-1$
|
|
224 |
private static final String COMMAND_ID_GOTO_SYMBOL = "org.eclipse.cdt.dsf.debug.ui.disassembly.commands.gotoSymbol"; //$NON-NLS-1$
|
|
225 |
// private static final String COMMAND_ID_TOGGLE_BREAKPOINT = "org.eclipse.debug.ui.commands.ToggleBreakpoint"; //$NON-NLS-1$
|
|
226 |
// private static final String COMMAND_ID_RUN_TO_LINE = "org.eclipse.debug.ui.commands.RunToLine"; //$NON-NLS-1$
|
|
227 |
// private static final String COMMAND_ID_TOGGLE_STEPPING_MODE = "org.eclipse.cdt.dsf.debug.ui.debug.ui.menu.showDisassemblyAction"; //$NON-NLS-1$
|
|
228 |
|
|
229 |
private static final String KEY_BINDING_CONTEXT_DISASSEMBLY = "org.eclipse.cdt.dsf.debug.ui.disassembly.context"; //$NON-NLS-1$
|
|
230 |
|
|
231 |
protected DisassemblyViewer fViewer;
|
|
232 |
|
|
233 |
protected AbstractDisassemblyAction fActionGotoPC;
|
|
234 |
protected AbstractDisassemblyAction fActionGotoAddress;
|
|
235 |
private AbstractDisassemblyAction fActionGotoSymbol;
|
|
236 |
private AbstractDisassemblyAction fActionToggleBreakpoint;
|
|
237 |
protected AbstractDisassemblyAction fActionToggleSource;
|
|
238 |
private AbstractDisassemblyAction fActionToggleFunctionColumn;
|
|
239 |
private AbstractDisassemblyAction fActionToggleSymbols;
|
|
240 |
private AbstractDisassemblyAction fActionRefreshView;
|
|
241 |
private Action fActionOpenPreferences;
|
|
242 |
private AbstractDisassemblyAction fActionToggleAddressColumn;
|
|
243 |
private AbstractDisassemblyAction fActionToggleBreakpointEnablement;
|
|
244 |
|
|
245 |
protected DisassemblyDocument fDocument;
|
|
246 |
private IAnnotationAccess fAnnotationAccess;
|
|
247 |
private AnnotationRulerColumn fAnnotationRulerColumn;
|
|
248 |
private MarkerAnnotationPreferences fAnnotationPreferences;
|
|
249 |
private IPreferenceStore fPreferenceStore;
|
|
250 |
private IOverviewRuler fOverviewRuler;
|
|
251 |
private final ListenerList fRulerContextMenuListeners= new ListenerList(ListenerList.IDENTITY);
|
|
252 |
private SourceViewerDecorationSupport fDecorationSupport;
|
|
253 |
private Font fFont;
|
|
254 |
private IVerticalRuler fVerticalRuler;
|
|
255 |
private IFindReplaceTarget fFindReplaceTarget;
|
|
256 |
private IPropertyChangeListener fPropertyChangeListener= new PropertyChangeListener();
|
|
257 |
private Color fInstructionColor;
|
|
258 |
private Color fErrorColor;
|
|
259 |
private Color fSourceColor;
|
|
260 |
private Color fLabelColor;
|
|
261 |
private Control fRedrawControl;
|
|
262 |
private RGB fPCAnnotationRGB;
|
|
263 |
private Composite fComposite;
|
|
264 |
|
|
265 |
private DropTarget fDropTarget;
|
|
266 |
private DragSource fDragSource;
|
|
267 |
private TextViewerDragAdapter fDragSourceAdapter;
|
|
268 |
private DisassemblyDropAdapter fDropTargetAdapter;
|
|
269 |
|
|
270 |
private FunctionOffsetRulerColumn fOpcodeRulerColumn;
|
|
271 |
private AddressRulerColumn fAddressRulerColumn;
|
|
272 |
|
|
273 |
private BigInteger fStartAddress;
|
|
274 |
private BigInteger fEndAddress;
|
|
275 |
private int fAddressSize= 32;
|
|
276 |
|
|
277 |
private volatile boolean fUpdatePending;
|
|
278 |
private BigInteger fPCAddress;
|
|
279 |
private BigInteger fGotoAddressPending= PC_UNKNOWN;
|
|
280 |
private BigInteger fFocusAddress= PC_UNKNOWN;
|
|
281 |
private int fBufferZone;
|
|
282 |
private IExecutionDMContext fTargetContext;
|
|
283 |
private String fDebugSessionId;
|
|
284 |
private int fTargetFrame;
|
|
285 |
private DisassemblyIPAnnotation fPCAnnotation;
|
|
286 |
private DisassemblyIPAnnotation fSecondaryPCAnnotation;
|
|
287 |
private boolean fPCAnnotationUpdatePending;
|
|
288 |
private ArrayList<BigInteger> fPendingPCUpdates = new ArrayList<BigInteger>(5);
|
|
289 |
private Position fScrollPos;
|
|
290 |
private int fScrollLine;
|
|
291 |
private Position fFocusPos;
|
|
292 |
private BigInteger fFrameAddress= PC_UNKNOWN;
|
|
293 |
protected Map<String, Action> fGlobalActions = new HashMap<String, Action>();
|
|
294 |
private List<Action> fSelectionActions = new ArrayList<Action>();
|
|
295 |
private List<AbstractDisassemblyAction> fStateDependentActions = new ArrayList<AbstractDisassemblyAction>();
|
|
296 |
private boolean fSourceOnlyMode;
|
|
297 |
private boolean fShowSource;
|
|
298 |
private boolean fShowOpcodes;
|
|
299 |
private boolean fShowSymbols;
|
|
300 |
private Map<String, Object> fFile2Storage = new HashMap<String, Object>();
|
|
301 |
private boolean fShowDisassembly;
|
|
302 |
private LinkedList<AddressRangePosition> fPCHistory = new LinkedList<AddressRangePosition>();
|
|
303 |
private int fPCHistorySizeMax = 4;
|
|
304 |
private boolean fGotoFramePending;
|
|
305 |
|
|
306 |
private String fPCAnnotationColorKey;
|
|
307 |
|
|
308 |
private ArrayList<Runnable> fRunnableQueue = new ArrayList<Runnable>();
|
|
309 |
|
|
310 |
protected IPartListener2 fPartListener =
|
|
311 |
new IPartListener2() {
|
|
312 |
public void partActivated(IWorkbenchPartReference partRef) {
|
|
313 |
}
|
|
314 |
public void partBroughtToTop(IWorkbenchPartReference partRef) {
|
|
315 |
}
|
|
316 |
public void partClosed(IWorkbenchPartReference partRef) {
|
|
317 |
}
|
|
318 |
public void partDeactivated(IWorkbenchPartReference partRef) {
|
|
319 |
}
|
|
320 |
public void partOpened(IWorkbenchPartReference partRef) {
|
|
321 |
}
|
|
322 |
public void partHidden(IWorkbenchPartReference partRef) {
|
|
323 |
if (partRef.getPart(false) == DisassemblyPart.this) {
|
|
324 |
setActive(false);
|
|
325 |
}
|
|
326 |
}
|
|
327 |
public void partVisible(IWorkbenchPartReference partRef) {
|
|
328 |
if (partRef.getPart(false) == DisassemblyPart.this) {
|
|
329 |
setActive(true);
|
|
330 |
}
|
|
331 |
}
|
|
332 |
public void partInputChanged(IWorkbenchPartReference partRef) {
|
|
333 |
}
|
|
334 |
};
|
|
335 |
|
|
336 |
private boolean fActive = true;
|
|
337 |
private boolean fDoPendingPosted;
|
|
338 |
private boolean fUpdateBeforeFocus;
|
|
339 |
|
|
340 |
private boolean fRefreshAll;
|
|
341 |
private IMarker fGotoMarkerPending;
|
|
342 |
private boolean fUpdateTitlePending;
|
|
343 |
private boolean fRefreshViewPending;
|
|
344 |
private boolean fUpdateSourcePending;
|
|
345 |
|
|
346 |
private ArrayList<IHandlerActivation> fHandlerActivations;
|
|
347 |
private IContextActivation fContextActivation;
|
|
348 |
|
|
349 |
private DsfServicesTracker fServicesTracker;
|
|
350 |
private IFrameDMContext fTargetFrameContext;
|
|
351 |
protected IFrameDMData fTargetFrameData;
|
|
352 |
|
|
353 |
|
|
354 |
private final class ActionRefreshView extends AbstractDisassemblyAction {
|
|
355 |
public ActionRefreshView() {
|
|
356 |
super(DisassemblyPart.this);
|
|
357 |
setText(DisassemblyMessages.Disassembly_action_RefreshView_label);
|
|
358 |
setImageDescriptor(DisassemblyImageRegistry.getImageDescriptor(DisassemblyImageRegistry.ICON_Refresh_enabled));
|
|
359 |
setDisabledImageDescriptor(DisassemblyImageRegistry.getImageDescriptor(DisassemblyImageRegistry.ICON_Refresh_disabled));
|
|
360 |
}
|
|
361 |
@Override
|
|
362 |
public void run() {
|
|
363 |
refreshView(10);
|
|
364 |
}
|
|
365 |
}
|
|
366 |
|
|
367 |
private final class ActionToggleAddressColumn extends AbstractDisassemblyAction {
|
|
368 |
ActionToggleAddressColumn () {
|
|
369 |
super(DisassemblyPart.this);
|
|
370 |
setText(DisassemblyMessages.Disassembly_action_ShowAddresses_label);
|
|
371 |
}
|
|
372 |
@Override
|
|
373 |
public void run() {
|
|
374 |
IPreferenceStore store = DsfUIPlugin.getDefault().getPreferenceStore();
|
|
375 |
store.setValue(DisassemblyPreferenceConstants.SHOW_ADDRESS_RULER, !isAddressRulerVisible());
|
|
376 |
}
|
|
377 |
@Override
|
|
378 |
public void update() {
|
|
379 |
setChecked(isAddressRulerVisible());
|
|
380 |
}
|
|
381 |
}
|
|
382 |
|
|
383 |
private final class ActionToggleFunctionColumn extends AbstractDisassemblyAction {
|
|
384 |
ActionToggleFunctionColumn() {
|
|
385 |
super(DisassemblyPart.this);
|
|
386 |
setText(DisassemblyMessages.Disassembly_action_ShowFunctionOffsets_label);
|
|
387 |
}
|
|
388 |
@Override
|
|
389 |
public void run() {
|
|
390 |
IPreferenceStore store = DsfUIPlugin.getDefault().getPreferenceStore();
|
|
391 |
store.setValue(DisassemblyPreferenceConstants.SHOW_FUNCTION_OFFSETS, !isOpcodeRulerVisible());
|
|
392 |
}
|
|
393 |
@Override
|
|
394 |
public void update() {
|
|
395 |
setChecked(isOpcodeRulerVisible());
|
|
396 |
}
|
|
397 |
}
|
|
398 |
|
|
399 |
private final class ActionToggleBreakpoint extends AbstractDisassemblyAction {
|
|
400 |
private IBreakpoint fBreakpoint;
|
|
401 |
private int fLine;
|
|
402 |
public ActionToggleBreakpoint() {
|
|
403 |
super(DisassemblyPart.this);
|
|
404 |
setText(DisassemblyMessages.Disassembly_action_AddBreakpoint_label);
|
|
405 |
setImageDescriptor(DisassemblyImageRegistry.getImageDescriptor(DisassemblyImageRegistry.ICON_ToggleBreakpoint));
|
|
406 |
}
|
|
407 |
@Override
|
|
408 |
public void run() {
|
|
409 |
try {
|
|
410 |
if (fBreakpoint != null) {
|
|
411 |
fBreakpoint.delete();
|
|
412 |
} else {
|
|
413 |
insertBreakpoint(fLine, false);
|
|
414 |
}
|
|
415 |
} catch (CoreException e) {
|
|
416 |
DsfUIPlugin.getDefault().getLog().log(e.getStatus());
|
|
417 |
}
|
|
418 |
}
|
|
419 |
@Override
|
|
420 |
public void update() {
|
|
421 |
super.update();
|
|
422 |
if (isEnabled()) {
|
|
423 |
fLine = fVerticalRuler.getLineOfLastMouseButtonActivity();
|
|
424 |
IBreakpoint[] bps = getBreakpointsAtLine(fLine);
|
|
425 |
if (bps == null) {
|
|
426 |
fBreakpoint = null;
|
|
427 |
setText(DisassemblyMessages.Disassembly_action_AddBreakpoint_label);
|
|
428 |
} else {
|
|
429 |
fBreakpoint = bps[0];
|
|
430 |
setText(DisassemblyMessages.Disassembly_action_RemoveBreakpoint_label);
|
|
431 |
}
|
|
432 |
}
|
|
433 |
}
|
|
434 |
}
|
|
435 |
|
|
436 |
private final class ActionToggleBreakpointEnablement extends AbstractDisassemblyAction {
|
|
437 |
private IBreakpoint fBreakpoint;
|
|
438 |
public ActionToggleBreakpointEnablement() {
|
|
439 |
super(DisassemblyPart.this);
|
|
440 |
setText(DisassemblyMessages.Disassembly_action_EnableBreakpoint_label);
|
|
441 |
}
|
|
442 |
@Override
|
|
443 |
public void run() {
|
|
444 |
try {
|
|
445 |
fBreakpoint.setEnabled(!fBreakpoint.isEnabled());
|
|
446 |
} catch (CoreException e) {
|
|
447 |
internalError(e);
|
|
448 |
}
|
|
449 |
}
|
|
450 |
@Override
|
|
451 |
public void update() {
|
|
452 |
super.update();
|
|
453 |
if (isEnabled()) {
|
|
454 |
int line = fVerticalRuler.getLineOfLastMouseButtonActivity();
|
|
455 |
IBreakpoint[] bps = getBreakpointsAtLine(line);
|
|
456 |
if (bps == null || bps.length == 0) {
|
|
457 |
setEnabled(false);
|
|
458 |
} else {
|
|
459 |
fBreakpoint = bps[0];
|
|
460 |
try {
|
|
461 |
if (fBreakpoint.isEnabled()) {
|
|
462 |
setText(DisassemblyMessages.Disassembly_action_DisableBreakpoint_label);
|
|
463 |
} else {
|
|
464 |
setText(DisassemblyMessages.Disassembly_action_EnableBreakpoint_label);
|
|
465 |
}
|
|
466 |
} catch (CoreException e) {
|
|
467 |
setEnabled(false);
|
|
468 |
}
|
|
469 |
}
|
|
470 |
}
|
|
471 |
}
|
|
472 |
}
|
|
473 |
|
|
474 |
private final class ActionToggleSource extends AbstractDisassemblyAction {
|
|
475 |
public ActionToggleSource() {
|
|
476 |
super(DisassemblyPart.this);
|
|
477 |
setText(DisassemblyMessages.Disassembly_action_ShowSource_label);
|
|
478 |
}
|
|
479 |
@Override
|
|
480 |
public void run() {
|
|
481 |
IPreferenceStore store = DsfUIPlugin.getDefault().getPreferenceStore();
|
|
482 |
boolean showSourceEnabled = store.getBoolean(DisassemblyPreferenceConstants.SHOW_SOURCE);
|
|
483 |
if (showSourceEnabled == fShowSource) {
|
|
484 |
store.setValue(DisassemblyPreferenceConstants.SHOW_SOURCE, !fShowSource);
|
|
485 |
} else {
|
|
486 |
sourceModeChanged(!fShowSource);
|
|
487 |
}
|
|
488 |
}
|
|
489 |
@Override
|
|
490 |
public void update() {
|
|
491 |
super.update();
|
|
492 |
if (isEnabled()) {
|
|
493 |
setEnabled(fShowDisassembly);
|
|
494 |
}
|
|
495 |
setChecked(fShowSource);
|
|
496 |
}
|
|
497 |
}
|
|
498 |
|
|
499 |
private final class ActionToggleSymbols extends AbstractDisassemblyAction {
|
|
500 |
public ActionToggleSymbols() {
|
|
501 |
super(DisassemblyPart.this);
|
|
502 |
setText(DisassemblyMessages.Disassembly_action_ShowSymbols_label);
|
|
503 |
}
|
|
504 |
@Override
|
|
505 |
public void run() {
|
|
506 |
IPreferenceStore store = DsfUIPlugin.getDefault().getPreferenceStore();
|
|
507 |
store.setValue(DisassemblyPreferenceConstants.SHOW_SYMBOLS, !fShowSymbols);
|
|
508 |
}
|
|
509 |
@Override
|
|
510 |
public void update() {
|
|
511 |
super.update();
|
|
512 |
setChecked(fShowSymbols);
|
|
513 |
}
|
|
514 |
}
|
|
515 |
|
|
516 |
/**
|
|
517 |
* Internal property change listener for handling changes in the
|
|
518 |
* preferences.
|
|
519 |
*/
|
|
520 |
class PropertyChangeListener implements IPropertyChangeListener {
|
|
521 |
/*
|
|
522 |
* @see IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
|
|
523 |
*/
|
|
524 |
public void propertyChange(PropertyChangeEvent event) {
|
|
525 |
handlePreferenceStoreChanged(event);
|
|
526 |
}
|
|
527 |
}
|
|
528 |
|
|
529 |
|
|
530 |
/**
|
|
531 |
* The constructor.
|
|
532 |
*/
|
|
533 |
public DisassemblyPart() {
|
|
534 |
fAnnotationPreferences = new MarkerAnnotationPreferences();
|
|
535 |
setPreferenceStore(new ChainedPreferenceStore(new IPreferenceStore[] {
|
|
536 |
DsfUIPlugin.getDefault().getPreferenceStore(), EditorsUI.getPreferenceStore() }));
|
|
537 |
fPCAddress = fFrameAddress = PC_UNKNOWN;
|
|
538 |
fTargetFrame = -1;
|
|
539 |
fBufferZone = 32;
|
|
540 |
fPCAnnotation = new DisassemblyIPAnnotation(true, 0);
|
|
541 |
fSecondaryPCAnnotation = new DisassemblyIPAnnotation(false, 0);
|
|
542 |
IPreferenceStore prefs = getPreferenceStore();
|
|
543 |
fStartAddress = new BigInteger(prefs.getString(DisassemblyPreferenceConstants.START_ADDRESS));
|
|
544 |
String endAddressString = prefs.getString(DisassemblyPreferenceConstants.END_ADDRESS);
|
|
545 |
if(endAddressString.startsWith("0x")) //$NON-NLS-1$
|
|
546 |
fEndAddress = new BigInteger(endAddressString.substring(2), 16);
|
|
547 |
else
|
|
548 |
fEndAddress = new BigInteger(endAddressString, 16);
|
|
549 |
// TLETODO [disassembly[ source only mode
|
|
550 |
fSourceOnlyMode = false; //prefs.getBoolean(DisassemblyPreferenceConstants.USE_SOURCE_ONLY_MODE);
|
|
551 |
fShowSource = fSourceOnlyMode || prefs.getBoolean(DisassemblyPreferenceConstants.SHOW_SOURCE);
|
|
552 |
fShowDisassembly = !fSourceOnlyMode || !fShowSource;
|
|
553 |
fShowOpcodes = prefs.getBoolean(DisassemblyPreferenceConstants.SHOW_FUNCTION_OFFSETS);
|
|
554 |
fShowSymbols = prefs.getBoolean(DisassemblyPreferenceConstants.SHOW_SYMBOLS);
|
|
555 |
fUpdateBeforeFocus = !prefs.getBoolean(DisassemblyPreferenceConstants.AVOID_READ_BEFORE_PC);
|
|
556 |
fPCHistorySizeMax = prefs.getInt(DisassemblyPreferenceConstants.PC_HISTORY_SIZE);
|
|
557 |
}
|
|
558 |
|
|
559 |
public void logWarning(String message, Throwable error) {
|
|
560 |
DsfUIPlugin.getDefault().getLog().log(new Status(IStatus.WARNING, DsfUIPlugin.PLUGIN_ID, message, error));
|
|
561 |
}
|
|
562 |
|
|
563 |
/*
|
|
564 |
* @see IAdaptable#getAdapter(java.lang.Class)
|
|
565 |
*/
|
|
566 |
@Override
|
|
567 |
@SuppressWarnings("unchecked")
|
|
568 |
public Object getAdapter(Class required) {
|
|
569 |
if (IVerticalRulerInfo.class.equals(required)) {
|
|
570 |
if (fVerticalRuler != null) {
|
|
571 |
return fVerticalRuler;
|
|
572 |
}
|
|
573 |
} else if (IDisassemblyPart.class.equals(required)) {
|
|
574 |
return this;
|
|
575 |
} else if (IFindReplaceTarget.class.equals(required)) {
|
|
576 |
if (fFindReplaceTarget == null) {
|
|
577 |
fFindReplaceTarget = (fViewer == null ? null : fViewer.getFindReplaceTarget());
|
|
578 |
}
|
|
579 |
return fFindReplaceTarget;
|
|
580 |
} else if (ITextOperationTarget.class.equals(required)) {
|
|
581 |
return (fViewer == null ? null : fViewer.getTextOperationTarget());
|
|
582 |
} else if (Control.class.equals(required)) {
|
|
583 |
return fViewer != null ? fViewer.getTextWidget() : null;
|
|
584 |
} else if (IGotoMarker.class.equals(required)) {
|
|
585 |
return new IGotoMarker() {
|
|
586 |
public void gotoMarker(IMarker marker) {
|
|
587 |
DisassemblyPart.this.gotoMarker(marker);
|
|
588 |
}};
|
|
589 |
} else if (IToggleBreakpointsTarget.class.equals(required)) {
|
|
590 |
return new IToggleBreakpointsTarget() {
|
|
591 |
public void toggleLineBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
|
|
592 |
ITextSelection textSelection = (ITextSelection)selection;
|
|
593 |
int line = textSelection.getStartLine();
|
|
594 |
IBreakpoint[] bp = getBreakpointsAtLine(line);
|
|
595 |
if (bp == null || bp.length == 0) {
|
|
596 |
insertBreakpoint(line, false);
|
|
597 |
} else {
|
|
598 |
for (int i = 0; i < bp.length; i++) {
|
|
599 |
bp[i].delete();
|
|
600 |
}
|
|
601 |
}
|
|
602 |
}
|
|
603 |
public boolean canToggleLineBreakpoints(IWorkbenchPart part, ISelection selection) {
|
|
604 |
return fDebugSessionId != null;
|
|
605 |
}
|
|
606 |
public void toggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
|
|
607 |
}
|
|
608 |
public boolean canToggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) {
|
|
609 |
return false;
|
|
610 |
}
|
|
611 |
public void toggleWatchpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
|
|
612 |
}
|
|
613 |
public boolean canToggleWatchpoints(IWorkbenchPart part, ISelection selection) {
|
|
614 |
return false;
|
|
615 |
}};
|
|
616 |
} else if (IRunToLineTarget.class.equals(required)) {
|
|
617 |
return new IRunToLineTarget() {
|
|
618 |
public void runToLine(IWorkbenchPart part, ISelection selection, ISuspendResume target) throws CoreException {
|
|
619 |
// ITextSelection textSelection = (ITextSelection)selection;
|
|
620 |
// int line = textSelection.getStartLine();
|
|
621 |
// BigInteger address = getAddressOfLine(line);
|
|
622 |
// TLETODO [disassembly] run to line
|
|
623 |
// getRunControl().runUntil(...);
|
|
624 |
}
|
|
625 |
public boolean canRunToLine(IWorkbenchPart part, ISelection selection, ISuspendResume target) {
|
|
626 |
return fTargetContext != null && isSuspended(fTargetContext) ;
|
|
627 |
}};
|
|
628 |
}
|
|
629 |
return super.getAdapter(required);
|
|
630 |
}
|
|
631 |
|
|
632 |
private void setPreferenceStore(IPreferenceStore store) {
|
|
633 |
if (fPreferenceStore != null) {
|
|
634 |
fPreferenceStore.removePropertyChangeListener(fPropertyChangeListener);
|
|
635 |
}
|
|
636 |
|
|
637 |
fPreferenceStore = store;
|
|
638 |
|
|
639 |
if (fPreferenceStore != null) {
|
|
640 |
fPreferenceStore.addPropertyChangeListener(fPropertyChangeListener);
|
|
641 |
}
|
|
642 |
}
|
|
643 |
|
|
644 |
/**
|
|
645 |
* Handles a property change event describing a change of the editor's
|
|
646 |
* preference store and updates the preference related editor properties.
|
|
647 |
* <p>
|
|
648 |
* Subclasses may extend.
|
|
649 |
* </p>
|
|
650 |
*
|
|
651 |
* @param event
|
|
652 |
* the property change event
|
|
653 |
*/
|
|
654 |
protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
|
|
655 |
|
|
656 |
if (fViewer == null)
|
|
657 |
return;
|
|
658 |
|
|
659 |
String property = event.getProperty();
|
|
660 |
IPreferenceStore store = getPreferenceStore();
|
|
661 |
|
|
662 |
if (getFontPropertyPreferenceKey().equals(property)) {
|
|
663 |
initializeViewerFont(fViewer);
|
|
664 |
} else if (property.equals(DisassemblyPreferenceConstants.SHOW_ADDRESS_RULER)) {
|
|
665 |
fActionToggleAddressColumn.update();
|
|
666 |
if (isAddressRulerVisible()) {
|
|
667 |
showAddressRuler();
|
|
668 |
} else {
|
|
669 |
hideAddressRuler();
|
|
670 |
}
|
|
671 |
} else if (property.equals(DisassemblyPreferenceConstants.ADDRESS_RADIX)) {
|
|
672 |
if (fAddressRulerColumn != null) {
|
|
673 |
hideAddressRuler();
|
|
674 |
showAddressRuler();
|
|
675 |
}
|
|
676 |
} else if (property.equals(DisassemblyPreferenceConstants.SHOW_ADDRESS_RADIX)) {
|
|
677 |
if (fAddressRulerColumn != null) {
|
|
678 |
hideAddressRuler();
|
|
679 |
showAddressRuler();
|
|
680 |
}
|
|
681 |
} else if (property.equals(DisassemblyPreferenceConstants.SHOW_SOURCE)) {
|
|
682 |
sourceModeChanged(store.getBoolean(property));
|
|
683 |
} else if (property.equals(DisassemblyPreferenceConstants.INSTRUCTION_RADIX)) {
|
|
684 |
Runnable doit = new Runnable() {
|
|
685 |
public void run() {
|
|
686 |
fDocument.invalidateAddressRange(fStartAddress, fEndAddress, true);
|
|
687 |
if (!fShowDisassembly) {
|
|
688 |
fDocument.invalidateDisassemblyWithSource(true);
|
|
689 |
}
|
|
690 |
fDocument.setMaxOpcodeLength(0);
|
|
691 |
fGotoFramePending = true;
|
|
692 |
}};
|
|
693 |
doScrollLocked(doit);
|
|
694 |
} else if (property.equals(DisassemblyPreferenceConstants.SHOW_SYMBOLS)) {
|
|
695 |
boolean showSymbols = store.getBoolean(property);
|
|
696 |
if (fShowSymbols == showSymbols) {
|
|
697 |
return;
|
|
698 |
}
|
|
699 |
fShowSymbols = showSymbols;
|
|
700 |
Runnable doit = new Runnable() {
|
|
701 |
public void run() {
|
|
702 |
fDocument.invalidateAddressRange(fStartAddress, fEndAddress, true);
|
|
703 |
if (!fShowDisassembly) {
|
|
704 |
fDocument.invalidateDisassemblyWithSource(true);
|
|
705 |
}
|
|
706 |
fGotoFramePending = true;
|
|
707 |
}};
|
|
708 |
doScrollLocked(doit);
|
|
709 |
} else if (property.equals(DisassemblyPreferenceConstants.USE_SOURCE_ONLY_MODE)) {
|
|
710 |
fSourceOnlyMode = store.getBoolean(property);
|
|
711 |
if (fDebugSessionId != null) {
|
|
712 |
disassemblyModeChanged(isDissemblyMixedModeOn());
|
|
713 |
}
|
|
714 |
} else if (property.equals(DisassemblyPreferenceConstants.SHOW_FUNCTION_OFFSETS)) {
|
|
715 |
fShowOpcodes = store.getBoolean(property);
|
|
716 |
fActionToggleFunctionColumn.update();
|
|
717 |
if (isOpcodeRulerVisible()) {
|
|
718 |
showOpcodeRuler();
|
|
719 |
} else {
|
|
720 |
hideOpcodeRuler();
|
|
721 |
}
|
|
722 |
} else if (property.equals(DisassemblyPreferenceConstants.AVOID_READ_BEFORE_PC)) {
|
|
723 |
fUpdateBeforeFocus = !store.getBoolean(property);
|
|
724 |
updateVisibleArea();
|
|
725 |
} else if (property.equals(fPCAnnotationColorKey)) {
|
|
726 |
fPCAnnotationRGB = PreferenceConverter.getColor(store, fPCAnnotationColorKey);
|
|
727 |
// redraw
|
|
728 |
for (Iterator<AddressRangePosition> it=fPCHistory.iterator(); it.hasNext();) {
|
|
729 |
AddressRangePosition pos = it.next();
|
|
730 |
fViewer.invalidateTextPresentation(pos.offset, pos.length);
|
|
731 |
}
|
|
732 |
} else if (property.equals(DisassemblyPreferenceConstants.PC_HISTORY_SIZE)) {
|
|
733 |
fPCHistorySizeMax = store.getInt(property);
|
|
734 |
}
|
|
735 |
}
|
|
736 |
|
|
737 |
/**
|
|
738 |
* This is a callback that will allow us to create the viewer and initialize
|
|
739 |
* it.
|
|
740 |
*/
|
|
741 |
@Override
|
|
742 |
public void createPartControl(Composite parent) {
|
|
743 |
fComposite = parent;
|
|
744 |
FillLayout layout = new FillLayout();
|
|
745 |
layout.marginHeight = 2;
|
|
746 |
parent.setLayout(layout);
|
|
747 |
fVerticalRuler = createVerticalRuler();
|
|
748 |
int styles = SWT.V_SCROLL | SWT.H_SCROLL | SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION;
|
|
749 |
fViewer = new DisassemblyViewer(parent, fVerticalRuler, getOverviewRuler(), true, styles);
|
|
750 |
SourceViewerConfiguration sourceViewerConfig = new DisassemblyViewerConfiguration(this);
|
|
751 |
fViewer.addTextPresentationListener(this);
|
|
752 |
fViewer.configure(sourceViewerConfig);
|
|
753 |
fDecorationSupport = new SourceViewerDecorationSupport(fViewer, getOverviewRuler(), getAnnotationAccess(),
|
|
754 |
getSharedColors());
|
|
755 |
configureSourceViewerDecorationSupport(fDecorationSupport);
|
|
756 |
fDecorationSupport.install(getPreferenceStore());
|
|
757 |
if (fPCAnnotationColorKey != null) {
|
|
758 |
fPCAnnotationRGB = PreferenceConverter.getColor(getPreferenceStore(), fPCAnnotationColorKey);
|
|
759 |
} else {
|
|
760 |
fPCAnnotationRGB = parent.getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION).getRGB();
|
|
761 |
}
|
|
762 |
|
|
763 |
initializeViewerFont(fViewer);
|
|
764 |
createActions();
|
|
765 |
hookRulerContextMenu();
|
|
766 |
hookContextMenu();
|
|
767 |
contributeToActionBars();
|
|
768 |
|
|
769 |
fViewer.addSelectionChangedListener(new ISelectionChangedListener() {
|
|
770 |
public void selectionChanged(SelectionChangedEvent event) {
|
|
771 |
updateSelectionDependentActions();
|
|
772 |
}
|
|
773 |
});
|
|
774 |
|
|
775 |
fDocument = createDocument();
|
|
776 |
fViewer.setDocument(fDocument, new AnnotationModel());
|
|
777 |
JFaceResources.getFontRegistry().addListener(fPropertyChangeListener);
|
|
778 |
|
|
779 |
fErrorColor = getSharedColors().getColor(new RGB(96, 0, 0));
|
|
780 |
fInstructionColor = getSharedColors().getColor(new RGB(0, 0, 96));
|
|
781 |
fSourceColor = getSharedColors().getColor(new RGB(64, 0, 80));
|
|
782 |
fLabelColor = getSharedColors().getColor(new RGB(0, 0, 96));
|
|
783 |
|
|
784 |
if (isAddressRulerVisible()) {
|
|
785 |
showAddressRuler();
|
|
786 |
}
|
|
787 |
if (isOpcodeRulerVisible()) {
|
|
788 |
showOpcodeRuler();
|
|
789 |
}
|
|
790 |
initDragAndDrop();
|
|
791 |
PlatformUI.getWorkbench().getHelpSystem().setHelp(fViewer.getControl(), IDisassemblyHelpContextIds.DISASSEMBLY_VIEW);
|
|
792 |
updateTitle();
|
|
793 |
updateStateDependentActions();
|
|
794 |
|
|
795 |
if (fDebugSessionId != null) {
|
|
796 |
debugContextChanged();
|
|
797 |
} else {
|
|
798 |
updateDebugContext();
|
|
799 |
}
|
|
800 |
DsfSession.addSessionEndedListener(this);
|
|
801 |
}
|
|
802 |
|
|
803 |
/*
|
|
804 |
* @see org.eclipse.ui.part.WorkbenchPart#setSite(org.eclipse.ui.IWorkbenchPartSite)
|
|
805 |
*/
|
|
806 |
@Override
|
|
807 |
protected void setSite(IWorkbenchPartSite site) {
|
|
808 |
super.setSite(site);
|
|
809 |
site.getPage().addPartListener(fPartListener);
|
|
810 |
}
|
|
811 |
|
|
812 |
private DisassemblyDocument createDocument() {
|
|
813 |
DisassemblyDocument doc = new DisassemblyDocument();
|
|
814 |
return doc;
|
|
815 |
}
|
|
816 |
|
|
817 |
/*
|
|
818 |
* @see org.eclipse.ui.IWorkbenchPart#dispose()
|
|
819 |
*/
|
|
820 |
@Override
|
|
821 |
public void dispose() {
|
|
822 |
IWorkbenchPartSite site = getSite();
|
|
823 |
site.setSelectionProvider(null);
|
|
824 |
site.getPage().removePartListener(fPartListener);
|
|
825 |
if (fHandlerActivations != null) {
|
|
826 |
IHandlerService handlerService = (IHandlerService)site.getService(IHandlerService.class);
|
|
827 |
handlerService.deactivateHandlers(fHandlerActivations);
|
|
828 |
fHandlerActivations = null;
|
|
829 |
}
|
|
830 |
if (fContextActivation != null) {
|
|
831 |
IContextService ctxService = (IContextService)site.getService(IContextService.class);
|
|
832 |
ctxService.deactivateContext(fContextActivation);
|
|
833 |
}
|
|
834 |
fViewer = null;
|
|
835 |
setDebugContext(null);
|
|
836 |
DsfSession.removeSessionEndedListener(this);
|
|
837 |
|
|
838 |
fAnnotationAccess = null;
|
|
839 |
fAnnotationPreferences = null;
|
|
840 |
fAnnotationRulerColumn = null;
|
|
841 |
fComposite = null;
|
|
842 |
if (fDecorationSupport != null) {
|
|
843 |
fDecorationSupport.uninstall();
|
|
844 |
fDecorationSupport = null;
|
|
845 |
}
|
|
846 |
if (fFont != null) {
|
|
847 |
fFont.dispose();
|
|
848 |
fFont = null;
|
|
849 |
}
|
|
850 |
if (fDropTarget != null) {
|
|
851 |
fDropTarget.dispose();
|
|
852 |
fDropTarget = null;
|
|
853 |
fDragSource.dispose();
|
|
854 |
fDragSource = null;
|
|
855 |
}
|
|
856 |
if (fPropertyChangeListener != null) {
|
|
857 |
if (fPreferenceStore != null) {
|
|
858 |
fPreferenceStore.removePropertyChangeListener(fPropertyChangeListener);
|
|
859 |
fPreferenceStore = null;
|
|
860 |
}
|
|
861 |
fPropertyChangeListener = null;
|
|
862 |
}
|
|
863 |
|
|
864 |
fDocument.dispose();
|
|
865 |
fDocument = null;
|
|
866 |
super.dispose();
|
|
867 |
}
|
|
868 |
|
|
869 |
private void initDragAndDrop() {
|
|
870 |
if (fDropTarget == null) {
|
|
871 |
Transfer[] dropTypes = new Transfer[] { FileTransfer.getInstance(), TextTransfer.getInstance() };
|
|
872 |
Transfer[] dragTypes = new Transfer[] { TextTransfer.getInstance() };
|
|
873 |
Control dropControl = getSourceViewer().getTextWidget();
|
|
874 |
Control dragControl = dropControl;
|
|
875 |
int dropOps = DND.DROP_COPY | DND.DROP_DEFAULT;
|
|
876 |
int dragOps = DND.DROP_COPY | DND.DROP_DEFAULT;
|
|
877 |
|
|
878 |
fDropTarget = new DropTarget(dropControl, dropOps);
|
|
879 |
fDropTarget.setTransfer(dropTypes);
|
|
880 |
fDropTargetAdapter = new DisassemblyDropAdapter(this);
|
|
881 |
fDropTarget.addDropListener(fDropTargetAdapter);
|
|
882 |
|
|
883 |
fDragSource = new DragSource(dragControl, dragOps);
|
|
884 |
fDragSource.setTransfer(dragTypes);
|
|
885 |
fDragSourceAdapter = new TextViewerDragAdapter(getSourceViewer());
|
|
886 |
fDragSource.addDragListener(fDragSourceAdapter);
|
|
887 |
}
|
|
888 |
}
|
|
889 |
|
|
890 |
private ISourceViewer getSourceViewer() {
|
|
891 |
return fViewer;
|
|
892 |
}
|
|
893 |
|
|
894 |
protected void configureSourceViewerDecorationSupport(SourceViewerDecorationSupport support) {
|
|
895 |
Iterator<?> e = fAnnotationPreferences.getAnnotationPreferences().iterator();
|
|
896 |
while (e.hasNext()) {
|
|
897 |
AnnotationPreference pref = (AnnotationPreference)e.next();
|
|
898 |
support.setAnnotationPreference(pref);
|
|
899 |
if (pref.getAnnotationType().equals(fPCAnnotation.getType())) {
|
|
900 |
fPCAnnotationColorKey = pref.getColorPreferenceKey();
|
|
901 |
}
|
|
902 |
}
|
|
903 |
support.setCursorLinePainterPreferenceKeys(CURRENT_LINE, CURRENT_LINE_COLOR);
|
|
904 |
support.setSymbolicFontName(getFontPropertyPreferenceKey());
|
|
905 |
}
|
|
906 |
|
|
907 |
/**
|
|
908 |
* Returns the symbolic font name for this view as defined in XML.
|
|
909 |
*
|
|
910 |
* @return a String with the symbolic font name or <code>null</code> if
|
|
911 |
* none is defined
|
|
912 |
*/
|
|
913 |
private String getSymbolicFontName() {
|
|
914 |
if (getConfigurationElement() != null)
|
|
915 |
return getConfigurationElement().getAttribute("symbolicFontName"); //$NON-NLS-1$
|
|
916 |
else
|
|
917 |
return null;
|
|
918 |
}
|
|
919 |
|
|
920 |
protected final String getFontPropertyPreferenceKey() {
|
|
921 |
String symbolicFontName = getSymbolicFontName();
|
|
922 |
|
|
923 |
if (symbolicFontName != null)
|
|
924 |
return symbolicFontName;
|
|
925 |
else
|
|
926 |
return JFaceResources.TEXT_FONT;
|
|
927 |
}
|
|
928 |
|
|
929 |
/**
|
|
930 |
* Initializes the given viewer's font.
|
|
931 |
*
|
|
932 |
* @param viewer
|
|
933 |
* the viewer
|
|
934 |
*/
|
|
935 |
private void initializeViewerFont(ISourceViewer viewer) {
|
|
936 |
|
|
937 |
boolean isSharedFont = true;
|
|
938 |
Font font = null;
|
|
939 |
String symbolicFontName = getSymbolicFontName();
|
|
940 |
|
|
941 |
if (symbolicFontName != null)
|
|
942 |
font = JFaceResources.getFont(symbolicFontName);
|
|
943 |
else if (fPreferenceStore != null) {
|
|
944 |
// Backward compatibility
|
|
945 |
if (fPreferenceStore.contains(JFaceResources.TEXT_FONT)
|
|
946 |
&& !fPreferenceStore.isDefault(JFaceResources.TEXT_FONT)) {
|
|
947 |
FontData data = PreferenceConverter.getFontData(fPreferenceStore, JFaceResources.TEXT_FONT);
|
|
948 |
|
|
949 |
if (data != null) {
|
|
950 |
isSharedFont = false;
|
|
951 |
font = new Font(viewer.getTextWidget().getDisplay(), data);
|
|
952 |
}
|
|
953 |
}
|
|
954 |
}
|
|
955 |
if (font == null)
|
|
956 |
font = JFaceResources.getTextFont();
|
|
957 |
|
|
958 |
setFont(viewer, font);
|
|
959 |
|
|
960 |
if (fFont != null) {
|
|
961 |
fFont.dispose();
|
|
962 |
fFont = null;
|
|
963 |
}
|
|
964 |
|
|
965 |
if (!isSharedFont)
|
|
966 |
fFont = font;
|
|
967 |
}
|
|
968 |
|
|
969 |
/**
|
|
970 |
* Sets the font for the given viewer sustaining selection and scroll
|
|
971 |
* position.
|
|
972 |
*
|
|
973 |
* @param sourceViewer
|
|
974 |
* the source viewer
|
|
975 |
* @param font
|
|
976 |
* the font
|
|
977 |
*/
|
|
978 |
private void setFont(ISourceViewer sourceViewer, Font font) {
|
|
979 |
if (sourceViewer.getDocument() != null) {
|
|
980 |
|
|
981 |
Point selection = sourceViewer.getSelectedRange();
|
|
982 |
int topIndex = sourceViewer.getTopIndex();
|
|
983 |
|
|
984 |
StyledText styledText = sourceViewer.getTextWidget();
|
|
985 |
Control parent = styledText;
|
|
986 |
if (sourceViewer instanceof ITextViewerExtension) {
|
|
987 |
ITextViewerExtension extension = (ITextViewerExtension) sourceViewer;
|
|
988 |
parent = extension.getControl();
|
|
989 |
}
|
|
990 |
|
|
991 |
parent.setRedraw(false);
|
|
992 |
|
|
993 |
styledText.setFont(font);
|
|
994 |
|
|
995 |
if (fVerticalRuler instanceof IVerticalRulerExtension) {
|
|
996 |
IVerticalRulerExtension e = (IVerticalRulerExtension) fVerticalRuler;
|
|
997 |
e.setFont(font);
|
|
998 |
}
|
|
999 |
|
|
1000 |
sourceViewer.setSelectedRange(selection.x, selection.y);
|
|
1001 |
sourceViewer.setTopIndex(topIndex);
|
|
1002 |
|
|
1003 |
if (parent instanceof Composite) {
|
|
1004 |
Composite composite = (Composite) parent;
|
|
1005 |
composite.layout(true);
|
|
1006 |
}
|
|
1007 |
|
|
1008 |
parent.setRedraw(true);
|
|
1009 |
|
|
1010 |
} else {
|
|
1011 |
|
|
1012 |
StyledText styledText = sourceViewer.getTextWidget();
|
|
1013 |
styledText.setFont(font);
|
|
1014 |
|
|
1015 |
if (fVerticalRuler instanceof IVerticalRulerExtension) {
|
|
1016 |
IVerticalRulerExtension e = (IVerticalRulerExtension) fVerticalRuler;
|
|
1017 |
e.setFont(font);
|
|
1018 |
}
|
|
1019 |
}
|
|
1020 |
}
|
|
1021 |
|
|
1022 |
protected IVerticalRuler createVerticalRuler() {
|
|
1023 |
CompositeRuler ruler = createCompositeRuler();
|
|
1024 |
IPreferenceStore store = getPreferenceStore();
|
|
1025 |
if (ruler != null && store != null) {
|
|
1026 |
for (Iterator<?> iter = ruler.getDecoratorIterator(); iter.hasNext();) {
|
|
1027 |
IVerticalRulerColumn column = (IVerticalRulerColumn) iter.next();
|
|
1028 |
if (column instanceof AnnotationRulerColumn) {
|
|
1029 |
fAnnotationRulerColumn = (AnnotationRulerColumn) column;
|
|
1030 |
for (Iterator<?> iter2 = fAnnotationPreferences.getAnnotationPreferences().iterator(); iter2.hasNext();) {
|
|
1031 |
AnnotationPreference preference = (AnnotationPreference) iter2.next();
|
|
1032 |
String key = preference.getVerticalRulerPreferenceKey();
|
|
1033 |
boolean showAnnotation = true;
|
|
1034 |
if (key != null && store.contains(key))
|
|
1035 |
showAnnotation = store.getBoolean(key);
|
|
1036 |
if (showAnnotation)
|
|
1037 |
fAnnotationRulerColumn.addAnnotationType(preference.getAnnotationType());
|
|
1038 |
}
|
|
1039 |
fAnnotationRulerColumn.addAnnotationType(Annotation.TYPE_UNKNOWN);
|
|
1040 |
break;
|
|
1041 |
}
|
|
1042 |
}
|
|
1043 |
}
|
|
1044 |
return ruler;
|
|
1045 |
}
|
|
1046 |
|
|
1047 |
/**
|
|
1048 |
* Returns the vertical ruler.
|
|
1049 |
*
|
|
1050 |
* @return the vertical ruler
|
|
1051 |
*/
|
|
1052 |
protected IVerticalRuler getVerticalRuler() {
|
|
1053 |
return fVerticalRuler;
|
|
1054 |
}
|
|
1055 |
|
|
1056 |
/**
|
|
1057 |
* Returns the overview ruler.
|
|
1058 |
*
|
|
1059 |
* @return the overview ruler
|
|
1060 |
*/
|
|
1061 |
protected IOverviewRuler getOverviewRuler() {
|
|
1062 |
if (fOverviewRuler == null)
|
|
1063 |
fOverviewRuler = createOverviewRuler(getSharedColors());
|
|
1064 |
return fOverviewRuler;
|
|
1065 |
}
|
|
1066 |
|
|
1067 |
protected ISharedTextColors getSharedColors() {
|
|
1068 |
return EditorsUI.getSharedTextColors();
|
|
1069 |
}
|
|
1070 |
|
|
1071 |
protected IOverviewRuler createOverviewRuler(ISharedTextColors sharedColors) {
|
|
1072 |
IOverviewRuler ruler = new OverviewRuler(getAnnotationAccess(), VERTICAL_RULER_WIDTH, sharedColors);
|
|
1073 |
Iterator<?> e = fAnnotationPreferences.getAnnotationPreferences().iterator();
|
|
1074 |
while (e.hasNext()) {
|
|
1075 |
AnnotationPreference preference = (AnnotationPreference) e.next();
|
|
1076 |
if (preference.contributesToHeader())
|
|
1077 |
ruler.addHeaderAnnotationType(preference.getAnnotationType());
|
|
1078 |
}
|
|
1079 |
return ruler;
|
|
1080 |
}
|
|
1081 |
|
|
1082 |
/**
|
|
1083 |
* Creates a new address ruler column that is appropriately initialized.
|
|
1084 |
*
|
|
1085 |
* @return the created line number column
|
|
1086 |
*/
|
|
1087 |
protected IVerticalRulerColumn createAddressRulerColumn() {
|
|
1088 |
fAddressRulerColumn= new AddressRulerColumn();
|
|
1089 |
initializeRulerColumn(fAddressRulerColumn, DisassemblyPreferenceConstants.ADDRESS_COLOR);
|
|
1090 |
IPreferenceStore prefs = getPreferenceStore();
|
|
1091 |
fAddressRulerColumn.setRadix(prefs.getInt(DisassemblyPreferenceConstants.ADDRESS_RADIX));
|
|
1092 |
fAddressRulerColumn.setShowRadixPrefix(prefs.getBoolean(DisassemblyPreferenceConstants.SHOW_ADDRESS_RADIX));
|
|
1093 |
return fAddressRulerColumn;
|
|
1094 |
}
|
|
1095 |
|
|
1096 |
/**
|
|
1097 |
* Creates a new ruler column that is appropriately initialized.
|
|
1098 |
*
|
|
1099 |
* @return the created line number column
|
|
1100 |
*/
|
|
1101 |
protected IVerticalRulerColumn createOpcodeRulerColumn() {
|
|
1102 |
fOpcodeRulerColumn= new FunctionOffsetRulerColumn();
|
|
1103 |
initializeRulerColumn(fOpcodeRulerColumn, DisassemblyPreferenceConstants.OPCODE_COLOR);
|
|
1104 |
return fOpcodeRulerColumn;
|
|
1105 |
}
|
|
1106 |
|
|
1107 |
/**
|
|
1108 |
* Initializes the given address ruler column from the preference store.
|
|
1109 |
*
|
|
1110 |
* @param rulerColumn the ruler column to be initialized
|
|
1111 |
*/
|
|
1112 |
protected void initializeRulerColumn(DisassemblyRulerColumn rulerColumn, String colorPrefKey) {
|
|
1113 |
ISharedTextColors sharedColors= getSharedColors();
|
|
1114 |
IPreferenceStore store= getPreferenceStore();
|
|
1115 |
if (store != null) {
|
|
1116 |
|
|
1117 |
RGB rgb= null;
|
|
1118 |
// foreground color
|
|
1119 |
if (store.contains(colorPrefKey)) {
|
|
1120 |
if (store.isDefault(colorPrefKey))
|
|
1121 |
rgb= PreferenceConverter.getDefaultColor(store, colorPrefKey);
|
|
1122 |
else
|
|
1123 |
rgb= PreferenceConverter.getColor(store, colorPrefKey);
|
|
1124 |
}
|
|
1125 |
if (rgb == null)
|
|
1126 |
rgb= new RGB(0, 0, 0);
|
|
1127 |
rulerColumn.setForeground(sharedColors.getColor(rgb));
|
|
1128 |
|
|
1129 |
rgb= null;
|
|
1130 |
|
|
1131 |
rulerColumn.redraw();
|
|
1132 |
}
|
|
1133 |
}
|
|
1134 |
|
|
1135 |
|
|
1136 |
/**
|
|
1137 |
* @return the preference store
|
|
1138 |
*/
|
|
1139 |
private IPreferenceStore getPreferenceStore() {
|
|
1140 |
return fPreferenceStore;
|
|
1141 |
}
|
|
1142 |
|
|
1143 |
/**
|
|
1144 |
* Creates a composite ruler to be used as the vertical ruler by this
|
|
1145 |
* editor. Subclasses may re-implement this method.
|
|
1146 |
*
|
|
1147 |
* @return the vertical ruler
|
|
1148 |
*/
|
|
1149 |
protected CompositeRuler createCompositeRuler() {
|
|
1150 |
CompositeRuler ruler = new CompositeRuler();
|
|
1151 |
ruler.addDecorator(0, new AnnotationRulerColumn(VERTICAL_RULER_WIDTH, getAnnotationAccess()));
|
|
1152 |
return ruler;
|
|
1153 |
}
|
|
1154 |
|
|
1155 |
private boolean isAddressRulerVisible() {
|
|
1156 |
return getPreferenceStore().getBoolean(DisassemblyPreferenceConstants.SHOW_ADDRESS_RULER);
|
|
1157 |
}
|
|
1158 |
|
|
1159 |
/**
|
|
1160 |
* Shows the address ruler column.
|
|
1161 |
*/
|
|
1162 |
private void showAddressRuler() {
|
|
1163 |
if (fAddressRulerColumn == null) {
|
|
1164 |
IVerticalRuler v= getVerticalRuler();
|
|
1165 |
if (v instanceof CompositeRuler) {
|
|
1166 |
CompositeRuler c= (CompositeRuler) v;
|
|
1167 |
c.addDecorator(1, createAddressRulerColumn());
|
|
1168 |
}
|
|
1169 |
}
|
|
1170 |
}
|
|
1171 |
|
|
1172 |
/**
|
|
1173 |
* Hides the address ruler column.
|
|
1174 |
*/
|
|
1175 |
private void hideAddressRuler() {
|
|
1176 |
if (fAddressRulerColumn != null) {
|
|
1177 |
IVerticalRuler v= getVerticalRuler();
|
|
1178 |
if (v instanceof CompositeRuler) {
|
|
1179 |
CompositeRuler c= (CompositeRuler) v;
|
|
1180 |
c.removeDecorator(fAddressRulerColumn);
|
|
1181 |
}
|
|
1182 |
fAddressRulerColumn = null;
|
|
1183 |
}
|
|
1184 |
}
|
|
1185 |
|
|
1186 |
private boolean isOpcodeRulerVisible() {
|
|
1187 |
return fShowOpcodes;
|
|
1188 |
}
|
|
1189 |
|
|
1190 |
/**
|
|
1191 |
* Shows the opcode ruler column.
|
|
1192 |
*/
|
|
1193 |
private void showOpcodeRuler() {
|
|
1194 |
if (fOpcodeRulerColumn == null) {
|
|
1195 |
IVerticalRuler v= getVerticalRuler();
|
|
1196 |
if (v instanceof CompositeRuler) {
|
|
1197 |
CompositeRuler c= (CompositeRuler) v;
|
|
1198 |
c.addDecorator(2, createOpcodeRulerColumn());
|
|
1199 |
}
|
|
1200 |
}
|
|
1201 |
}
|
|
1202 |
|
|
1203 |
/**
|
|
1204 |
* Hides the opcode ruler column.
|
|
1205 |
*/
|
|
1206 |
private void hideOpcodeRuler() {
|
|
1207 |
if (fOpcodeRulerColumn != null) {
|
|
1208 |
IVerticalRuler v= getVerticalRuler();
|
|
1209 |
if (v instanceof CompositeRuler) {
|
|
1210 |
CompositeRuler c= (CompositeRuler) v;
|
|
1211 |
c.removeDecorator(fOpcodeRulerColumn);
|
|
1212 |
}
|
|
1213 |
fOpcodeRulerColumn = null;
|
|
1214 |
}
|
|
1215 |
}
|
|
1216 |
|
|
1217 |
/**
|
|
1218 |
* Returns the annotation access.
|
|
1219 |
*
|
|
1220 |
* @return the annotation access
|
|
1221 |
*/
|
|
1222 |
protected IAnnotationAccess getAnnotationAccess() {
|
|
1223 |
if (fAnnotationAccess == null)
|
|
1224 |
fAnnotationAccess = createAnnotationAccess();
|
|
1225 |
return fAnnotationAccess;
|
|
1226 |
}
|
|
1227 |
|
|
1228 |
/**
|
|
1229 |
* Creates the annotation access for this editor.
|
|
1230 |
*
|
|
1231 |
* @return the created annotation access
|
|
1232 |
*/
|
|
1233 |
protected IAnnotationAccess createAnnotationAccess() {
|
|
1234 |
return new DefaultMarkerAnnotationAccess();
|
|
1235 |
}
|
|
1236 |
|
|
1237 |
private void hookContextMenu() {
|
|
1238 |
String id = "#DisassemblyPartContext"; //$NON-NLS-1$
|
|
1239 |
MenuManager menuMgr = new MenuManager(id, id);
|
|
1240 |
menuMgr.setRemoveAllWhenShown(true);
|
|
1241 |
menuMgr.addMenuListener(new IMenuListener() {
|
|
1242 |
public void menuAboutToShow(IMenuManager manager) {
|
|
1243 |
DisassemblyPart.this.fillContextMenu(manager);
|
|
1244 |
}
|
|
1245 |
});
|
|
1246 |
Menu menu = menuMgr.createContextMenu(fViewer.getTextWidget());
|
|
1247 |
fViewer.getTextWidget().setMenu(menu);
|
|
1248 |
getSite().registerContextMenu(id, menuMgr, fViewer);
|
|
1249 |
}
|
|
1250 |
|
|
1251 |
private void hookRulerContextMenu() {
|
|
1252 |
String id = "#DisassemblyPartRulerContext"; //$NON-NLS-1$
|
|
1253 |
MenuManager menuMgr = new MenuManager(id, id);
|
|
1254 |
menuMgr.setRemoveAllWhenShown(true);
|
|
1255 |
menuMgr.addMenuListener(new IMenuListener() {
|
|
1256 |
public void menuAboutToShow(IMenuManager manager) {
|
|
1257 |
DisassemblyPart.this.fillRulerContextMenu(manager);
|
|
1258 |
}
|
|
1259 |
});
|
|
1260 |
Menu menu = menuMgr.createContextMenu(fVerticalRuler.getControl());
|
|
1261 |
fVerticalRuler.getControl().setMenu(menu);
|
|
1262 |
getSite().registerContextMenu(id, menuMgr, fViewer);
|
|
1263 |
}
|
|
1264 |
|
|
1265 |
private void contributeToActionBars() {
|
|
1266 |
IWorkbenchPartSite site = getSite();
|
|
1267 |
site.setSelectionProvider(fViewer);
|
|
1268 |
IContextService ctxService = (IContextService)site.getService(IContextService.class);
|
|
1269 |
fContextActivation = ctxService.activateContext(KEY_BINDING_CONTEXT_DISASSEMBLY);
|
|
1270 |
contributeToActionBars(getActionBars());
|
|
1271 |
}
|
|
1272 |
|
|
1273 |
protected abstract IActionBars getActionBars();
|
|
1274 |
|
|
1275 |
protected void contributeToActionBars(IActionBars bars) {
|
|
1276 |
for (Iterator<String> iter = fGlobalActions.keySet().iterator(); iter.hasNext();) {
|
|
1277 |
String key = iter.next();
|
|
1278 |
IAction action = fGlobalActions.get(key);
|
|
1279 |
bars.setGlobalActionHandler(key, action);
|
|
1280 |
}
|
|
1281 |
IMenuManager menu = bars.getMenuManager();
|
|
1282 |
IMenuManager navigateMenu= menu.findMenuUsingPath(IWorkbenchActionConstants.M_NAVIGATE);
|
|
1283 |
if (navigateMenu != null) {
|
|
1284 |
navigateMenu.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, fActionGotoPC);
|
|
1285 |
navigateMenu.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, fActionGotoAddress);
|
|
1286 |
navigateMenu.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, fActionGotoSymbol);
|
|
1287 |
}
|
|
1288 |
bars.updateActionBars();
|
|
1289 |
}
|
|
1290 |
|
|
1291 |
protected void fillContextMenu(IMenuManager manager) {
|
|
1292 |
Point cursorLoc = getSite().getShell().getDisplay().getCursorLocation();
|
|
1293 |
fViewer.getTextWidget().toControl(cursorLoc);
|
|
1294 |
fActionToggleSource.update();
|
|
1295 |
fActionToggleSymbols.update();
|
|
1296 |
manager.add(new GroupMarker("group.top")); // ICommonMenuConstants.GROUP_TOP //$NON-NLS-1$
|
|
1297 |
manager.add(new Separator("group.breakpoints")); //$NON-NLS-1$
|
|
1298 |
manager.add(new Separator(IWorkbenchActionConstants.GO_TO));
|
|
1299 |
manager.add(fActionGotoPC);
|
|
1300 |
manager.add(fActionGotoAddress);
|
|
1301 |
manager.add(fActionGotoSymbol);
|
|
1302 |
manager.add(new Separator("group.debug")); //$NON-NLS-1$
|
|
1303 |
manager.add(new Separator(ITextEditorActionConstants.GROUP_EDIT));
|
|
1304 |
manager.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, fGlobalActions.get(ITextEditorActionConstants.COPY));
|
|
1305 |
manager.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, fGlobalActions.get(ITextEditorActionConstants.SELECT_ALL));
|
|
1306 |
manager.add(new Separator(ITextEditorActionConstants.GROUP_SETTINGS));
|
|
1307 |
manager.add(fActionToggleSource);
|
|
1308 |
manager.add(fActionToggleSymbols);
|
|
1309 |
manager.add(fActionOpenPreferences);
|
|
1310 |
manager.add(new Separator());
|
|
1311 |
manager.add(fActionRefreshView);
|
|
1312 |
// Other plug-ins can contribute their actions here
|
|
1313 |
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
|
|
1314 |
}
|
|
1315 |
|
|
1316 |
protected void fillRulerContextMenu(IMenuManager manager) {
|
|
1317 |
fActionToggleBreakpoint.update();
|
|
1318 |
fActionToggleBreakpointEnablement.update();
|
|
1319 |
fActionToggleAddressColumn.update();
|
|
1320 |
fActionToggleFunctionColumn.update();
|
|
1321 |
|
|
1322 |
manager.add(new GroupMarker("group.top")); // ICommonMenuConstants.GROUP_TOP //$NON-NLS-1$
|
|
1323 |
manager.add(new Separator("group.breakpoints")); //$NON-NLS-1$
|
|
1324 |
manager.add(fActionToggleBreakpoint);
|
|
1325 |
manager.add(fActionToggleBreakpointEnablement);
|
|
1326 |
manager.add(new GroupMarker("debug")); //$NON-NLS-1$
|
|
1327 |
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
|
|
1328 |
manager.add(new GroupMarker(ITextEditorActionConstants.GROUP_RESTORE));
|
|
1329 |
manager.add(new Separator("add")); //$NON-NLS-1$
|
|
1330 |
manager.add(new Separator(ITextEditorActionConstants.GROUP_RULERS));
|
|
1331 |
manager.add(fActionToggleAddressColumn);
|
|
1332 |
manager.add(fActionToggleFunctionColumn);
|
|
1333 |
manager.add(new Separator(ITextEditorActionConstants.GROUP_REST));
|
|
1334 |
|
|
1335 |
for (Object listener : fRulerContextMenuListeners.getListeners())
|
|
1336 |
((IMenuListener) listener).menuAboutToShow(manager);
|
|
1337 |
|
|
1338 |
manager.add(new Separator(ITextEditorActionConstants.GROUP_EDIT));
|
|
1339 |
manager.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, fGlobalActions.get(ITextEditorActionConstants.COPY));
|
|
1340 |
}
|
|
1341 |
|
|
1342 |
protected void fillLocalToolBar(IToolBarManager manager) {
|
|
1343 |
manager.add(fActionGotoPC);
|
|
1344 |
manager.add(fActionGotoAddress);
|
|
1345 |
}
|
|
1346 |
|
|
1347 |
protected void updateSelectionDependentActions() {
|
|
1348 |
Iterator<Action> iterator= fSelectionActions.iterator();
|
|
1349 |
while (iterator.hasNext()) {
|
|
1350 |
IUpdate action = (IUpdate)iterator.next();
|
|
1351 |
action.update();
|
|
1352 |
}
|
|
1353 |
}
|
|
1354 |
|
|
1355 |
protected void updateStateDependentActions() {
|
|
1356 |
Iterator<AbstractDisassemblyAction> iterator= fStateDependentActions.iterator();
|
|
1357 |
while (iterator.hasNext()) {
|
|
1358 |
IUpdate action = iterator.next();
|
|
1359 |
action.update();
|
|
1360 |
}
|
|
1361 |
}
|
|
1362 |
|
|
1363 |
protected void createActions() {
|
|
1364 |
Action action;
|
|
1365 |
action= new TextOperationAction(fViewer, ITextOperationTarget.COPY);
|
|
1366 |
action.setText(DisassemblyMessages.Disassembly_action_Copy_label);
|
|
1367 |
action.setImageDescriptor(DisassemblyImageRegistry.getImageDescriptor(DisassemblyImageRegistry.ICON_Copy_enabled));
|
|
1368 |
action.setDisabledImageDescriptor(DisassemblyImageRegistry.getImageDescriptor(DisassemblyImageRegistry.ICON_Copy_disabled));
|
|
1369 |
action.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_COPY);
|
|
1370 |
fGlobalActions.put(ITextEditorActionConstants.COPY, action);
|
|
1371 |
fSelectionActions.add(action);
|
|
1372 |
|
|
1373 |
action= new TextOperationAction(fViewer, ITextOperationTarget.SELECT_ALL);
|
|
1374 |
action.setText(DisassemblyMessages.Disassembly_action_SelectAll_label);
|
|
1375 |
action.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_SELECT_ALL);
|
|
1376 |
fGlobalActions.put(ITextEditorActionConstants.SELECT_ALL, action);
|
|
1377 |
|
|
1378 |
action= new TextOperationAction(fViewer, ITextOperationTarget.PRINT);
|
|
1379 |
action.setActionDefinitionId(IWorkbenchCommandConstants.FILE_PRINT);
|
|
1380 |
fGlobalActions.put(ITextEditorActionConstants.PRINT, action);
|
|
1381 |
|
|
1382 |
fActionGotoPC = new ActionGotoProgramCounter(this);
|
|
1383 |
fActionGotoPC.setActionDefinitionId(COMMAND_ID_GOTO_PC);
|
|
1384 |
fStateDependentActions.add(fActionGotoPC);
|
|
1385 |
registerWithHandlerService(fActionGotoPC);
|
|
1386 |
|
|
1387 |
fActionGotoAddress = new ActionGotoAddress(this);
|
|
1388 |
fActionGotoAddress.setActionDefinitionId(COMMAND_ID_GOTO_ADDRESS);
|
|
1389 |
fStateDependentActions.add(fActionGotoAddress);
|
|
1390 |
registerWithHandlerService(fActionGotoAddress);
|
|
1391 |
|
|
1392 |
fActionGotoSymbol = new ActionGotoSymbol(this);
|
|
1393 |
fActionGotoSymbol.setActionDefinitionId(COMMAND_ID_GOTO_SYMBOL);
|
|
1394 |
fStateDependentActions.add(fActionGotoSymbol);
|
|
1395 |
registerWithHandlerService(fActionGotoSymbol);
|
|
1396 |
|
|
1397 |
fActionToggleSource = new ActionToggleSource();
|
|
1398 |
fStateDependentActions.add(fActionToggleSource);
|
|
1399 |
fActionToggleBreakpoint = new ActionToggleBreakpoint();
|
|
1400 |
// fActionToggleBreakpoint.setActionDefinitionId(COMMAND_ID_TOGGLE_BREAKPOINT);
|
|
1401 |
// registerWithHandlerService(fActionToggleBreakpoint);
|
|
1402 |
fVerticalRuler.getControl().addMouseListener(new MouseAdapter() {
|
|
1403 |
@Override
|
|
1404 |
public void mouseDoubleClick(MouseEvent e) {
|
|
1405 |
fActionToggleBreakpoint.update();
|
|
1406 |
if (fActionToggleBreakpoint.isEnabled()) {
|
|
1407 |
fActionToggleBreakpoint.run();
|
|
1408 |
}
|
|
1409 |
}
|
|
1410 |
});
|
|
1411 |
fActionToggleBreakpointEnablement = new ActionToggleBreakpointEnablement();
|
|
1412 |
fActionToggleAddressColumn = new ActionToggleAddressColumn();
|
|
1413 |
fActionToggleFunctionColumn = new ActionToggleFunctionColumn();
|
|
1414 |
fActionToggleSymbols = new ActionToggleSymbols();
|
|
1415 |
// fActionSourceSteppingMode.setActionDefinitionId(COMMAND_ID_TOGGLE_STEPPING_MODE);
|
|
1416 |
// registerWithHandlerService(fActionSourceSteppingMode);
|
|
1417 |
fActionRefreshView = new ActionRefreshView();
|
|
1418 |
fStateDependentActions.add(fActionRefreshView);
|
|
1419 |
fGlobalActions.put(ActionFactory.REFRESH.getId(), fActionRefreshView);
|
|
1420 |
fActionOpenPreferences = new ActionOpenPreferences(getSite().getShell());
|
|
1421 |
}
|
|
1422 |
|
|
1423 |
/**
|
|
1424 |
* Register given action with the handler service for key bindings.
|
|
1425 |
*
|
|
1426 |
* @param action
|
|
1427 |
*/
|
|
1428 |
private void registerWithHandlerService(IAction action) {
|
|
1429 |
if (fHandlerActivations == null) {
|
|
1430 |
fHandlerActivations = new ArrayList<IHandlerActivation>(5);
|
|
1431 |
}
|
|
1432 |
IHandlerService handlerService = (IHandlerService)getSite().getService(IHandlerService.class);
|
|
1433 |
fHandlerActivations.add(handlerService.activateHandler(action.getActionDefinitionId(), new ActionHandler(action)));
|
|
1434 |
}
|
|
1435 |
|
|
1436 |
private void gotoFrame(IFrameDMContext frame) {
|
|
1437 |
if (fActive) {
|
|
1438 |
gotoFrame(frame.getLevel(), PC_UNKNOWN);
|
|
1439 |
}
|
|
1440 |
}
|
|
1441 |
|
|
1442 |
private void gotoFrame(int frame) {
|
|
1443 |
if (fActive) {
|
|
1444 |
gotoFrame(frame, PC_UNKNOWN);
|
|
1445 |
}
|
|
1446 |
}
|
|
1447 |
|
|
1448 |
/*
|
|
1449 |
* @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyPart#gotoProgramCounter()
|
|
1450 |
*/
|
|
1451 |
public final void gotoProgramCounter() {
|
|
1452 |
if (fPCAddress != PC_RUNNING) {
|
|
1453 |
updatePC(fPCAddress);
|
|
1454 |
}
|
|
1455 |
}
|
|
1456 |
|
|
1457 |
/*
|
|
1458 |
* @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyPart#gotoAddress(java.math.BigInteger)
|
|
1459 |
*/
|
|
1460 |
public final void gotoAddress(BigInteger address) {
|
|
1461 |
fFocusAddress = address;
|
|
1462 |
if (fDebugSessionId == null) {
|
|
1463 |
return;
|
|
1464 |
}
|
|
1465 |
if (DEBUG) System.out.println("gotoAddress " + getAddressText(address)); //$NON-NLS-1$
|
|
1466 |
if (fGotoAddressPending == PC_UNKNOWN) {
|
|
1467 |
fGotoAddressPending = address;
|
|
1468 |
}
|
|
1469 |
if (fUpdatePending) {
|
|
1470 |
return;
|
|
1471 |
}
|
|
1472 |
AddressRangePosition pos = getPositionOfAddress(address);
|
|
1473 |
if (pos != null) {
|
|
1474 |
if (pos.fValid) {
|
|
1475 |
AddressRangePosition previousPos = /* fUpdateBeforeFocus ? getPositionOfAddress(pos.fAddressOffset-1): */ null;
|
|
1476 |
if (previousPos == null || previousPos.fValid) {
|
|
1477 |
if (fGotoAddressPending.equals(address)) {
|
|
1478 |
fGotoAddressPending = PC_UNKNOWN;
|
|
1479 |
}
|
|
1480 |
gotoPosition(pos, false);
|
|
1481 |
} else {
|
|
1482 |
int lines = fBufferZone+3;
|
|
1483 |
BigInteger endAddress = pos.fAddressOffset;
|
|
1484 |
BigInteger startAddress = previousPos.fAddressOffset.max(
|
|
1485 |
endAddress.subtract(BigInteger.valueOf(lines * fDocument.getMeanSizeOfInstructions())));
|
|
1486 |
retrieveDisassembly(startAddress, endAddress, lines);
|
|
1487 |
}
|
|
1488 |
} else {
|
|
1489 |
int lines = fBufferZone+3;
|
|
1490 |
BigInteger endAddress = pos.fAddressOffset.add(pos.fAddressLength).min(
|
|
1491 |
address.add(BigInteger.valueOf(lines * fDocument.getMeanSizeOfInstructions())));
|
|
1492 |
retrieveDisassembly(address, endAddress, lines);
|
|
1493 |
}
|
|
1494 |
}
|
|
1495 |
}
|
|
1496 |
|
|
1497 |
/*
|
|
1498 |
* @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyPart#gotoSymbol(java.lang.String)
|
|
1499 |
*/
|
|
1500 |
public final void gotoSymbol(final String symbol) {
|
|
1501 |
if (!fActive || fTargetFrameContext == null) {
|
|
1502 |
return;
|
|
1503 |
}
|
|
1504 |
final DsfExecutor executor= getSession().getExecutor();
|
|
1505 |
executor.execute(new DsfRunnable() {
|
|
1506 |
public void run() {
|
|
1507 |
final IExpressions expressions= getService(IExpressions.class);
|
|
1508 |
if (expressions == null) {
|
|
1509 |
return;
|
|
1510 |
}
|
|
1511 |
IExpressionDMContext exprDmc= expressions.createExpression(fTargetContext, '&'+symbol);
|
|
1512 |
final FormattedValueDMContext valueDmc= expressions.getFormattedValueContext(exprDmc, IFormattedValues.HEX_FORMAT);
|
|
1513 |
expressions.getFormattedExpressionValue(valueDmc, new DataRequestMonitor<FormattedValueDMData>(executor, null) {
|
|
1514 |
@Override
|
|
1515 |
protected void handleSuccess() {
|
|
1516 |
FormattedValueDMData data= getData();
|
|
1517 |
final String value= data.getFormattedValue();
|
|
1518 |
final BigInteger address= decodeAddress(value);
|
|
1519 |
if (address != null) {
|
|
1520 |
asyncExec(new Runnable() {
|
|
1521 |
public void run() {
|
|
1522 |
gotoAddress(address);
|
|
1523 |
}});
|
|
1524 |
}
|
|
1525 |
}
|
|
1526 |
@Override
|
|
1527 |
protected void handleError() {
|
|
1528 |
asyncExec(new Runnable() {
|
|
1529 |
public void run() {
|
|
1530 |
ErrorDialog.openError(getSite().getShell(), "Error", null, getStatus()); //$NON-NLS-1$
|
|
1531 |
}});
|
|
1532 |
}
|
|
1533 |
});
|
|
1534 |
}});
|
|
1535 |
}
|
|
1536 |
|
|
1537 |
private void gotoPosition(Position pos, boolean select) {
|
|
1538 |
if (fViewer == null) {
|
|
1539 |
return;
|
|
1540 |
}
|
|
1541 |
setFocusPosition(pos);
|
|
1542 |
fViewer.setSelectedRange(pos.offset, select ? Math.max(pos.length-1, 0) : 0);
|
|
1543 |
int revealOffset = pos.offset;
|
|
1544 |
boolean onTop = false;
|
|
1545 |
if (/* !fUpdateBeforeFocus && */ pos.offset > 0) {
|
|
1546 |
try {
|
|
1547 |
AddressRangePosition previousPos = fDocument.getModelPosition(pos.offset - 1);
|
|
1548 |
if (previousPos instanceof LabelPosition) {
|
|
1549 |
revealOffset = previousPos.offset;
|
|
1550 |
onTop = true;
|
|
1551 |
} else if (!previousPos.fValid) {
|
|
1552 |
onTop = true;
|
|
1553 |
}
|
|
1554 |
} catch (BadLocationException e) {
|
|
1555 |
// cannot happen
|
|
1556 |
}
|
|
1557 |
}
|
|
1558 |
fViewer.revealOffset(revealOffset, onTop);
|
|
1559 |
}
|
|
1560 |
|
|
1561 |
private void gotoMarker(final IMarker marker) {
|
|
1562 |
if (marker == null) {
|
|
1563 |
return;
|
|
1564 |
}
|
|
1565 |
if (fDebugSessionId == null || fUpdatePending) {
|
|
1566 |
fGotoMarkerPending = marker;
|
|
1567 |
return;
|
|
1568 |
}
|
|
1569 |
fGotoMarkerPending = null;
|
|
1570 |
|
|
1571 |
//TLETODO [disassembly] goto (breakpoint) marker
|
|
1572 |
}
|
|
1573 |
|
|
1574 |
/*
|
|
1575 |
* @see org.eclipse.jface.text.IViewportListener#viewportChanged(int)
|
|
1576 |
*/
|
|
1577 |
public void viewportChanged(int verticalOffset) {
|
|
1578 |
if (fDebugSessionId != null && fGotoAddressPending == PC_UNKNOWN && fScrollPos == null && !fUpdatePending && !fRefreshViewPending) {
|
|
1579 |
fUpdatePending = true;
|
|
1580 |
invokeLater(new Runnable() {
|
|
1581 |
public void run() {
|
|
1582 |
assert fUpdatePending;
|
|
1583 |
if (fUpdatePending) {
|
|
1584 |
fUpdatePending = false;
|
|
1585 |
updateVisibleArea();
|
|
1586 |
}
|
|
1587 |
}
|
|
1588 |
});
|
|
1589 |
}
|
|
1590 |
}
|
|
1591 |
|
|
1592 |
/**
|
|
1593 |
* Update lines of currently visible area + one page buffer zone below.
|
|
1594 |
*/
|
|
1595 |
private void updateVisibleArea() {
|
|
1596 |
if (!fActive || fUpdatePending || fViewer == null || fDebugSessionId == null) {
|
|
1597 |
return;
|
|
1598 |
}
|
|
1599 |
if (fTargetContext == null || !isSuspended(fTargetContext) || fFrameAddress == PC_UNKNOWN) {
|
|
1600 |
return;
|
|
1601 |
}
|
|
1602 |
StyledText styledText = fViewer.getTextWidget();
|
|
1603 |
Rectangle clientArea = styledText.getClientArea();
|
|
1604 |
fBufferZone = Math.max(8, clientArea.height / styledText.getLineHeight());
|
|
1605 |
int topIndex = fViewer.getTopIndex();
|
|
1606 |
int bottomIndex = fViewer.getBottomIndex();
|
|
1607 |
int focusIndex = -1;
|
|
1608 |
boolean focusVisible = false;
|
|
1609 |
boolean isScrollingUp = fViewer.isUserTriggeredScrolling() && fViewer.getLastTopPixel() >= styledText.getTopPixel();
|
|
1610 |
if (fFocusPos != null) {
|
|
1611 |
try {
|
|
1612 |
int focusOffset = fFocusPos.offset;
|
|
1613 |
focusIndex = fDocument.getLineOfOffset(focusOffset);
|
|
1614 |
focusVisible = focusIndex >= topIndex && focusIndex <= bottomIndex;
|
|
1615 |
// workaround for: Clicking the IP annotation in the right ruler has no effect.
|
|
1616 |
// we deselect the IP location if it is scrolled outside the visible area
|
|
1617 |
if (!focusVisible) {
|
|
1618 |
Point selection = fViewer.getSelectedRange();
|
|
1619 |
if (selection.x == focusOffset && selection.y > 0) {
|
|
1620 |
fViewer.setSelectedRange(selection.x, 0);
|
|
1621 |
}
|
|
1622 |
}
|
|
1623 |
} catch (BadLocationException e) {
|
|
1624 |
setFocusPosition(null);
|
|
1625 |
}
|
|
1626 |
}
|
|
1627 |
if (!focusVisible) {
|
|
1628 |
focusIndex = topIndex + fScrollLine;
|
|
1629 |
}
|
|
1630 |
BigInteger focusAddress = getAddressOfLine(focusIndex);
|
|
1631 |
bottomIndex += 2;
|
|
1632 |
AddressRangePosition bestPosition = null;
|
|
1633 |
int bestLine = -1;
|
|
1634 |
BigInteger bestDistance = null;
|
|
1635 |
Iterator<AddressRangePosition> it = fDocument.getInvalidAddressRanges().iterator();
|
|
1636 |
while (it.hasNext()) {
|
|
1637 |
AddressRangePosition p = it.next();
|
|
1638 |
try {
|
|
1639 |
int line = fDocument.getLineOfOffset(p.offset);
|
|
1640 |
if (line >= topIndex && line <= bottomIndex) {
|
|
1641 |
if (p instanceof DisassemblyPosition || p.fAddressLength.compareTo(
|
|
1642 |
BigInteger.valueOf(fBufferZone * 2)) <= 0) {
|
|
1643 |
// small areas and known areas are OK to update
|
|
1644 |
} else if (!isScrollingUp && !fUpdateBeforeFocus
|
|
1645 |
&& p.fAddressOffset.compareTo(focusAddress) < 0) {
|
|
1646 |
continue;
|
|
1647 |
}
|
|
1648 |
BigInteger distance = p.fAddressOffset.subtract(focusAddress).abs();
|
|
1649 |
if (bestDistance == null || distance.compareTo(bestDistance) < 0) {
|
|
1650 |
bestPosition = p;
|
|
1651 |
bestLine = line;
|
|
1652 |
bestDistance = distance;
|
|
1653 |
if (bestDistance.compareTo(BigInteger.valueOf(fBufferZone * 2)) <= 0) {
|
|
1654 |
break;
|
|
1655 |
}
|
|
1656 |
}
|
|
1657 |
}
|
|
1658 |
} catch (BadLocationException e) {
|
|
1659 |
continue;
|
|
1660 |
}
|
|
1661 |
}
|
|
1662 |
if (bestPosition != null) {
|
|
1663 |
int lines = fBufferZone+3;
|
|
1664 |
BigInteger startAddress = bestPosition.fAddressOffset;
|
|
1665 |
BigInteger endAddress = bestPosition.fAddressOffset.add(bestPosition.fAddressLength);
|
|
1666 |
BigInteger addressRange = BigInteger.valueOf(lines * fDocument.getMeanSizeOfInstructions());
|
|
1667 |
if (bestLine > focusIndex || bestLine == focusIndex && startAddress.compareTo(focusAddress) >= 0) {
|
|
1668 |
// insert at start of range
|
|
1669 |
if (endAddress.subtract(startAddress).compareTo(addressRange) < 0) {
|
|
1670 |
// try to increase range to reduce number of requests
|
|
1671 |
Iterator<?> iter = fDocument.getModelPositionIterator(endAddress);
|
|
1672 |
while (iter.hasNext()) {
|
|
1673 |
AddressRangePosition p = (AddressRangePosition)iter.next();
|
|
1674 |
if (p.fValid) {
|
|
1675 |
endAddress = endAddress.add(p.fAddressLength);
|
|
1676 |
if (endAddress.subtract(startAddress).compareTo(addressRange) >= 0) {
|
|
1677 |
break;
|
|
1678 |
}
|
|
1679 |
} else {
|
|
1680 |
break;
|
|
1681 |
}
|
|
1682 |
}
|
|
1683 |
}
|
|
1684 |
} else {
|
|
1685 |
// insert at end of range
|
|
1686 |
startAddress = startAddress.max(endAddress.subtract(addressRange));
|
|
1687 |
// make sure we get all disassembly lines until endAddress
|
|
1688 |
lines = endAddress.subtract(startAddress).intValue();
|
|
1689 |
}
|
|
1690 |
retrieveDisassembly(startAddress, endAddress, lines);
|
|
1691 |
}
|
|
1692 |
scheduleDoPending();
|
|
1693 |
}
|
|
1694 |
|
|
1695 |
private void asyncExec(Runnable runnable) {
|
|
1696 |
if (fViewer != null) {
|
|
1697 |
fViewer.getControl().getDisplay().asyncExec(runnable);
|
|
1698 |
}
|
|
1699 |
}
|
|
1700 |
private void invokeLater(Runnable runnable) {
|
|
1701 |
invokeLater(10, runnable);
|
|
1702 |
}
|
|
1703 |
private void invokeLater(int delay, Runnable runnable) {
|
|
1704 |
if (fViewer != null) {
|
|
1705 |
fViewer.getControl().getDisplay().timerExec(delay, runnable);
|
|
1706 |
}
|
|
1707 |
}
|
|
1708 |
|
|
1709 |
/**
|
|
1710 |
* Insert sourcelines if available.
|
|
1711 |
*/
|
|
1712 |
/*default*/ void updateInvalidSource() {
|
|
1713 |
if (fViewer == null) {
|
|
1714 |
return;
|
|
1715 |
}
|
|
1716 |
boolean unlock = false;
|
|
1717 |
try {
|
|
1718 |
if (fScrollPos == null) {
|
|
1719 |
if (fUpdatePending) {
|
|
1720 |
fUpdateSourcePending= true;
|
|
1721 |
return;
|
|
1722 |
}
|
|
1723 |
fUpdateSourcePending= false;
|
|
1724 |
unlock = true;
|
|
1725 |
fUpdatePending = true;
|
|
1726 |
lockScroller();
|
|
1727 |
}
|
|
1728 |
ArrayList<SourcePosition> copy = new ArrayList<SourcePosition>(fDocument.getInvalidSource());
|
|
1729 |
Iterator<SourcePosition> it = copy.iterator();
|
|
1730 |
while (it.hasNext()) {
|
|
1731 |
SourcePosition p = it.next();
|
|
1732 |
if (!p.fValid) {
|
|
1733 |
insertSource(p);
|
|
1734 |
} else if (DEBUG && fDocument.getInvalidSource().remove(p)) {
|
|
1735 |
System.err.println("!!! valid source position in invalid source list at "+getAddressText(p.fAddressOffset)); //$NON-NLS-1$
|
|
1736 |
}
|
|
1737 |
}
|
|
1738 |
} finally {
|
|
1739 |
if (unlock) {
|
|
1740 |
fUpdatePending = false;
|
|
1741 |
unlockScroller();
|
|
1742 |
doPending();
|
|
1743 |
}
|
|
1744 |
}
|
|
1745 |
}
|
|
1746 |
|
|
1747 |
/**
|
|
1748 |
* Show disassembly for given (source) file.
|
|
1749 |
*
|
|
1750 |
* @param file
|
|
1751 |
* @param lines
|
|
1752 |
*/
|
|
1753 |
void retrieveDisassembly(final String file, final int lines, final boolean mixed) {
|
|
1754 |
if (fDebugSessionId == null) {
|
|
1755 |
return;
|
|
1756 |
}
|
|
1757 |
if (fUpdatePending) {
|
|
1758 |
invokeLater(new Runnable() {
|
|
1759 |
public void run() {
|
|
1760 |
retrieveDisassembly(file, lines, mixed);
|
|
1761 |
}});
|
|
1762 |
return;
|
|
1763 |
}
|
|
1764 |
if (DEBUG) System.out.println("retrieveDisassembly "+file); //$NON-NLS-1$
|
|
1765 |
String debuggerPath= file;
|
|
1766 |
|
|
1767 |
// try reverse lookup
|
|
1768 |
final ISourceLookup lookup= getService(ISourceLookup.class);
|
|
1769 |
final ISourceLookupDMContext ctx= DMContexts.getAncestorOfType(fTargetContext, ISourceLookupDMContext.class);
|
|
1770 |
final DsfExecutor executor= getSession().getExecutor();
|
|
1771 |
Query<String> query= new Query<String>() {
|
|
1772 |
@Override
|
|
1773 |
protected void execute(final DataRequestMonitor<String> rm) {
|
|
1774 |
final DataRequestMonitor<String> request= new DataRequestMonitor<String>(executor, rm) {
|
|
1775 |
@Override
|
|
1776 |
protected void handleSuccess() {
|
|
1777 |
rm.setData(getData());
|
|
1778 |
rm.done();
|
|
1779 |
}
|
|
1780 |
};
|
|
1781 |
lookup.getDebuggerPath(ctx, file, request);
|
|
1782 |
}
|
|
1783 |
};
|
|
1784 |
try {
|
|
1785 |
getSession().getExecutor().execute(query);
|
|
1786 |
debuggerPath= query.get();
|
|
1787 |
} catch (InterruptedException exc) {
|
|
1788 |
internalError(exc);
|
|
1789 |
} catch (ExecutionException exc) {
|
|
1790 |
internalError(exc);
|
|
1791 |
}
|
|
1792 |
|
|
1793 |
final IDisassemblyDMContext context= DMContexts.getAncestorOfType(fTargetContext, IDisassemblyDMContext.class);
|
|
1794 |
|
|
1795 |
final String finalFile= debuggerPath;
|
|
1796 |
final DataRequestMonitor<IMixedInstruction[]> disassemblyRequest= new DataRequestMonitor<IMixedInstruction[]>(executor, null) {
|
|
1797 |
@Override
|
|
1798 |
public void handleCompleted() {
|
|
1799 |
final IMixedInstruction[] data= getData();
|
|
1800 |
if (!isCanceled() && data != null) {
|
|
1801 |
asyncExec(new Runnable() {
|
|
1802 |
public void run() {
|
|
1803 |
if (!insertDisassembly(null, data)) {
|
|
1804 |
// retry in non-mixed mode
|
|
1805 |
retrieveDisassembly(file, lines, false);
|
|
1806 |
}
|
|
1807 |
}});
|
|
1808 |
} else {
|
|
1809 |
final IStatus status= getStatus();
|
|
1810 |
if (status != null && !status.isOK()) {
|
|
1811 |
asyncExec(new Runnable() {
|
|
1812 |
public void run() {
|
|
1813 |
ErrorDialog.openError(getSite().getShell(), "Error", null, getStatus()); //$NON-NLS-1$
|
|
1814 |
}
|
|
1815 |
});
|
|
1816 |
}
|
|
1817 |
fUpdatePending= false;
|
|
1818 |
}
|
|
1819 |
}
|
|
1820 |
};
|
|
1821 |
assert !fUpdatePending;
|
|
1822 |
fUpdatePending = true;
|
|
1823 |
executor.execute(new Runnable() {
|
|
1824 |
public void run() {
|
|
1825 |
final IDisassembly disassembly= fServicesTracker.getService(IDisassembly.class);
|
|
1826 |
if (disassembly == null) {
|
|
1827 |
disassemblyRequest.cancel();
|
|
1828 |
disassemblyRequest.done();
|
|
1829 |
return;
|
|
1830 |
}
|
|
1831 |
disassembly.getMixedInstructions(context, finalFile, 1, lines, disassemblyRequest);
|
|
1832 |
}});
|
|
1833 |
}
|
|
1834 |
|
|
1835 |
private void retrieveDisassembly(BigInteger startAddress, BigInteger endAddress, int lines) {
|
|
1836 |
if (fDebugSessionId == null) {
|
|
1837 |
return;
|
|
1838 |
}
|
|
1839 |
if (DEBUG) System.out.println("retrieveDisassembly "+getAddressText(startAddress)+" "+lines+" lines"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
|
1840 |
retrieveDisassembly(startAddress, endAddress, lines, true, false);
|
|
1841 |
}
|
|
1842 |
|
|
1843 |
private void retrieveDisassembly(final BigInteger startAddress, BigInteger endAddress, final int linesHint, boolean mixed, boolean ignoreFile) {
|
|
1844 |
assert !fUpdatePending;
|
|
1845 |
fUpdatePending = true;
|
|
1846 |
final int lines= linesHint + 2;
|
|
1847 |
final BigInteger addressLength= BigInteger.valueOf(lines * 4);
|
|
1848 |
if (endAddress.subtract(startAddress).compareTo(addressLength) > 0) {
|
|
1849 |
endAddress= startAddress.add(addressLength);
|
|
1850 |
}
|
|
1851 |
boolean insideActiveFrame= startAddress.equals(fFrameAddress);
|
|
1852 |
String file= null;
|
|
1853 |
int lineNumber= -1;
|
|
1854 |
if (!ignoreFile && insideActiveFrame && fTargetFrameData != null) {
|
|
1855 |
file= fTargetFrameData.getFile();
|
|
1856 |
if (file != null && file.trim().length() == 0) {
|
|
1857 |
file= null;
|
|
1858 |
}
|
|
1859 |
lineNumber= fTargetFrameData.getLine();
|
|
1860 |
}
|
|
1861 |
final String finalFile= file;
|
|
1862 |
final int finalLineNumber= lineNumber;
|
|
1863 |
final BigInteger finalEndAddress= endAddress;
|
|
1864 |
|
|
1865 |
final DsfExecutor executor= getSession().getExecutor();
|
|
1866 |
final IDisassemblyDMContext context= DMContexts.getAncestorOfType(fTargetContext, IDisassemblyDMContext.class);
|
|
1867 |
|
|
1868 |
if (mixed) {
|
|
1869 |
final DataRequestMonitor<IMixedInstruction[]> disassemblyRequest= new DataRequestMonitor<IMixedInstruction[]>(executor, null) {
|
|
1870 |
@Override
|
|
1871 |
public void handleCompleted() {
|
|
1872 |
final IMixedInstruction[] data= getData();
|
|
1873 |
if (!isCanceled() && data != null) {
|
|
1874 |
asyncExec(new Runnable() {
|
|
1875 |
public void run() {
|
|
1876 |
if (!insertDisassembly(startAddress, data)) {
|
|
1877 |
// retry in non-mixed mode
|
|
1878 |
retrieveDisassembly(startAddress, finalEndAddress, linesHint, false, false);
|
|
1879 |
}
|
|
1880 |
}});
|
|
1881 |
} else {
|
|
1882 |
final IStatus status= getStatus();
|
|
1883 |
if (status != null && !status.isOK()) {
|
|
1884 |
if( finalFile != null ) {
|
|
1885 |
asyncExec(new Runnable() {
|
|
1886 |
public void run() {
|
|
1887 |
retrieveDisassembly(startAddress, finalEndAddress, linesHint, true, true);
|
|
1888 |
}});
|
|
1889 |
}
|
|
1890 |
else {
|
|
1891 |
asyncExec(new Runnable() {
|
|
1892 |
public void run() {
|
|
1893 |
doScrollLocked(new Runnable() {
|
|
1894 |
public void run() {
|
|
1895 |
insertError(startAddress, status.getMessage());
|
|
1896 |
}
|
|
1897 |
});
|
|
1898 |
}});
|
|
1899 |
}
|
|
1900 |
}
|
|
1901 |
fUpdatePending= false;
|
|
1902 |
}
|
|
1903 |
}
|
|
1904 |
};
|
|
1905 |
if (file != null) {
|
|
1906 |
executor.execute(new Runnable() {
|
|
1907 |
public void run() {
|
|
1908 |
final IDisassembly disassembly= fServicesTracker.getService(IDisassembly.class);
|
|
1909 |
if (disassembly == null) {
|
|
1910 |
disassemblyRequest.cancel();
|
|
1911 |
disassemblyRequest.done();
|
|
1912 |
return;
|
|
1913 |
}
|
|
1914 |
disassembly.getMixedInstructions(context, finalFile, finalLineNumber, lines*2, disassemblyRequest);
|
|
1915 |
}});
|
|
1916 |
} else {
|
|
1917 |
executor.execute(new Runnable() {
|
|
1918 |
public void run() {
|
|
1919 |
final IDisassembly disassembly= fServicesTracker.getService(IDisassembly.class);
|
|
1920 |
if (disassembly == null) {
|
|
1921 |
disassemblyRequest.cancel();
|
|
1922 |
disassemblyRequest.done();
|
|
1923 |
return;
|
|
1924 |
}
|
|
1925 |
disassembly.getMixedInstructions(context, startAddress, finalEndAddress, disassemblyRequest);
|
|
1926 |
}});
|
|
1927 |
}
|
|
1928 |
} else {
|
|
1929 |
final DataRequestMonitor<IInstruction[]> disassemblyRequest= new DataRequestMonitor<IInstruction[]>(executor, null) {
|
|
1930 |
@Override
|
|
1931 |
public void handleCompleted() {
|
|
1932 |
if (!isCanceled() && getData() != null) {
|
|
1933 |
asyncExec(new Runnable() {
|
|
1934 |
public void run() {
|
|
1935 |
insertDisassembly(startAddress, getData());
|
|
1936 |
}});
|
|
1937 |
} else {
|
|
1938 |
final IStatus status= getStatus();
|
|
1939 |
if (status != null && !status.isOK()) {
|
|
1940 |
asyncExec(new Runnable() {
|
|
1941 |
public void run() {
|
|
1942 |
doScrollLocked(new Runnable() {
|
|
1943 |
public void run() {
|
|
1944 |
insertError(startAddress, status.getMessage());
|
|
1945 |
}
|
|
1946 |
});
|
|
1947 |
}});
|
|
1948 |
}
|
|
1949 |
fUpdatePending= false;
|
|
1950 |
}
|
|
1951 |
}
|
|
1952 |
};
|
|
1953 |
if (file != null) {
|
|
1954 |
executor.execute(new Runnable() {
|
|
1955 |
public void run() {
|
|
1956 |
final IDisassembly disassembly= fServicesTracker.getService(IDisassembly.class);
|
|
1957 |
if (disassembly == null) {
|
|
1958 |
disassemblyRequest.cancel();
|
|
1959 |
disassemblyRequest.done();
|
|
1960 |
return;
|
|
1961 |
}
|
|
1962 |
disassembly.getInstructions(context, finalFile, finalLineNumber, lines, disassemblyRequest);
|
|
1963 |
}});
|
|
1964 |
} else {
|
|
1965 |
executor.execute(new Runnable() {
|
|
1966 |
public void run() {
|
|
1967 |
final IDisassembly disassembly= fServicesTracker.getService(IDisassembly.class);
|
|
1968 |
if (disassembly == null) {
|
|
1969 |
disassemblyRequest.cancel();
|
|
1970 |
disassemblyRequest.done();
|
|
1971 |
return;
|
|
1972 |
}
|
|
1973 |
disassembly.getInstructions(context, startAddress, finalEndAddress, disassemblyRequest);
|
|
1974 |
}});
|
|
1975 |
}
|
|
1976 |
}
|
|
1977 |
}
|
|
1978 |
|
|
1979 |
private void insertError(BigInteger address, String message) {
|
|
1980 |
AddressRangePosition p = null;
|
|
1981 |
p = getPositionOfAddress(address);
|
|
1982 |
if (p.fValid) {
|
|
1983 |
return;
|
|
1984 |
}
|
|
1985 |
try {
|
|
1986 |
fDocument.insertErrorLine(p, address, BigInteger.ONE, message);
|
|
1987 |
} catch (BadLocationException exc) {
|
|
1988 |
internalError(exc);
|
|
1989 |
}
|
|
1990 |
}
|
|
1991 |
|
|
1992 |
private void insertDisassembly(BigInteger startAddress, IInstruction[] instructions) {
|
|
1993 |
if (fViewer == null || fDebugSessionId == null) {
|
|
1994 |
return;
|
|
1995 |
}
|
|
1996 |
if (DEBUG) System.out.println("insertDisassembly "+getAddressText(startAddress)); //$NON-NLS-1$
|
|
1997 |
assert fUpdatePending;
|
|
1998 |
if (!fUpdatePending) {
|
|
1999 |
// safe-guard in case something weird is going on
|
|
2000 |
return;
|
|
2001 |
}
|
|
2002 |
try {
|
|
2003 |
lockScroller();
|
|
2004 |
|
|
2005 |
AddressRangePosition p= null;
|
|
2006 |
for (int j = 0; j < instructions.length; j++) {
|
|
2007 |
IInstruction instruction = instructions[j];
|
|
2008 |
BigInteger address= instruction.getAdress();
|
|
2009 |
if (startAddress == null || startAddress.compareTo(BigInteger.ZERO) < 0) {
|
|
2010 |
fGotoAddressPending = startAddress = address;
|
|
2011 |
}
|
|
2012 |
if (p == null || !p.containsAddress(address)) {
|
|
2013 |
p = getPositionOfAddress(address);
|
|
2014 |
}
|
|
2015 |
if (p instanceof ErrorPosition && p.fValid) {
|
|
2016 |
p.fValid = false;
|
|
2017 |
fDocument.getInvalidAddressRanges().add(p);
|
|
2018 |
} else if (p == null || p.fValid) {
|
|
2019 |
if (DEBUG) System.out.println("Excess disassembly lines at " + getAddressText(address)); //$NON-NLS-1$
|
|
2020 |
return;
|
|
2021 |
}
|
|
2022 |
boolean hasSource= false;
|
|
2023 |
String compilationPath= null;
|
|
2024 |
// insert symbol label
|
|
2025 |
final String functionName= instruction.getFuntionName();
|
|
2026 |
if (functionName != null && functionName.length() > 0 && instruction.getOffset() == 0) {
|
|
2027 |
p = fDocument.insertLabel(p, address, functionName, fShowSymbols && (!hasSource || fShowDisassembly));
|
|
2028 |
}
|
|
2029 |
// determine instruction byte length
|
|
2030 |
BigInteger instrLength= null;
|
|
2031 |
if (j < instructions.length - 1) {
|
|
2032 |
instrLength= instructions[j+1].getAdress().subtract(instruction.getAdress()).abs();
|
|
2033 |
} else if (instructions.length == 1) {
|
|
2034 |
if (p.fAddressLength.compareTo(BigInteger.valueOf(8)) <= 0) {
|
|
2035 |
instrLength= p.fAddressLength;
|
|
2036 |
}
|
|
2037 |
}
|
|
2038 |
if (instrLength == null) {
|
|
2039 |
// cannot determine length of last instruction
|
|
2040 |
break;
|
|
2041 |
}
|
|
2042 |
final String opCode;
|
|
2043 |
// insert function name+offset instead of opcode bytes
|
|
2044 |
if (functionName != null && functionName.length() > 0) {
|
|
2045 |
opCode= functionName + '+' + instruction.getOffset();
|
|
2046 |
} else {
|
|
2047 |
opCode= ""; //$NON-NLS-1$
|
|
2048 |
}
|
|
2049 |
p = fDocument.insertDisassemblyLine(p, address, instrLength.intValue(), opCode, instruction.getInstruction(), compilationPath, -1);
|
|
2050 |
if (p == null) {
|
|
2051 |
break;
|
|
2052 |
}
|
|
2053 |
}
|
|
2054 |
|
|
2055 |
} catch (BadLocationException e) {
|
|
2056 |
// should not happen
|
|
2057 |
internalError(e);
|
|
2058 |
} finally {
|
|
2059 |
fUpdatePending = false;
|
|
2060 |
updateInvalidSource();
|
|
2061 |
unlockScroller();
|
|
2062 |
doPending();
|
|
2063 |
updateVisibleArea();
|
|
2064 |
}
|
|
2065 |
}
|
|
2066 |
|
|
2067 |
private boolean insertDisassembly(BigInteger startAddress, IMixedInstruction[] mixedInstructions) {
|
|
2068 |
if (fViewer == null || fDebugSessionId == null) {
|
|
2069 |
return true;
|
|
2070 |
}
|
|
2071 |
if (DEBUG) System.out.println("insertDisassembly "+getAddressText(startAddress)); //$NON-NLS-1$
|
|
2072 |
assert fUpdatePending;
|
|
2073 |
if (!fUpdatePending) {
|
|
2074 |
// safe-guard in case something weird is going on
|
|
2075 |
return true;
|
|
2076 |
}
|
|
2077 |
// indicates whether disassembly for the start address was inserted
|
|
2078 |
boolean success= false;
|
|
2079 |
try {
|
|
2080 |
lockScroller();
|
|
2081 |
|
|
2082 |
AddressRangePosition p= null;
|
|
2083 |
for (int i = 0; i < mixedInstructions.length; ++i) {
|
|
2084 |
IMixedInstruction mixedInstruction= mixedInstructions[i];
|
|
2085 |
final String file= mixedInstruction.getFileName();
|
|
2086 |
final int lineNumber= mixedInstruction.getLineNumber() - 1;
|
|
2087 |
IInstruction[] instructions= mixedInstruction.getInstructions();
|
|
2088 |
for (int j = 0; j < instructions.length; ++j) {
|
|
2089 |
IInstruction instruction = instructions[j];
|
|
2090 |
BigInteger address= instruction.getAdress();
|
|
2091 |
if (startAddress == null || startAddress.compareTo(BigInteger.ZERO) < 0) {
|
|
2092 |
fGotoAddressPending = startAddress = address;
|
|
2093 |
}
|
|
2094 |
if (p == null || !p.containsAddress(address)) {
|
|
2095 |
p = getPositionOfAddress(address);
|
|
2096 |
}
|
|
2097 |
if (p instanceof ErrorPosition && p.fValid) {
|
|
2098 |
p.fValid = false;
|
|
2099 |
fDocument.getInvalidAddressRanges().add(p);
|
|
2100 |
} else if (p == null) {
|
|
2101 |
if (DEBUG) System.out.println("Excess disassembly lines at " + getAddressText(address)); //$NON-NLS-1$
|
|
2102 |
return success;
|
|
2103 |
} else if (p.fValid) {
|
|
2104 |
if (DEBUG) System.out.println("Excess disassembly lines at " + getAddressText(address)); //$NON-NLS-1$
|
|
2105 |
if (file != null && lineNumber >= 0 || p.fAddressLength == BigInteger.ONE) {
|
|
2106 |
// override probably unaligned disassembly
|
|
2107 |
p.fValid = false;
|
|
2108 |
fDocument.getInvalidAddressRanges().add(p);
|
|
2109 |
} else {
|
|
2110 |
return success;
|
|
2111 |
}
|
|
2112 |
}
|
|
2113 |
boolean hasSource= false;
|
|
2114 |
if (file != null && lineNumber >= 0) {
|
|
2115 |
p = insertSource(p, address, file, lineNumber);
|
|
2116 |
hasSource = fFile2Storage.get(file) != null;
|
|
2117 |
}
|
|
2118 |
// insert symbol label
|
|
2119 |
final String functionName= instruction.getFuntionName();
|
|
2120 |
if (functionName != null && functionName.length() > 0 && instruction.getOffset() == 0) {
|
|
2121 |
p = fDocument.insertLabel(p, address, functionName, fShowSymbols && (!hasSource || fShowDisassembly));
|
|
2122 |
}
|
|
2123 |
// determine instruction byte length
|
|
2124 |
BigInteger instrLength= null;
|
|
2125 |
if (j < instructions.length - 1) {
|
|
2126 |
instrLength= instructions[j+1].getAdress().subtract(instruction.getAdress()).abs();
|
|
2127 |
} else if (i < mixedInstructions.length - 1) {
|
|
2128 |
int nextSrcLineIdx= i+1;
|
|
2129 |
while (nextSrcLineIdx < mixedInstructions.length) {
|
|
2130 |
IInstruction[] nextInstrs= mixedInstructions[nextSrcLineIdx].getInstructions();
|
|
2131 |
if (nextInstrs.length > 0) {
|
|
2132 |
instrLength= nextInstrs[0].getAdress().subtract(instruction.getAdress()).abs();
|
|
2133 |
break;
|
|
2134 |
}
|
|
2135 |
++nextSrcLineIdx;
|
|
2136 |
}
|
|
2137 |
if (nextSrcLineIdx >= mixedInstructions.length) {
|
|
2138 |
break;
|
|
2139 |
}
|
|
2140 |
} else if (instructions.length == 1) {
|
|
2141 |
if (p.fAddressLength.compareTo(BigInteger.valueOf(8)) <= 0) {
|
|
2142 |
instrLength= p.fAddressLength;
|
|
2143 |
}
|
|
2144 |
}
|
|
2145 |
if (instrLength == null) {
|
|
2146 |
// cannot determine length of last instruction
|
|
2147 |
break;
|
|
2148 |
}
|
|
2149 |
final String opCode;
|
|
2150 |
// insert function name+offset instead of opcode bytes
|
|
2151 |
if (functionName != null && functionName.length() > 0) {
|
|
2152 |
opCode= functionName + '+' + instruction.getOffset();
|
|
2153 |
} else {
|
|
2154 |
opCode= ""; //$NON-NLS-1$
|
|
2155 |
}
|
|
2156 |
success= success || address.compareTo(startAddress) == 0;
|
|
2157 |
p = fDocument.insertDisassemblyLine(p, address, instrLength.intValue(), opCode, instruction.getInstruction(), file, lineNumber);
|
|
2158 |
if (p == null && success) {
|
|
2159 |
break;
|
|
2160 |
}
|
|
2161 |
}
|
|
2162 |
}
|
|
2163 |
|
|
2164 |
} catch (BadLocationException e) {
|
|
2165 |
// should not happen
|
|
2166 |
internalError(e);
|
|
2167 |
} finally {
|
|
2168 |
fUpdatePending = false;
|
|
2169 |
if (success) {
|
|
2170 |
updateInvalidSource();
|
|
2171 |
unlockScroller();
|
|
2172 |
doPending();
|
|
2173 |
updateVisibleArea();
|
|
2174 |
} else {
|
|
2175 |
unlockScroller();
|
|
2176 |
}
|
|
2177 |
}
|
|
2178 |
return success;
|
|
2179 |
}
|
|
2180 |
|
|
2181 |
private void retrieveFrameAddress(final IExecutionDMContext targetContext, final int frame) {
|
|
2182 |
if (targetContext != null && isSuspended(targetContext)) {
|
|
2183 |
if (fUpdatePending) {
|
|
2184 |
gotoFrame(frame);
|
|
2185 |
return;
|
|
2186 |
}
|
|
2187 |
if (DEBUG) System.out.println("retrieveFrameAddress "+frame); //$NON-NLS-1$
|
|
2188 |
fUpdatePending = true;
|
|
2189 |
final DsfExecutor executor= getSession().getExecutor();
|
|
2190 |
executor.execute(new DsfRunnable() {
|
|
2191 |
public void run() {
|
|
2192 |
retrieveFrameAddressInSessionThread(targetContext, frame);
|
|
2193 |
}});
|
|
2194 |
}
|
|
2195 |
}
|
|
2196 |
|
|
2197 |
private void retrieveFrameAddressInSessionThread(final IExecutionDMContext targetContext, final int frame) {
|
|
2198 |
final IStack stack= fServicesTracker.getService(IStack.class);
|
|
2199 |
final DsfExecutor executor= getSession().getExecutor();
|
|
2200 |
if (fTargetFrameContext == null) {
|
|
2201 |
if (frame == 0) {
|
|
2202 |
stack.getTopFrame(targetContext, new DataRequestMonitor<IFrameDMContext>(executor, null) {
|
|
2203 |
@Override
|
|
2204 |
protected void handleCompleted() {
|
|
2205 |
fUpdatePending= false;
|
|
2206 |
fTargetFrameContext= getData();
|
|
2207 |
if (fTargetFrameContext != null) {
|
|
2208 |
retrieveFrameAddressInSessionThread(targetContext, frame);
|
|
2209 |
}
|
|
2210 |
}
|
|
2211 |
});
|
|
2212 |
} else {
|
|
2213 |
// TODO retrieve other stack frame
|
|
2214 |
}
|
|
2215 |
return;
|
|
2216 |
}
|
|
2217 |
stack.getFrameData(fTargetFrameContext, new DataRequestMonitor<IFrameDMData>(executor, null) {
|
|
2218 |
@Override
|
|
2219 |
protected void handleCompleted() {
|
|
2220 |
if (!isCanceled()) {
|
|
2221 |
fUpdatePending= false;
|
|
2222 |
final IFrameDMData frameData= getData();
|
|
2223 |
fTargetFrameData= frameData;
|
|
2224 |
final IAddress address= frameData.getAddress();
|
|
2225 |
final BigInteger addressValue= address.getValue();
|
|
2226 |
if (DEBUG) System.out.println("retrieveFrameAddress done "+getAddressText(addressValue)); //$NON-NLS-1$
|
|
2227 |
asyncExec(new Runnable() {
|
|
2228 |
public void run() {
|
|
2229 |
if (address.getSize() * 4 > fAddressSize) {
|
|
2230 |
addressSizeChanged(address.getSize() * 4);
|
|
2231 |
}
|
|
2232 |
if (frame == 0) {
|
|
2233 |
updatePC(addressValue);
|
|
2234 |
} else {
|
|
2235 |
gotoFrame(frame, addressValue);
|
|
2236 |
}
|
|
2237 |
}
|
|
2238 |
|
|
2239 |
});
|
|
2240 |
}
|
|
2241 |
}
|
|
2242 |
});
|
|
2243 |
}
|
|
2244 |
|
|
2245 |
private void addressSizeChanged(int addressSize) {
|
|
2246 |
BigInteger oldEndAddress= fEndAddress;
|
|
2247 |
fEndAddress= BigInteger.ONE.shiftLeft(addressSize);
|
|
2248 |
int oldAddressSize= fAddressSize;
|
|
2249 |
fAddressSize= addressSize;
|
|
2250 |
if (addressSize < oldAddressSize) {
|
|
2251 |
fDocument.deleteDisassemblyRange(fEndAddress, oldEndAddress, true, true);
|
|
2252 |
List<AddressRangePosition> positions= fDocument.getInvalidAddressRanges();
|
|
2253 |
List<AddressRangePosition> toRemove= new ArrayList<AddressRangePosition>();
|
|
2254 |
for (AddressRangePosition position : positions) {
|
|
2255 |
if (position.fAddressOffset.compareTo(fEndAddress) >= 0) {
|
|
2256 |
try {
|
|
2257 |
fDocument.replace(position, position.length, ""); //$NON-NLS-1$
|
|
2258 |
fDocument.removeModelPosition(position);
|
|
2259 |
toRemove.add(position);
|
|
2260 |
} catch (BadLocationException exc) {
|
|
2261 |
internalError(exc);
|
|
2262 |
}
|
|
2263 |
} else if (position.containsAddress(fEndAddress)){
|
|
2264 |
position.fAddressLength= fEndAddress.subtract(position.fAddressOffset);
|
|
2265 |
}
|
|
2266 |
}
|
|
2267 |
positions.removeAll(toRemove);
|
|
2268 |
} else if (addressSize > oldAddressSize) {
|
|
2269 |
fDocument.insertInvalidAddressRange(fDocument.getLength(), 0, oldEndAddress, fEndAddress);
|
|
2270 |
} else {
|
|
2271 |
return;
|
|
2272 |
}
|
|
2273 |
if (fAddressRulerColumn != null) {
|
|
2274 |
fAddressRulerColumn.setAddressSize(addressSize);
|
|
2275 |
if (fComposite != null) {
|
|
2276 |
fComposite.layout(true);
|
|
2277 |
}
|
|
2278 |
}
|
|
2279 |
}
|
|
2280 |
|
|
2281 |
private AddressRangePosition getPositionOfAddress(BigInteger address) {
|
|
2282 |
if (address == null || address.compareTo(BigInteger.ZERO) < 0) {
|
|
2283 |
return null;
|
|
2284 |
}
|
|
2285 |
AddressRangePosition pos = fDocument.getPositionOfAddress(address);
|
|
2286 |
assert !(pos instanceof SourcePosition);
|
|
2287 |
assert pos != null || address.compareTo(fStartAddress) < 0|| address.compareTo(fEndAddress) >= 0;
|
|
2288 |
return pos;
|
|
2289 |
}
|
|
2290 |
|
|
2291 |
private BigInteger getAddressOfLine(int line) {
|
|
2292 |
return fDocument.getAddressOfLine(line);
|
|
2293 |
}
|
|
2294 |
|
|
2295 |
/**
|
|
2296 |
* Passing the focus request to the viewer's control.
|
|
2297 |
*/
|
|
2298 |
@Override
|
|
2299 |
public void setFocus() {
|
|
2300 |
fViewer.getControl().setFocus();
|
|
2301 |
}
|
|
2302 |
|
|
2303 |
protected void setActive(boolean active) {
|
|
2304 |
if (DEBUG) System.out.println("setActive("+ active +")"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
2305 |
fActive = active;
|
|
2306 |
if (fActive) {
|
|
2307 |
if (fRefreshAll) {
|
|
2308 |
fRefreshAll = false;
|
|
2309 |
refreshView(0);
|
|
2310 |
} else {
|
|
2311 |
doPendingPCUpdates();
|
|
2312 |
if (fTargetContext != null) {
|
|
2313 |
int frame = getActiveStackFrame();
|
|
2314 |
if (frame < 0 && isSuspended(fTargetContext)) {
|
|
2315 |
frame= 0;
|
|
2316 |
}
|
|
2317 |
if (frame != fTargetFrame) {
|
|
2318 |
gotoFrame(frame);
|
|
2319 |
}
|
|
2320 |
}
|
|
2321 |
}
|
|
2322 |
} else {
|
|
2323 |
fGotoAddressPending= fFocusAddress= PC_UNKNOWN;
|
|
2324 |
}
|
|
2325 |
firePropertyChange(PROP_ACTIVE);
|
|
2326 |
}
|
|
2327 |
|
|
2328 |
private int getActiveStackFrame() {
|
|
2329 |
if (fTargetFrameContext != null) {
|
|
2330 |
return fTargetFrameContext.getLevel();
|
|
2331 |
}
|
|
2332 |
return -1;
|
|
2333 |
}
|
|
2334 |
|
|
2335 |
/**
|
|
2336 |
*
|
|
2337 |
*/
|
|
2338 |
protected void updateDebugContext() {
|
|
2339 |
IAdaptable debugContext= DebugUITools.getDebugContext();
|
|
2340 |
if (debugContext instanceof IDMVMContext) {
|
|
2341 |
setDebugContext((IDMVMContext)debugContext);
|
|
2342 |
}
|
|
2343 |
}
|
|
2344 |
|
|
2345 |
protected void setDebugContext(IDMVMContext vmContext) {
|
|
2346 |
if (vmContext != null) {
|
|
2347 |
IDMContext dmContext= vmContext.getDMContext();
|
|
2348 |
String sessionId= dmContext.getSessionId();
|
|
2349 |
if (!sessionId.equals(fDebugSessionId)) {
|
|
2350 |
// switch to different session or initiate session
|
|
2351 |
if (DEBUG) System.out.println("DisassemblyPart.setDebugContext() " + sessionId); //$NON-NLS-1$
|
|
2352 |
fTargetContext= null;
|
|
2353 |
if (dmContext instanceof IFrameDMContext) {
|
|
2354 |
IFrameDMContext frame= (IFrameDMContext) dmContext;
|
|
2355 |
IExecutionDMContext executionContext= DMContexts.getAncestorOfType(frame, IExecutionDMContext.class);
|
|
2356 |
if (executionContext != null) {
|
|
2357 |
fTargetContext= executionContext;
|
|
2358 |
fTargetFrameContext= frame;
|
|
2359 |
fTargetFrame= frame.getLevel();
|
|
2360 |
}
|
|
2361 |
}
|
|
2362 |
if (fTargetContext != null) {
|
|
2363 |
if (fDebugSessionId != null) {
|
|
2364 |
if (getSession() != null) {
|
|
2365 |
getSession().removeServiceEventListener(this);
|
|
2366 |
}
|
|
2367 |
}
|
|
2368 |
fDebugSessionId= sessionId;
|
|
2369 |
if (fServicesTracker != null) {
|
|
2370 |
fServicesTracker.dispose();
|
|
2371 |
}
|
|
2372 |
fServicesTracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), sessionId);
|
|
2373 |
if (fViewer != null) {
|
|
2374 |
debugContextChanged();
|
|
2375 |
}
|
|
2376 |
}
|
|
2377 |
} else if (dmContext instanceof IFrameDMContext) {
|
|
2378 |
// switch to different frame
|
|
2379 |
IFrameDMContext frame= (IFrameDMContext) dmContext;
|
|
2380 |
final IDMContext[] parents= frame.getParents();
|
|
2381 |
for (IDMContext context : parents) {
|
|
2382 |
if (context instanceof IExecutionDMContext) {
|
|
2383 |
fTargetContext= (IExecutionDMContext) context;
|
|
2384 |
fTargetFrameContext= frame;
|
|
2385 |
gotoFrame(frame);
|
|
2386 |
break;
|
|
2387 |
}
|
|
2388 |
}
|
|
2389 |
}
|
|
2390 |
} else if (fDebugSessionId != null) {
|
|
2391 |
if (getSession() != null) {
|
|
2392 |
getSession().removeServiceEventListener(this);
|
|
2393 |
}
|
|
2394 |
fDebugSessionId= null;
|
|
2395 |
fTargetContext= null;
|
|
2396 |
if (fServicesTracker != null) {
|
|
2397 |
fServicesTracker.dispose();
|
|
2398 |
fServicesTracker= null;
|
|
2399 |
}
|
|
2400 |
if (fViewer != null) {
|
|
2401 |
debugContextChanged();
|
|
2402 |
}
|
|
2403 |
}
|
|
2404 |
}
|
|
2405 |
|
|
2406 |
private void debugContextChanged() {
|
|
2407 |
if (DEBUG) System.out.println("DisassemblyPart.debugContextChanged()"); //$NON-NLS-1$
|
|
2408 |
fRunnableQueue.clear();
|
|
2409 |
fUpdatePending = false;
|
|
2410 |
resetViewer();
|
|
2411 |
if (fDebugSessionId != null) {
|
|
2412 |
final DsfSession session= getSession();
|
|
2413 |
session.addServiceEventListener(this, null);
|
|
2414 |
updatePC(PC_UNKNOWN);
|
|
2415 |
|
|
2416 |
if (fGotoAddressPending != PC_UNKNOWN) {
|
|
2417 |
gotoAddress(fGotoAddressPending);
|
|
2418 |
}
|
|
2419 |
if (fGotoMarkerPending != null) {
|
|
2420 |
gotoMarker(fGotoMarkerPending);
|
|
2421 |
}
|
|
2422 |
fViewer.addViewportListener(this);
|
|
2423 |
} else {
|
|
2424 |
fViewer.removeViewportListener(this);
|
|
2425 |
fGotoMarkerPending = null;
|
|
2426 |
// invokeLater(new Runnable() {
|
|
2427 |
// public void run() {
|
|
2428 |
// closePart();
|
|
2429 |
// }});
|
|
2430 |
}
|
|
2431 |
updateTitle();
|
|
2432 |
updateStateDependentActions();
|
|
2433 |
firePropertyChange(PROP_CONNECTED);
|
|
2434 |
firePropertyChange(PROP_SUSPENDED);
|
|
2435 |
}
|
|
2436 |
|
|
2437 |
/*
|
|
2438 |
* @see org.eclipse.cdt.dsf.service.DsfSession.SessionEndedListener#sessionEnded(org.eclipse.cdt.dsf.service.DsfSession)
|
|
2439 |
*/
|
|
2440 |
public void sessionEnded(DsfSession endedSsession) {
|
|
2441 |
if (endedSsession.getId().equals(fDebugSessionId)) {
|
|
2442 |
asyncExec(new Runnable() {
|
|
2443 |
public void run() {
|
|
2444 |
setDebugContext(null);
|
|
2445 |
}});
|
|
2446 |
}
|
|
2447 |
}
|
|
2448 |
|
|
2449 |
@DsfServiceEventHandler
|
|
2450 |
public void handleEvent(IExitedDMEvent event) {
|
131
|
2451 |
// Note we may get more than one ExitedDMEvent for contexts
|
|
2452 |
// (threads, processes, etc.) in this debug session. So check
|
|
2453 |
// for NPE.
|
|
2454 |
// This is already fixed in CDT head....01/28/10
|
|
2455 |
if (fTargetContext == null)
|
|
2456 |
return;
|
|
2457 |
|
37
|
2458 |
final IExecutionDMContext context= event.getDMContext();
|
|
2459 |
if (context.equals(fTargetContext)
|
|
2460 |
|| DMContexts.isAncestorOf(fTargetContext, context)) {
|
|
2461 |
asyncExec(new Runnable() {
|
|
2462 |
public void run() {
|
|
2463 |
setDebugContext(null);
|
|
2464 |
}});
|
|
2465 |
}
|
|
2466 |
}
|
|
2467 |
|
|
2468 |
@DsfServiceEventHandler
|
|
2469 |
public void handleEvent(ISuspendedDMEvent event) {
|
|
2470 |
final IExecutionDMContext context= event.getDMContext();
|
|
2471 |
if (context.equals(fTargetContext)
|
|
2472 |
|| DMContexts.isAncestorOf(fTargetContext, context)) {
|
|
2473 |
asyncExec(new Runnable() {
|
|
2474 |
public void run() {
|
|
2475 |
updatePC(PC_UNKNOWN);
|
|
2476 |
firePropertyChange(PROP_SUSPENDED);
|
|
2477 |
}
|
|
2478 |
});
|
|
2479 |
}
|
|
2480 |
}
|
|
2481 |
|
|
2482 |
@DsfServiceEventHandler
|
|
2483 |
public void handleEvent(IResumedDMEvent event) {
|
|
2484 |
final IExecutionDMContext context= event.getDMContext();
|
|
2485 |
if (context.equals(fTargetContext)
|
|
2486 |
|| DMContexts.isAncestorOf(fTargetContext, context)) {
|
|
2487 |
asyncExec(new Runnable() {
|
|
2488 |
public void run() {
|
|
2489 |
updatePC(PC_RUNNING);
|
|
2490 |
firePropertyChange(PROP_SUSPENDED);
|
|
2491 |
}
|
|
2492 |
});
|
|
2493 |
}
|
|
2494 |
}
|
|
2495 |
|
|
2496 |
private void attachBreakpointsAnnotationModel() {
|
|
2497 |
IAnnotationModel annotationModel = fViewer.getAnnotationModel();
|
|
2498 |
if (annotationModel instanceof IAnnotationModelExtension) {
|
|
2499 |
IAnnotationModelExtension ame= (IAnnotationModelExtension) annotationModel;
|
|
2500 |
ame.addAnnotationModel(BREAKPOINT_ANNOTATIONS, new BreakpointsAnnotationModel());
|
|
2501 |
}
|
|
2502 |
}
|
|
2503 |
|
|
2504 |
private void refreshView(int delay) {
|
|
2505 |
if (fViewer == null || fRefreshViewPending || fRefreshAll) {
|
|
2506 |
return;
|
|
2507 |
}
|
|
2508 |
fRunnableQueue.clear();
|
|
2509 |
fRefreshViewPending = true;
|
|
2510 |
final long refreshViewScheduled = System.currentTimeMillis() + delay;
|
|
2511 |
final Runnable refresh = new Runnable() {
|
|
2512 |
public void run() {
|
|
2513 |
fRefreshViewPending = false;
|
|
2514 |
long now = System.currentTimeMillis();
|
|
2515 |
if (now >= refreshViewScheduled) {
|
|
2516 |
if (DEBUG) System.err.println("*** refreshing view ***"); //$NON-NLS-1$
|
|
2517 |
fFocusAddress = PC_UNKNOWN;
|
|
2518 |
int targetFrame= fTargetFrame;
|
|
2519 |
resetViewer();
|
|
2520 |
if (fScrollPos != null) {
|
|
2521 |
fScrollPos.isDeleted = true;
|
|
2522 |
}
|
|
2523 |
gotoFrame(targetFrame);
|
|
2524 |
} else {
|
|
2525 |
refreshView((int)(refreshViewScheduled - now));
|
|
2526 |
}
|
|
2527 |
}};
|
|
2528 |
if (delay > 0) {
|
|
2529 |
invokeLater(delay, new Runnable() {
|
|
2530 |
public void run() {
|
|
2531 |
doScrollLocked(refresh);
|
|
2532 |
}});
|
|
2533 |
} else {
|
|
2534 |
doScrollLocked(refresh);
|
|
2535 |
}
|
|
2536 |
}
|
|
2537 |
|
|
2538 |
private void resetViewer() {
|
|
2539 |
// clear all state and cache
|
|
2540 |
fPCAnnotationUpdatePending = false;
|
|
2541 |
fGotoFramePending = false;
|
|
2542 |
fPCAddress = fFrameAddress = PC_RUNNING;
|
|
2543 |
fTargetFrame = -1;
|
|
2544 |
fGotoAddressPending = fFocusAddress;
|
|
2545 |
fFocusAddress = PC_UNKNOWN;
|
|
2546 |
setFocusPosition(null);
|
|
2547 |
fPCHistory.clear();
|
|
2548 |
fPendingPCUpdates.clear();
|
|
2549 |
fFile2Storage.clear();
|
|
2550 |
DisassemblyDocument doc= fDocument;
|
|
2551 |
fDocument = createDocument();
|
|
2552 |
fViewer.setDocument(fDocument, new AnnotationModel());
|
|
2553 |
doc.dispose();
|
|
2554 |
if (fDebugSessionId != null) {
|
|
2555 |
attachBreakpointsAnnotationModel();
|
|
2556 |
fDocument.insertInvalidAddressRange(0, 0, fStartAddress, fEndAddress);
|
|
2557 |
}
|
|
2558 |
}
|
|
2559 |
|
|
2560 |
private AddressRangePosition getPCPosition(BigInteger address) {
|
|
2561 |
if (address.compareTo(BigInteger.ZERO) < 0) {
|
|
2562 |
// invalid address
|
|
2563 |
return null;
|
|
2564 |
}
|
|
2565 |
AddressRangePosition pos = getPositionOfAddress(address);
|
|
2566 |
if (pos == null || !pos.fValid) {
|
|
2567 |
// invalid disassembly line
|
|
2568 |
return null;
|
|
2569 |
}
|
|
2570 |
if (pos.length > 0) {
|
|
2571 |
// valid disassembly line
|
|
2572 |
return pos;
|
|
2573 |
}
|
|
2574 |
// hidden disassembly
|
|
2575 |
if (!(pos instanceof DisassemblyPosition)) {
|
|
2576 |
return pos;
|
|
2577 |
}
|
|
2578 |
String srcFile = ((DisassemblyPosition)pos).getFile();
|
|
2579 |
if (srcFile == null) {
|
|
2580 |
return pos;
|
|
2581 |
}
|
|
2582 |
SourceFileInfo fi = fDocument.getSourceInfo(srcFile);
|
|
2583 |
if (fi == null) {
|
|
2584 |
return pos;
|
|
2585 |
}
|
|
2586 |
if (fi.fSource == null) {
|
|
2587 |
if (fi.fError != null) {
|
|
2588 |
// could not read source
|
|
2589 |
return pos;
|
|
2590 |
}
|
|
2591 |
return null;
|
|
2592 |
}
|
|
2593 |
// if (!fi.fValid) {
|
|
2594 |
// // need line info first
|
|
2595 |
// return null;
|
|
2596 |
// }
|
|
2597 |
// determine stmt line of source range
|
|
2598 |
try {
|
|
2599 |
int stmtLine = ((DisassemblyPosition)pos).getLine();
|
|
2600 |
if (stmtLine < 0) {
|
|
2601 |
return pos;
|
|
2602 |
}
|
|
2603 |
BigInteger stmtAddress = fi.fLine2Addr[stmtLine];
|
|
2604 |
if (stmtAddress.compareTo(BigInteger.ZERO) < 0) {
|
|
2605 |
return pos;
|
|
2606 |
}
|
|
2607 |
SourcePosition srcPos = fDocument.getSourcePosition(stmtAddress);
|
|
2608 |
if (srcPos == null) {
|
|
2609 |
return pos;
|
|
2610 |
} else if (!srcPos.fValid) {
|
|
2611 |
return null;
|
|
2612 |
}
|
|
2613 |
assert stmtLine >= srcPos.fLine;
|
|
2614 |
int baseOffset = fi.fSource.getLineOffset(srcPos.fLine);
|
|
2615 |
IRegion stmtLineRegion = fi.fSource.getLineInformation(stmtLine);
|
|
2616 |
int lineOffset = stmtLineRegion.getOffset();
|
|
2617 |
int offset = srcPos.offset + lineOffset - baseOffset;
|
|
2618 |
int length = stmtLineRegion.getLength() + 1;
|
|
2619 |
if (offset >= srcPos.offset && offset < srcPos.offset + srcPos.length) {
|
|
2620 |
return new AddressRangePosition(offset, length, address, BigInteger.ZERO);
|
|
2621 |
}
|
|
2622 |
} catch (BadLocationException e) {
|
|
2623 |
internalError(e);
|
|
2624 |
}
|
|
2625 |
return pos;
|
|
2626 |
}
|
|
2627 |
|
|
2628 |
/**
|
|
2629 |
* Update the annotation indicating the given address.
|
|
2630 |
* @return a position which denotes the documents position
|
|
2631 |
*/
|
|
2632 |
private AddressRangePosition updateAddressAnnotation(Annotation annotation, BigInteger address) {
|
|
2633 |
IAnnotationModel annotationModel = fViewer.getAnnotationModel();
|
|
2634 |
annotationModel.removeAnnotation(annotation);
|
|
2635 |
AddressRangePosition pos = getPCPosition(address);
|
|
2636 |
if (pos != null) {
|
|
2637 |
annotationModel.addAnnotation(annotation, new Position(pos.offset, Math.max(0, pos.length-1)));
|
|
2638 |
}
|
|
2639 |
return pos;
|
|
2640 |
}
|
|
2641 |
|
|
2642 |
public IBreakpoint[] getBreakpointsAtLine(int line) {
|
|
2643 |
BreakpointsAnnotationModel bpModel= null;
|
|
2644 |
IAnnotationModel am= fViewer.getAnnotationModel();
|
|
2645 |
if (am instanceof IAnnotationModelExtension) {
|
|
2646 |
IAnnotationModelExtension ame= (IAnnotationModelExtension) am;
|
|
2647 |
bpModel= (BreakpointsAnnotationModel) ame.getAnnotationModel(BREAKPOINT_ANNOTATIONS);
|
|
2648 |
if (bpModel != null) {
|
|
2649 |
IRegion lineRegion;
|
|
2650 |
try {
|
|
2651 |
lineRegion= fDocument.getLineInformation(line);
|
|
2652 |
} catch (BadLocationException exc) {
|
|
2653 |
return null;
|
|
2654 |
}
|
|
2655 |
int offset= lineRegion.getOffset();
|
|
2656 |
int length= lineRegion.getLength();
|
|
2657 |
@SuppressWarnings("unchecked")
|
|
2658 |
Iterator<SimpleMarkerAnnotation> it= bpModel.getAnnotationIterator(offset, length, true, true);
|
|
2659 |
List<IBreakpoint> bpList= new ArrayList<IBreakpoint>(5);
|
|
2660 |
final IBreakpointManager bpMgr= DebugPlugin.getDefault().getBreakpointManager();
|
|
2661 |
while (it.hasNext()) {
|
|
2662 |
final SimpleMarkerAnnotation annotation= it.next();
|
|
2663 |
IBreakpoint bp= bpMgr.getBreakpoint(annotation.getMarker());
|
|
2664 |
if (bp != null) {
|
|
2665 |
bpList.add(bp);
|
|
2666 |
}
|
|
2667 |
}
|
|
2668 |
if (bpList.size() > 0) {
|
|
2669 |
return bpList.toArray(new IBreakpoint[bpList.size()]);
|
|
2670 |
}
|
|
2671 |
}
|
|
2672 |
}
|
|
2673 |
return null;
|
|
2674 |
}
|
|
2675 |
|
|
2676 |
private void gotoFrame(int frame, BigInteger address) {
|
|
2677 |
if (DEBUG) System.out.println("gotoFrame " + frame + " " + getAddressText(address)); //$NON-NLS-1$ //$NON-NLS-2$
|
|
2678 |
fTargetFrame = frame;
|
|
2679 |
fFrameAddress = address;
|
|
2680 |
if (fTargetFrame == -1) {
|
|
2681 |
fTargetFrame = getActiveStackFrame();
|
|
2682 |
if (fTargetFrame < 0 && isSuspended(fTargetContext)) {
|
|
2683 |
fTargetFrame= 0;
|
|
2684 |
}
|
|
2685 |
if (fTargetFrame == -1) {
|
|
2686 |
fGotoFramePending = false;
|
|
2687 |
return;
|
|
2688 |
}
|
|
2689 |
}
|
|
2690 |
fGotoFramePending = true;
|
|
2691 |
if (frame == 0) {
|
|
2692 |
fPCAddress = fFrameAddress;
|
|
2693 |
}
|
|
2694 |
if (fFrameAddress.compareTo(PC_UNKNOWN) == 0) {
|
|
2695 |
if (!fUpdatePending) {
|
|
2696 |
fGotoFramePending = false;
|
|
2697 |
retrieveFrameAddress(fTargetContext, fTargetFrame);
|
|
2698 |
}
|
|
2699 |
return;
|
|
2700 |
}
|
|
2701 |
AddressRangePosition pcPos = updatePCAnnotation();
|
|
2702 |
if (pcPos == null && fFrameAddress.compareTo(BigInteger.ZERO) >= 0) {
|
|
2703 |
pcPos = getPCPosition(fFrameAddress);
|
|
2704 |
if (pcPos == null) {
|
|
2705 |
gotoAddress(fFrameAddress);
|
|
2706 |
return;
|
|
2707 |
}
|
|
2708 |
}
|
|
2709 |
if (pcPos != null) {
|
|
2710 |
if (frame == 0) {
|
|
2711 |
addToPCHistory(pcPos);
|
|
2712 |
}
|
|
2713 |
fGotoFramePending = false;
|
|
2714 |
if (fGotoAddressPending == fFrameAddress) {
|
|
2715 |
fGotoAddressPending = PC_UNKNOWN;
|
|
2716 |
}
|
|
2717 |
// if (DEBUG) System.out.println("pc updated "+getAddressText(address)); //$NON-NLS-1$
|
|
2718 |
gotoPosition(pcPos, false);
|
|
2719 |
updateVisibleArea();
|
|
2720 |
} else {
|
|
2721 |
// give up
|
|
2722 |
fGotoFramePending = false;
|
|
2723 |
fGotoAddressPending = PC_UNKNOWN;
|
|
2724 |
}
|
|
2725 |
doPendingPCUpdates();
|
|
2726 |
}
|
|
2727 |
|
|
2728 |
/*
|
|
2729 |
* @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyPart#isActive()
|
|
2730 |
*/
|
|
2731 |
public final boolean isActive() {
|
|
2732 |
return fActive;
|
|
2733 |
}
|
|
2734 |
|
|
2735 |
/*
|
|
2736 |
* @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyPart#isConnected()
|
|
2737 |
*/
|
|
2738 |
public final boolean isConnected() {
|
|
2739 |
return fDebugSessionId != null && fTargetContext != null;
|
|
2740 |
}
|
|
2741 |
|
|
2742 |
/*
|
|
2743 |
* @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyPart#isSuspended()
|
|
2744 |
*/
|
|
2745 |
public final boolean isSuspended() {
|
|
2746 |
return isConnected() && isSuspended(fTargetContext);
|
|
2747 |
}
|
|
2748 |
|
|
2749 |
/*
|
|
2750 |
* @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyPart#getTextViewer()
|
|
2751 |
*/
|
|
2752 |
public final ISourceViewer getTextViewer() {
|
|
2753 |
return fViewer;
|
|
2754 |
}
|
|
2755 |
|
|
2756 |
/*
|
|
2757 |
* @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyPart#addRulerContextMenuListener(org.eclipse.jface.action.IMenuListener)
|
|
2758 |
*/
|
|
2759 |
public final void addRulerContextMenuListener(IMenuListener listener) {
|
|
2760 |
fRulerContextMenuListeners.add(listener);
|
|
2761 |
}
|
|
2762 |
|
|
2763 |
/*
|
|
2764 |
* @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyPart#removeRulerContextMenuListener(org.eclipse.jface.action.IMenuListener)
|
|
2765 |
*/
|
|
2766 |
public final void removeRulerContextMenuListener(IMenuListener listener) {
|
|
2767 |
fRulerContextMenuListeners.remove(listener);
|
|
2768 |
}
|
|
2769 |
|
|
2770 |
private boolean isSuspended(final IExecutionDMContext targetContext) {
|
|
2771 |
DsfSession session = getSession();
|
|
2772 |
if (session == null || !session.isActive()) {
|
|
2773 |
return false;
|
|
2774 |
}
|
|
2775 |
if (session.getExecutor().isInExecutorThread()) {
|
|
2776 |
return getRunControl().isSuspended(targetContext);
|
|
2777 |
}
|
|
2778 |
Query<Boolean> query = new Query<Boolean>() {
|
|
2779 |
@Override
|
|
2780 |
protected void execute(DataRequestMonitor<Boolean> rm) {
|
|
2781 |
try {
|
|
2782 |
rm.setData(getRunControl().isSuspended(targetContext));
|
|
2783 |
} finally {
|
|
2784 |
rm.done();
|
|
2785 |
}
|
|
2786 |
}
|
|
2787 |
};
|
|
2788 |
session.getExecutor().execute(query);
|
|
2789 |
try {
|
|
2790 |
return query.get();
|
|
2791 |
} catch (InterruptedException exc) {
|
|
2792 |
} catch (ExecutionException exc) {
|
|
2793 |
}
|
|
2794 |
return false;
|
|
2795 |
}
|
|
2796 |
|
|
2797 |
private IRunControl getRunControl() {
|
|
2798 |
return getService(IRunControl.class);
|
|
2799 |
}
|
|
2800 |
|
|
2801 |
/*default*/ DsfSession getSession() {
|
|
2802 |
return DsfSession.getSession(fDebugSessionId);
|
|
2803 |
}
|
|
2804 |
|
|
2805 |
/*default*/ <V> V getService(Class<V> serviceClass) {
|
|
2806 |
if (fServicesTracker != null) {
|
|
2807 |
return fServicesTracker.getService(serviceClass);
|
|
2808 |
}
|
|
2809 |
return null;
|
|
2810 |
}
|
|
2811 |
|
|
2812 |
/*default*/ IFrameDMContext getTargetFrameContext() {
|
|
2813 |
return fTargetFrameContext;
|
|
2814 |
}
|
|
2815 |
|
|
2816 |
/**
|
|
2817 |
* Schedule the retrieval of a module time stamp for the given address.
|
|
2818 |
* Should return a <code>Long</code> object in case the value was computed,
|
|
2819 |
* another object to be waited on if the retrieval is in progress, <code>null</code>
|
|
2820 |
* if no time stamp could be retrieved.
|
|
2821 |
*
|
|
2822 |
* @param address
|
|
2823 |
* @return Long, Object or <code>null</code>
|
|
2824 |
*/
|
|
2825 |
synchronized Object retrieveModuleTimestamp(BigInteger address) {
|
|
2826 |
// TLETODO [disassembly] retrieve and cache module time stamp
|
|
2827 |
return null;
|
|
2828 |
}
|
|
2829 |
|
|
2830 |
private void setFocusPosition(Position pcPos) {
|
|
2831 |
if (fFocusPos != null) {
|
|
2832 |
fDocument.removePosition(fFocusPos);
|
|
2833 |
fFocusPos = null;
|
|
2834 |
}
|
|
2835 |
if (pcPos != null) {
|
|
2836 |
fFocusPos = new Position(pcPos.offset, pcPos.length);
|
|
2837 |
try {
|
|
2838 |
fDocument.addPosition(fFocusPos);
|
|
2839 |
} catch (BadLocationException e) {
|
|
2840 |
internalError(e);
|
|
2841 |
}
|
|
2842 |
} else {
|
|
2843 |
fFocusAddress = PC_UNKNOWN;
|
|
2844 |
}
|
|
2845 |
}
|
|
2846 |
|
|
2847 |
private void doPendingPCUpdates() {
|
|
2848 |
if (fPendingPCUpdates.isEmpty()) {
|
|
2849 |
return;
|
|
2850 |
}
|
|
2851 |
BigInteger pc;
|
|
2852 |
do {
|
|
2853 |
pc = fPendingPCUpdates.remove(0);
|
|
2854 |
if (pc.compareTo(BigInteger.ZERO) >= 0) {
|
|
2855 |
break;
|
|
2856 |
}
|
|
2857 |
} while (!fPendingPCUpdates.isEmpty());
|
|
2858 |
gotoFrame(0, pc);
|
|
2859 |
}
|
|
2860 |
|
|
2861 |
private void addToPCHistory(AddressRangePosition pcPos) {
|
|
2862 |
if (DEBUG) System.out.println("addToPCHistory "+getAddressText(pcPos.fAddressOffset)); //$NON-NLS-1$
|
|
2863 |
if (fPCHistorySizeMax <= 1) {
|
|
2864 |
return;
|
|
2865 |
}
|
|
2866 |
AddressRangePosition first = null;
|
|
2867 |
if (fPCHistory.size() > 0) {
|
|
2868 |
first = fPCHistory.getFirst();
|
|
2869 |
if (first.fAddressOffset == pcPos.fAddressOffset) {
|
|
2870 |
if (first.offset != pcPos.offset || first.length != pcPos.length) {
|
|
2871 |
fPCHistory.removeFirst();
|
|
2872 |
fViewer.invalidateTextPresentation(first.offset, first.length);
|
|
2873 |
} else {
|
|
2874 |
return;
|
|
2875 |
}
|
|
2876 |
}
|
|
2877 |
}
|
|
2878 |
// clone and add
|
|
2879 |
pcPos = new AddressRangePosition(pcPos.offset, pcPos.length, pcPos.fAddressOffset, BigInteger.ZERO);
|
|
2880 |
fPCHistory.addFirst(pcPos);
|
|
2881 |
try {
|
|
2882 |
fDocument.addPosition(pcPos);
|
|
2883 |
} catch (BadLocationException e) {
|
|
2884 |
internalError(e);
|
|
2885 |
}
|
|
2886 |
// limit to max size
|
|
2887 |
if (fPCHistory.size() > fPCHistorySizeMax) {
|
|
2888 |
AddressRangePosition last = fPCHistory.removeLast();
|
|
2889 |
fDocument.removePosition(last);
|
|
2890 |
fViewer.invalidateTextPresentation(last.offset, last.length);
|
|
2891 |
}
|
|
2892 |
// redraw
|
|
2893 |
for (Iterator<AddressRangePosition> it=fPCHistory.iterator(); it.hasNext();) {
|
|
2894 |
AddressRangePosition pos = it.next();
|
|
2895 |
fViewer.invalidateTextPresentation(pos.offset, pos.length);
|
|
2896 |
}
|
|
2897 |
}
|
|
2898 |
|
|
2899 |
/**
|
|
2900 |
* Update current pc. If a pc update is currently under way, adds this
|
|
2901 |
* address to a list of pending pc updates.
|
|
2902 |
*
|
|
2903 |
* @param pc Current pc address. -1 means retrieve pc from top frame, -2
|
|
2904 |
* means target resumed
|
|
2905 |
*/
|
|
2906 |
private void updatePC(BigInteger pc) {
|
|
2907 |
if (!fPendingPCUpdates.isEmpty()) {
|
|
2908 |
BigInteger last = fPendingPCUpdates.get(fPendingPCUpdates.size()-1);
|
|
2909 |
if (last.compareTo(BigInteger.ZERO) < 0) {
|
|
2910 |
fPendingPCUpdates.remove(fPendingPCUpdates.size()-1);
|
|
2911 |
}
|
|
2912 |
}
|
|
2913 |
fPendingPCUpdates.add(pc);
|
|
2914 |
if (fPendingPCUpdates.size() > fPCHistorySizeMax) {
|
|
2915 |
if (!fActive) {
|
|
2916 |
// if not active, we can savely remove
|
|
2917 |
// the pc updates before the history range
|
|
2918 |
fPendingPCUpdates.remove(0);
|
|
2919 |
}
|
|
2920 |
// we ignore the current goto frame request
|
|
2921 |
// and continue with the pending updates
|
|
2922 |
fGotoFramePending = false;
|
|
2923 |
}
|
|
2924 |
if (fActive) {
|
|
2925 |
if (fGotoFramePending) {
|
|
2926 |
if (!fUpdatePending) {
|
|
2927 |
gotoFrame(0, fFrameAddress);
|
|
2928 |
}
|
|
2929 |
} else {
|
|
2930 |
doPendingPCUpdates();
|
|
2931 |
}
|
|
2932 |
}
|
|
2933 |
}
|
|
2934 |
|
|
2935 |
private AddressRangePosition updatePCAnnotation() {
|
|
2936 |
if (fUpdatePending) {
|
|
2937 |
fPCAnnotationUpdatePending = true;
|
|
2938 |
return null;
|
|
2939 |
}
|
|
2940 |
AddressRangePosition pos;
|
|
2941 |
if (fTargetFrame == 0) {
|
|
2942 |
// clear secondary
|
|
2943 |
updateAddressAnnotation(fSecondaryPCAnnotation, PC_UNKNOWN);
|
|
2944 |
// set primary
|
|
2945 |
pos = updateAddressAnnotation(fPCAnnotation, fPCAddress);
|
|
2946 |
} else {
|
|
2947 |
// clear primary
|
|
2948 |
updateAddressAnnotation(fPCAnnotation, PC_UNKNOWN);
|
|
2949 |
// set secondary
|
|
2950 |
pos = updateAddressAnnotation(fSecondaryPCAnnotation, fFrameAddress);
|
|
2951 |
}
|
|
2952 |
fPCAnnotationUpdatePending = pos == null && fFrameAddress.compareTo(BigInteger.ZERO) >= 0;
|
|
2953 |
return pos;
|
|
2954 |
}
|
|
2955 |
|
|
2956 |
private void scheduleDoPending() {
|
|
2957 |
if (!fUpdatePending && !fDoPendingPosted) {
|
|
2958 |
fDoPendingPosted = true;
|
|
2959 |
invokeLater(new Runnable() {
|
|
2960 |
public void run() {
|
|
2961 |
doPending();
|
|
2962 |
fDoPendingPosted = false;
|
|
2963 |
}
|
|
2964 |
});
|
|
2965 |
}
|
|
2966 |
}
|
|
2967 |
|
|
2968 |
private void doPending() {
|
|
2969 |
if (fViewer == null || fDocument == null) {
|
|
2970 |
return;
|
|
2971 |
}
|
|
2972 |
if (fUpdateSourcePending) {
|
|
2973 |
updateInvalidSource();
|
|
2974 |
}
|
|
2975 |
boolean sourceValid= fDocument.getInvalidSource().isEmpty();
|
|
2976 |
if (sourceValid || fShowDisassembly) {
|
|
2977 |
if (fGotoFramePending) {
|
|
2978 |
gotoFrame(fTargetFrame, fFrameAddress);
|
|
2979 |
}
|
|
2980 |
}
|
|
2981 |
if (sourceValid) {
|
|
2982 |
if (fGotoAddressPending != PC_UNKNOWN) {
|
|
2983 |
gotoAddress(fGotoAddressPending);
|
|
2984 |
} else if (fGotoMarkerPending != null) {
|
|
2985 |
gotoMarker(fGotoMarkerPending);
|
|
2986 |
}
|
|
2987 |
if (fPCAnnotationUpdatePending && !fGotoFramePending) {
|
|
2988 |
updatePCAnnotation();
|
|
2989 |
}
|
|
2990 |
if (fUpdateTitlePending) {
|
|
2991 |
updateTitle();
|
|
2992 |
}
|
|
2993 |
}
|
|
2994 |
}
|
|
2995 |
|
|
2996 |
/**
|
|
2997 |
* Safely run given runnable in a state when no update is pending.
|
|
2998 |
* Delays execution by 10 ms if update is currently pending.
|
|
2999 |
* @param doit
|
|
3000 |
*/
|
|
3001 |
private void doScrollLocked(final Runnable doit) {
|
|
3002 |
if (fViewer == null || fDebugSessionId == null) {
|
|
3003 |
// disposed
|
|
3004 |
return;
|
|
3005 |
}
|
|
3006 |
if (!fActive) {
|
|
3007 |
// refresh all when becoming active again
|
|
3008 |
fRefreshViewPending= false;
|
|
3009 |
fRefreshAll = true;
|
|
3010 |
return;
|
|
3011 |
}
|
|
3012 |
if (doit != null) {
|
|
3013 |
fRunnableQueue.add(doit);
|
|
3014 |
}
|
|
3015 |
if (fUpdatePending) {
|
|
3016 |
if (fRunnableQueue.size() == 1) {
|
|
3017 |
Runnable doitlater = new Runnable() {
|
|
3018 |
public void run() {
|
|
3019 |
doScrollLocked(null);
|
|
3020 |
}};
|
|
3021 |
invokeLater(doitlater);
|
|
3022 |
}
|
|
3023 |
} else {
|
|
3024 |
fUpdatePending = true;
|
|
3025 |
lockScroller();
|
|
3026 |
try {
|
|
3027 |
ArrayList<Runnable> copy = new ArrayList<Runnable>(fRunnableQueue);
|
|
3028 |
fRunnableQueue.clear();
|
|
3029 |
for (Iterator<Runnable> iter = copy.iterator(); iter.hasNext();) {
|
|
3030 |
Runnable doitnow = iter.next();
|
|
3031 |
try {
|
|
3032 |
doitnow.run();
|
|
3033 |
} catch(Exception e) {
|
|
3034 |
internalError(e);
|
|
3035 |
}
|
|
3036 |
}
|
|
3037 |
} finally {
|
|
3038 |
fUpdatePending = false;
|
|
3039 |
unlockScroller();
|
|
3040 |
doPending();
|
|
3041 |
updateVisibleArea();
|
|
3042 |
}
|
|
3043 |
}
|
|
3044 |
}
|
|
3045 |
|
|
3046 |
private void lockScroller() {
|
|
3047 |
assert fScrollPos == null;
|
|
3048 |
if (isOpcodeRulerVisible()) {
|
|
3049 |
fRedrawControl = fViewer.getControl();
|
|
3050 |
} else {
|
|
3051 |
fRedrawControl = fViewer.getTextWidget();
|
|
3052 |
}
|
|
3053 |
fRedrawControl.setRedraw(false);
|
|
3054 |
try {
|
|
3055 |
int topOffset = fViewer.getTopIndexStartOffset();
|
|
3056 |
int topIndex = fViewer.getTopIndex();
|
|
3057 |
int bottomIndex = fViewer.getBottomIndex();
|
|
3058 |
int bottomOffset = fViewer.getBottomIndexEndOffset();
|
|
3059 |
int focusLine;
|
|
3060 |
int focusOffset;
|
|
3061 |
if (fFocusPos != null && fFocusPos.isDeleted) {
|
|
3062 |
fFocusPos = null;
|
|
3063 |
}
|
|
3064 |
if (fFocusPos != null && fFocusPos.offset >= topOffset && fFocusPos.offset <= bottomOffset) {
|
|
3065 |
focusOffset = fFocusPos.offset;
|
|
3066 |
focusLine = fDocument.getLineOfOffset(focusOffset);
|
|
3067 |
} else {
|
|
3068 |
focusLine = Math.max(0, (topIndex + bottomIndex) / 2);
|
|
3069 |
focusOffset = fDocument.getLineOffset(focusLine);
|
|
3070 |
AddressRangePosition pos = fDocument.getDisassemblyPosition(focusOffset);
|
|
3071 |
if (pos != null && !pos.fValid) {
|
|
3072 |
// don't lock position of invalid range
|
|
3073 |
focusOffset = pos.offset+pos.length;
|
|
3074 |
focusLine = fDocument.getLineOfOffset(focusOffset);
|
|
3075 |
}
|
|
3076 |
}
|
|
3077 |
fScrollPos = new Position(focusOffset);
|
|
3078 |
fScrollLine = focusLine - topIndex;
|
|
3079 |
fDocument.addPosition(fScrollPos);
|
|
3080 |
} catch (BadLocationException e) {
|
|
3081 |
// should not happen
|
|
3082 |
internalError(e);
|
|
3083 |
}
|
|
3084 |
}
|
|
3085 |
|
|
3086 |
private void unlockScroller() {
|
|
3087 |
try {
|
|
3088 |
if (fScrollPos == null) {
|
|
3089 |
return;
|
|
3090 |
}
|
|
3091 |
if (fScrollPos.isDeleted) {
|
|
3092 |
fScrollPos.isDeleted = false;
|
|
3093 |
if (fScrollPos.offset >= fDocument.getLength()) {
|
|
3094 |
fScrollPos.offset = 0;
|
|
3095 |
fScrollLine = 0;
|
|
3096 |
}
|
|
3097 |
}
|
|
3098 |
if (fFocusPos != null && (fFocusPos.isDeleted || fFocusPos.length == 0)) {
|
|
3099 |
if (fFocusAddress.compareTo(BigInteger.ZERO) >= 0) {
|
|
3100 |
fGotoAddressPending = fFocusAddress;
|
|
3101 |
setFocusPosition(getPositionOfAddress(fFocusAddress));
|
|
3102 |
}
|
|
3103 |
}
|
|
3104 |
int topLine = fDocument.getLineOfOffset(fScrollPos.offset) - fScrollLine;
|
|
3105 |
// limit text size
|
|
3106 |
int lineCount = fDocument.getNumberOfLines();
|
|
3107 |
if (lineCount > fgHighWaterMark*fBufferZone) {
|
|
3108 |
int startLine = Math.max(0, topLine-fgLowWaterMark/2*fBufferZone);
|
|
3109 |
int endLine = Math.min(lineCount-1, topLine+fgLowWaterMark/2*fBufferZone);
|
|
3110 |
fDocument.deleteLineRange(endLine, lineCount-1);
|
|
3111 |
fDocument.deleteLineRange(0, startLine);
|
|
3112 |
}
|
|
3113 |
int lineHeight = fViewer.getTextWidget().getLineHeight();
|
|
3114 |
int topPixel = topLine * lineHeight;
|
|
3115 |
if (Math.abs(fViewer.getTextWidget().getTopPixel() - topPixel) >= lineHeight) {
|
|
3116 |
fViewer.setTopIndex(topLine);
|
|
3117 |
}
|
|
3118 |
} catch (BadLocationException e) {
|
|
3119 |
// should not happen
|
|
3120 |
internalError(e);
|
|
3121 |
} finally {
|
|
3122 |
if (fScrollPos != null && fDocument != null) {
|
|
3123 |
fDocument.removePosition(fScrollPos);
|
|
3124 |
fScrollPos = null;
|
|
3125 |
}
|
|
3126 |
if (fViewer != null) {
|
|
3127 |
fRedrawControl.setRedraw(true);
|
|
3128 |
getVerticalRuler().update();
|
|
3129 |
getOverviewRuler().update();
|
|
3130 |
}
|
|
3131 |
}
|
|
3132 |
}
|
|
3133 |
|
|
3134 |
private void insertSource(SourcePosition pos) {
|
|
3135 |
if (!fShowSource) {
|
|
3136 |
fDocument.insertSource(pos, "", pos.fLine, true); //$NON-NLS-1$
|
|
3137 |
return;
|
|
3138 |
}
|
|
3139 |
SourceFileInfo fi = pos.fFileInfo;
|
|
3140 |
BigInteger address = pos.fAddressOffset;
|
|
3141 |
int lineNr = pos.fLine;
|
|
3142 |
if (fi.fError != null) {
|
|
3143 |
// handled below
|
|
3144 |
} else if (fi.fValid) {
|
|
3145 |
// assert fi.fLinesNode.isValid();
|
|
3146 |
Addr2Line a2l = fi.fAddr2Line[Addr2Line.hash(address, fi.fAddr2Line.length)];
|
|
3147 |
while (a2l != null && !a2l.addr.equals(address))
|
|
3148 |
a2l = a2l.next;
|
|
3149 |
if (a2l != null) {
|
|
3150 |
int first = a2l.first;
|
|
3151 |
int line;
|
|
3152 |
for (line = first; line <= a2l.last; ++line) {
|
|
3153 |
if (!fi.fLine2Addr[line].equals(address)) {
|
|
3154 |
if (line > first) {
|
|
3155 |
String source = fi.getLines(first, line-1);
|
|
3156 |
pos = fDocument.insertSource(pos, source, first, false);
|
|
3157 |
}
|
|
3158 |
first = line+1;
|
|
3159 |
}
|
|
3160 |
}
|
|
3161 |
if (line > first) {
|
|
3162 |
String source = fi.getLines(first, line-1);
|
|
3163 |
fDocument.insertSource(pos, source, first, true);
|
|
3164 |
if (source.length() == 0) {
|
|
3165 |
fDocument.removeSourcePosition(pos);
|
|
3166 |
}
|
|
3167 |
} else if (first > a2l.first) {
|
|
3168 |
fDocument.insertSource(pos, "", first, true); //$NON-NLS-1$
|
|
3169 |
fDocument.removeSourcePosition(pos);
|
|
3170 |
}
|
|
3171 |
} else {
|
|
3172 |
// no source at all
|
|
3173 |
fDocument.insertSource(pos, "", lineNr, true); //$NON-NLS-1$
|
|
3174 |
fDocument.removeSourcePosition(pos);
|
|
3175 |
}
|
|
3176 |
} else if (fi.fLinesNode == null) {
|
|
3177 |
// TLETODO [disassembly] asynchronous line info
|
|
3178 |
if (fi.fSource != null) {
|
|
3179 |
fi.fError= new Error();
|
|
3180 |
}
|
|
3181 |
}
|
|
3182 |
if (fi.fError != null && !pos.fValid) {
|
|
3183 |
if (fi.fSource != null) {
|
|
3184 |
if (fi.fSource != null && lineNr >= 0 && lineNr < fi.fSource.getNumberOfLines()) {
|
|
3185 |
fi.fStartAddress = fi.fStartAddress.min(pos.fAddressOffset);
|
|
3186 |
fi.fEndAddress = fi.fEndAddress.max(pos.fAddressOffset.add(pos.fAddressLength));
|
|
3187 |
if (fi.fLine2Addr[lineNr] == null || fi.fLine2Addr[lineNr].compareTo(BigInteger.ZERO) < 0) {
|
|
3188 |
fi.fLine2Addr[lineNr] = pos.fAddressOffset;
|
|
3189 |
String sourceLine = fi.getLine(lineNr);
|
|
3190 |
fDocument.insertSource(pos, sourceLine, lineNr, true);
|
|
3191 |
} else if (fi.fLine2Addr[lineNr].compareTo(pos.fAddressOffset) > 0) {
|
|
3192 |
SourcePosition oldPos = fDocument.getSourcePosition(fi.fLine2Addr[lineNr]);
|
|
3193 |
if (oldPos != null) {
|
|
3194 |
try {
|
|
3195 |
fDocument.replace(oldPos, oldPos.length, null);
|
|
3196 |
} catch (BadLocationException e) {
|
|
3197 |
internalError(e);
|
|
3198 |
}
|
|
3199 |
fDocument.removeSourcePosition(oldPos);
|
|
3200 |
}
|
|
3201 |
fi.fLine2Addr[lineNr] = pos.fAddressOffset;
|
|
3202 |
String sourceLine = fi.getLine(lineNr);
|
|
3203 |
fDocument.insertSource(pos, sourceLine, lineNr, true);
|
|
3204 |
} else if (fi.fLine2Addr[lineNr].equals(pos.fAddressOffset)) {
|
|
3205 |
String sourceLine = fi.getLine(lineNr);
|
|
3206 |
fDocument.insertSource(pos, sourceLine, lineNr, true);
|
|
3207 |
} else {
|
|
3208 |
fDocument.insertSource(pos, "", lineNr, true); //$NON-NLS-1$
|
|
3209 |
fDocument.removeSourcePosition(pos);
|
|
3210 |
}
|
|
3211 |
}
|
|
3212 |
} else {
|
|
3213 |
// no source at all
|
|
3214 |
fDocument.insertSource(pos, "", lineNr, true); //$NON-NLS-1$
|
|
3215 |
fDocument.removeSourcePosition(pos);
|
|
3216 |
}
|
|
3217 |
}
|
|
3218 |
}
|
|
3219 |
|
|
3220 |
private void updateTitle() {
|
|
3221 |
if (fDebugSessionId == null) {
|
|
3222 |
String descr = DisassemblyMessages.Disassembly_message_notConnected;
|
|
3223 |
String title = getConfigurationElement().getAttribute("name"); //$NON-NLS-1$
|
|
3224 |
setPartName(title);
|
|
3225 |
setContentDescription(descr);
|
|
3226 |
setTitleToolTip(title);
|
|
3227 |
} else {
|
|
3228 |
// TLETODO Proper content description
|
|
3229 |
setContentDescription(""); //$NON-NLS-1$
|
|
3230 |
}
|
|
3231 |
}
|
|
3232 |
|
|
3233 |
private boolean isDissemblyMixedModeOn() {
|
|
3234 |
// TLETODO [disassembly] mixed mode on/off
|
|
3235 |
return true;
|
|
3236 |
}
|
|
3237 |
|
|
3238 |
/**
|
|
3239 |
* Close this part
|
|
3240 |
*/
|
|
3241 |
protected abstract void closePart();
|
|
3242 |
|
|
3243 |
/*
|
|
3244 |
* @see org.eclipse.jface.text.ITextPresentationListener#applyTextPresentation(org.eclipse.jface.text.TextPresentation)
|
|
3245 |
*/
|
|
3246 |
@SuppressWarnings("unchecked")
|
|
3247 |
public void applyTextPresentation(TextPresentation textPresentation) {
|
|
3248 |
IRegion coverage = textPresentation.getExtent();
|
|
3249 |
if (coverage == null) {
|
|
3250 |
coverage= new Region(0, fDocument.getLength());
|
|
3251 |
}
|
|
3252 |
int startOffset = coverage.getOffset();
|
|
3253 |
int length = coverage.getLength();
|
|
3254 |
int endOffset = startOffset + length;
|
|
3255 |
Iterator<Position> it;
|
|
3256 |
try {
|
|
3257 |
// make sure we start with first overlapping position
|
|
3258 |
AddressRangePosition pos = fDocument.getModelPosition(startOffset);
|
|
3259 |
assert pos != null;
|
|
3260 |
if (pos == null) {
|
|
3261 |
return;
|
|
3262 |
}
|
|
3263 |
it = fDocument.getPositionIterator(DisassemblyDocument.CATEGORY_MODEL, pos.offset);
|
|
3264 |
} catch (BadPositionCategoryException e) {
|
|
3265 |
return;
|
|
3266 |
} catch (BadLocationException e) {
|
|
3267 |
return;
|
|
3268 |
}
|
|
3269 |
ArrayList<StyleRange> styleRanges = new ArrayList<StyleRange>();
|
|
3270 |
while(it.hasNext()) {
|
|
3271 |
AddressRangePosition pos = (AddressRangePosition)it.next();
|
|
3272 |
if (pos.offset >= endOffset) {
|
|
3273 |
break;
|
|
3274 |
}
|
|
3275 |
if (pos.offset+pos.length <= startOffset) {
|
|
3276 |
continue;
|
|
3277 |
}
|
|
3278 |
if (pos.fValid && pos.length > 0) {
|
|
3279 |
if (pos instanceof DisassemblyPosition) {
|
|
3280 |
DisassemblyPosition disPos = (DisassemblyPosition)pos;
|
|
3281 |
styleRanges.add(new StyleRange(pos.offset, disPos.length, fInstructionColor, null, SWT.NULL));
|
|
3282 |
} else if (pos instanceof ErrorPosition) {
|
|
3283 |
styleRanges.add(new StyleRange(pos.offset, pos.length, fErrorColor, null, SWT.NULL));
|
|
3284 |
} else if (pos instanceof LabelPosition) {
|
|
3285 |
styleRanges.add(new StyleRange(pos.offset, pos.length, fLabelColor, null, SWT.BOLD));
|
|
3286 |
} else if (pos instanceof SourcePosition) {
|
|
3287 |
SourcePosition srcPos = (SourcePosition)pos;
|
|
3288 |
TextPresentation presentation = null;
|
|
3289 |
if (srcPos.fFileInfo.fSource != null) {
|
|
3290 |
presentation = srcPos.fFileInfo.getPresentation(srcPos.fFileInfo.getRegion(srcPos.fLine, pos.length));
|
|
3291 |
}
|
|
3292 |
if (presentation != null) {
|
|
3293 |
// clip result window to coverage
|
|
3294 |
int start = Math.max(startOffset, srcPos.offset);
|
|
3295 |
int end = Math.min(endOffset, srcPos.offset + srcPos.length);
|
|
3296 |
int srcOffset = srcPos.fFileInfo.getLineOffset(srcPos.fLine);
|
|
3297 |
int clipOffset = start - srcPos.offset;
|
|
3298 |
presentation.setResultWindow(new Region(srcOffset + clipOffset, end-start));
|
|
3299 |
for (Iterator<StyleRange> iter = presentation.getNonDefaultStyleRangeIterator(); iter.hasNext();) {
|
|
3300 |
StyleRange styleRange = iter.next();
|
|
3301 |
styleRange.start += srcPos.offset + clipOffset;
|
|
3302 |
styleRanges.add(styleRange);
|
|
3303 |
}
|
|
3304 |
} else {
|
|
3305 |
styleRanges.add(new StyleRange(pos.offset, pos.length, fSourceColor, null, SWT.NULL));
|
|
3306 |
}
|
|
3307 |
}
|
|
3308 |
}
|
|
3309 |
}
|
|
3310 |
if (styleRanges.size() > 0) {
|
|
3311 |
for (Iterator<StyleRange> iter = styleRanges.iterator(); iter.hasNext();) {
|
|
3312 |
textPresentation.addStyleRange(iter.next());
|
|
3313 |
}
|
|
3314 |
}
|
|
3315 |
// update pc history trail
|
|
3316 |
if (fPCHistory.size() > 1) {
|
|
3317 |
HSL hsv = new HSL(fPCAnnotationRGB);
|
|
3318 |
double luminanceStep = (1-hsv.luminance)/(fPCHistorySizeMax+1);
|
|
3319 |
hsv.luminance = 1 - luminanceStep * (fPCHistorySizeMax - fPCHistory.size());
|
|
3320 |
for (ListIterator<AddressRangePosition> listIt = fPCHistory.listIterator(fPCHistory.size()); listIt.hasPrevious();) {
|
|
3321 |
AddressRangePosition pcPos = listIt.previous();
|
|
3322 |
hsv.luminance -= luminanceStep;
|
|
3323 |
if (pcPos.isDeleted) {
|
|
3324 |
listIt.remove();
|
|
3325 |
continue;
|
|
3326 |
}
|
|
3327 |
if (!pcPos.fValid) {
|
|
3328 |
continue;
|
|
3329 |
}
|
|
3330 |
if (pcPos.overlapsWith(startOffset, length)) {
|
|
3331 |
RGB rgb = hsv.toRGB();
|
|
3332 |
Color pcColor = getSharedColors().getColor(rgb);
|
|
3333 |
Color textColor = null;
|
|
3334 |
// experimental: if color is dark, use white (background) as text color
|
|
3335 |
// Color textColor = hsv.luminance < 0.7 ? fViewer.getTextWidget().getBackground() : null;
|
|
3336 |
textPresentation.mergeStyleRange(new StyleRange(pcPos.offset, pcPos.length, textColor, pcColor));
|
|
3337 |
}
|
|
3338 |
}
|
|
3339 |
}
|
|
3340 |
}
|
|
3341 |
|
|
3342 |
|
|
3343 |
private IBreakpoint insertBreakpoint(int line, boolean edit) throws CoreException {
|
|
3344 |
SourcePosition srcPos = null;
|
|
3345 |
try {
|
|
3346 |
int lineOffset = fDocument.getLineOffset(line);
|
|
3347 |
srcPos = fDocument.getSourcePosition(lineOffset);
|
|
3348 |
} catch (BadLocationException e) {
|
|
3349 |
// should not happen, but its safe to ignore anyway
|
|
3350 |
}
|
|
3351 |
|
|
3352 |
IResource resource;
|
|
3353 |
ICBreakpoint bp;
|
|
3354 |
|
|
3355 |
if (srcPos != null && srcPos.length > 0) {
|
|
3356 |
SourceFileInfo srcInfo = srcPos.fFileInfo;
|
|
3357 |
String filePath = null;
|
|
3358 |
resource = (IResource)srcInfo.fFile.getAdapter(IResource.class);
|
|
3359 |
if (resource != null) {
|
|
3360 |
final IPath location= resource.getLocation();
|
|
3361 |
if (location == null) {
|
|
3362 |
return null;
|
|
3363 |
}
|
|
3364 |
filePath = location.toOSString();
|
|
3365 |
} else {
|
|
3366 |
resource = ResourcesPlugin.getWorkspace().getRoot();
|
|
3367 |
filePath = srcInfo.fFile.getFullPath().toOSString();
|
|
3368 |
}
|
|
3369 |
BigInteger address = srcPos.fAddressOffset;
|
|
3370 |
AddressRangePosition pos = fDocument.getDisassemblyPosition(address);
|
|
3371 |
int srcLine = -1;
|
|
3372 |
if (pos instanceof DisassemblyPosition) {
|
|
3373 |
srcLine = ((DisassemblyPosition)pos).getLine();
|
|
3374 |
}
|
|
3375 |
bp= CDIDebugModel.createLineBreakpoint(filePath, resource, ICBreakpointType.REGULAR, srcLine + 1, true, 0, "", true); //$NON-NLS-1$
|
|
3376 |
} else {
|
|
3377 |
resource = ResourcesPlugin.getWorkspace().getRoot();
|
|
3378 |
BigInteger address = getAddressOfLine(line);
|
|
3379 |
bp= CDIDebugModel.createAddressBreakpoint(null, null, resource, ICBreakpointType.REGULAR, new Addr64(address), true, 0, "", true); //$NON-NLS-1$
|
|
3380 |
}
|
|
3381 |
|
|
3382 |
return bp;
|
|
3383 |
}
|
|
3384 |
|
|
3385 |
private AddressRangePosition insertSource(AddressRangePosition pos, BigInteger address, final String file, int lineNr) {
|
|
3386 |
Object sourceElement = null;
|
|
3387 |
if (fFile2Storage.containsKey(file)) {
|
|
3388 |
sourceElement = fFile2Storage.get(file);
|
|
3389 |
} else {
|
|
3390 |
final ISourceLookupDMContext ctx= DMContexts.getAncestorOfType(fTargetContext, ISourceLookupDMContext.class);
|
|
3391 |
final DsfExecutor executor= getSession().getExecutor();
|
|
3392 |
Query<Object> query= new Query<Object>() {
|
|
3393 |
@Override
|
|
3394 |
protected void execute(final DataRequestMonitor<Object> rm) {
|
|
3395 |
final DataRequestMonitor<Object> request= new DataRequestMonitor<Object>(executor, rm) {
|
|
3396 |
@Override
|
|
3397 |
protected void handleSuccess() {
|
|
3398 |
rm.setData(getData());
|
|
3399 |
rm.done();
|
|
3400 |
}
|
|
3401 |
};
|
|
3402 |
final ISourceLookup lookup= getService(ISourceLookup.class);
|
|
3403 |
lookup.getSource(ctx, file, request);
|
|
3404 |
}
|
|
3405 |
};
|
|
3406 |
try {
|
|
3407 |
getSession().getExecutor().execute(query);
|
|
3408 |
sourceElement= query.get();
|
|
3409 |
} catch (InterruptedException exc) {
|
|
3410 |
internalError(exc);
|
|
3411 |
} catch (ExecutionException exc) {
|
|
3412 |
internalError(exc);
|
|
3413 |
}
|
|
3414 |
if (sourceElement instanceof File) {
|
|
3415 |
sourceElement = new LocalFileStorage((File)sourceElement);
|
|
3416 |
}
|
|
3417 |
if (sourceElement instanceof IStorage) {
|
|
3418 |
fFile2Storage.put(file, sourceElement);
|
|
3419 |
} else {
|
|
3420 |
fFile2Storage.put(file, null);
|
|
3421 |
logWarning(DisassemblyMessages.Disassembly_log_error_locateFile+file, null);
|
|
3422 |
}
|
|
3423 |
}
|
|
3424 |
if (sourceElement instanceof IStorage) {
|
|
3425 |
SourceFileInfo fi = fDocument.getSourceInfo((IStorage)sourceElement);
|
|
3426 |
if (fi == null) {
|
|
3427 |
IStorage storage = (IStorage)sourceElement;
|
|
3428 |
Display display = getSite().getShell().getDisplay();
|
|
3429 |
Runnable done = new SourceColorerJob(display, storage, this);
|
|
3430 |
fi = fDocument.createSourceInfo(file, storage, done);
|
|
3431 |
EditionFinderJob editionJob = null;
|
|
3432 |
if (storage instanceof IFile) {
|
|
3433 |
editionJob = new EditionFinderJob(fi, address, this);
|
|
3434 |
editionJob.schedule();
|
|
3435 |
}
|
|
3436 |
fi.fReadingJob.schedule();
|
|
3437 |
}
|
|
3438 |
pos = fDocument.insertInvalidSource(pos, address, fi, lineNr);
|
|
3439 |
}
|
|
3440 |
return pos;
|
|
3441 |
}
|
|
3442 |
|
|
3443 |
private void disassemblyModeChanged(boolean isDisassemblyOn) {
|
|
3444 |
if (fShowDisassembly == isDisassemblyOn) {
|
|
3445 |
return;
|
|
3446 |
}
|
|
3447 |
if (fShowDisassembly && !fSourceOnlyMode) {
|
|
3448 |
// if not in source-only mode, do not update if disassembly mode is disabled
|
|
3449 |
return;
|
|
3450 |
}
|
|
3451 |
fShowDisassembly = isDisassemblyOn;
|
|
3452 |
if (!fShowDisassembly) {
|
|
3453 |
sourceModeChanged(true);
|
|
3454 |
}
|
|
3455 |
fActionToggleSource.update();
|
|
3456 |
Runnable doit = new Runnable() {
|
|
3457 |
public void run() {
|
|
3458 |
fDocument.invalidateDisassemblyWithSource(!fShowDisassembly);
|
|
3459 |
fGotoFramePending = true;
|
|
3460 |
}};
|
|
3461 |
doScrollLocked(doit);
|
|
3462 |
}
|
|
3463 |
|
|
3464 |
/**
|
|
3465 |
* Turn on/off source mode.
|
|
3466 |
* @param isSourceModeOn
|
|
3467 |
*/
|
|
3468 |
private void sourceModeChanged(boolean isSourceModeOn) {
|
|
3469 |
if (fShowSource == isSourceModeOn) {
|
|
3470 |
return;
|
|
3471 |
}
|
|
3472 |
fShowSource = isSourceModeOn;
|
|
3473 |
fActionToggleSource.update();
|
|
3474 |
fDocument.invalidateSource();
|
|
3475 |
if (!fShowSource && !fShowDisassembly) {
|
|
3476 |
disassemblyModeChanged(true);
|
|
3477 |
} else {
|
|
3478 |
fPCAnnotationUpdatePending = true;
|
|
3479 |
updateInvalidSource();
|
|
3480 |
}
|
|
3481 |
}
|
|
3482 |
|
|
3483 |
public static BigInteger decodeAddress(String string) {
|
|
3484 |
if (string.startsWith("0x")) { //$NON-NLS-1$
|
|
3485 |
return new BigInteger(string.substring(2), 16);
|
|
3486 |
}
|
|
3487 |
return new BigInteger(string);
|
|
3488 |
}
|
|
3489 |
|
|
3490 |
private static String getAddressText(BigInteger address) {
|
|
3491 |
if (address == null) {
|
|
3492 |
return "<null>"; //$NON-NLS-1$
|
|
3493 |
}
|
|
3494 |
if (address.compareTo(BigInteger.ZERO) < 0) {
|
|
3495 |
return address.toString();
|
|
3496 |
}
|
|
3497 |
String hex = address.toString(16);
|
|
3498 |
return "0x" + "0000000000000000".substring(hex.length() + (address.bitLength() <= 32 ? 8 : 0)) + hex; //$NON-NLS-1$ //$NON-NLS-2$
|
|
3499 |
}
|
|
3500 |
|
|
3501 |
static void internalError(Throwable e) {
|
|
3502 |
if (DEBUG) {
|
|
3503 |
System.err.println("Disassembly: Internal error"); //$NON-NLS-1$
|
|
3504 |
e.printStackTrace();
|
|
3505 |
}
|
|
3506 |
}
|
|
3507 |
|
|
3508 |
}
|