1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

[302772] Refactor DSF Disassembly view to support CDI

This commit is contained in:
John Cortell 2010-02-15 15:34:31 +00:00
parent c569861751
commit eddb058986
31 changed files with 2742 additions and 998 deletions

View file

@ -10,6 +10,7 @@ Export-Package:
org.eclipse.cdt.debug.internal.ui;x-internal:=true, org.eclipse.cdt.debug.internal.ui;x-internal:=true,
org.eclipse.cdt.debug.internal.ui.actions;x-internal:=true, org.eclipse.cdt.debug.internal.ui.actions;x-internal:=true,
org.eclipse.cdt.debug.internal.ui.dialogfields;x-internal:=true, org.eclipse.cdt.debug.internal.ui.dialogfields;x-internal:=true,
org.eclipse.cdt.debug.internal.ui.disassembly.dsf;x-friends:="org.eclipse.cdt.dsf.ui",
org.eclipse.cdt.debug.internal.ui.editors;x-internal:=true, org.eclipse.cdt.debug.internal.ui.editors;x-internal:=true,
org.eclipse.cdt.debug.internal.ui.preferences;x-internal:=true, org.eclipse.cdt.debug.internal.ui.preferences;x-internal:=true,
org.eclipse.cdt.debug.internal.ui.propertypages;x-internal:=true, org.eclipse.cdt.debug.internal.ui.propertypages;x-internal:=true,

View file

@ -1,5 +1,5 @@
############################################################################### ###############################################################################
# Copyright (c) 2003, 2009 QNX Software Systems and others. # Copyright (c) 2003, 2010 QNX Software Systems and others.
# All rights reserved. This program and the accompanying materials # All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0 # are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at # which accompanies this distribution, and is available at
@ -41,3 +41,6 @@ CDTDebugModelPresentation.25=(disabled)
CBreakpointWorkbenchAdapterFactory.0=C/C++ breakpoint CBreakpointWorkbenchAdapterFactory.0=C/C++ breakpoint
CBreakpointWorkbenchAdapterFactory.1=C/C++ watchpoint CBreakpointWorkbenchAdapterFactory.1=C/C++ watchpoint
ErrorStatusHandler.1=Error ErrorStatusHandler.1=Error
DisassemblyBackendCdi_Symbol_Evaluation_Unusable=Expression \"{0}\" evaluated to an unusable value.
DisassemblyBackendCdi_Symbol_Didnt_Evaluate=Expression \"{0}\" could not be evaluated.
DisassemblyBackendCdi_Error_Dlg_Title=Error

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007 Wind River Systems and others. * Copyright (c) 2007, 2010 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -8,7 +8,7 @@
* Contributors: * Contributors:
* Wind River Systems - initial API and implementation * Wind River Systems - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model; package org.eclipse.cdt.debug.internal.ui.disassembly.dsf;
import java.math.BigInteger; import java.math.BigInteger;
@ -63,4 +63,15 @@ public class AddressRangePosition extends Position {
// identity comparison // identity comparison
return this == other; return this == other;
} }
/* (non-Javadoc)
* @see org.eclipse.jface.text.Position#toString()
*/
@Override
public String toString() {
return getClass().getSimpleName() + '@' + Integer.toHexString(System.identityHashCode(this))
+ (fValid ? "" : "[INVALID]") //$NON-NLS-1$ //$NON-NLS-2$
+ '[' + offset + ':' + length + "]->[" + fAddressOffset //$NON-NLS-1$
+ ':' + fAddressLength + ']';
}
} }

View file

@ -0,0 +1,105 @@
/*******************************************************************************
* Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Anton Leherbauer (Wind River Systems) - initial API and implementation
* Freescale Semiconductor - refactoring
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.disassembly.dsf;
import java.math.BigInteger;
import org.eclipse.cdt.debug.core.cdi.CDIException;
import org.eclipse.cdt.debug.core.cdi.model.ICDIInstruction;
import org.eclipse.cdt.debug.core.cdi.model.ICDIMixedInstruction;
import org.eclipse.cdt.debug.core.cdi.model.ICDITarget;
import org.eclipse.cdt.debug.core.model.ICDebugTarget;
import org.eclipse.cdt.debug.core.model.ICStackFrame;
import org.eclipse.cdt.debug.core.model.IDisassemblyBlock;
import org.eclipse.cdt.debug.internal.core.model.DisassemblyBlock;
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.swt.widgets.Display;
/**
*/
public class CDIDisassemblyRetrieval implements IDisassemblyRetrieval {
private ICDebugTarget fDebugTarget;
/**
* Constructor
*/
public CDIDisassemblyRetrieval(ICDebugTarget debugTarget) {
fDebugTarget= debugTarget;
}
/*
* @see org.eclipse.cdt.debug.ui.infinitedisassembly.views.IDisassemblyRetrieval#asyncGetDisassembly(java.math.BigInteger, java.math.BigInteger, java.lang.String, int, org.eclipse.cdt.debug.ui.infinitedisassembly.views.IDisassemblyRetrieval.DisassemblyRequest)
*/
public void asyncGetDisassembly(final BigInteger startAddress, final BigInteger endAddress, final String file, final int lineNumber, final int lines, final DisassemblyRequest disassemblyRequest) {
Runnable op= new Runnable() {
public void run() {
ICDITarget cdiTarget= (ICDITarget) fDebugTarget.getAdapter(ICDITarget.class);
try {
ICDIMixedInstruction[] mixedInstructions= null;
ICDIInstruction[] asmInstructions= null;
if (file != null) {
mixedInstructions= cdiTarget.getMixedInstructions(file, lineNumber, lines);
}
else if (startAddress != null) {
mixedInstructions= cdiTarget.getMixedInstructions(startAddress, endAddress);
if (mixedInstructions.length == 0) {
mixedInstructions= null;
asmInstructions= cdiTarget.getInstructions(startAddress, endAddress);
} else if (mixedInstructions.length == 1 && mixedInstructions[0].getInstructions().length == 0) {
mixedInstructions= null;
asmInstructions= cdiTarget.getInstructions(startAddress, endAddress);
}
}
if (mixedInstructions != null) {
IDisassemblyBlock block= DisassemblyBlock.create(fDebugTarget.getDisassembly(), mixedInstructions);
disassemblyRequest.setDisassemblyBlock(block);
} else if (asmInstructions != null) {
IDisassemblyBlock block= DisassemblyBlock.create(fDebugTarget.getDisassembly(), asmInstructions);
disassemblyRequest.setDisassemblyBlock(block);
}
} catch (CDIException exc) {
disassemblyRequest.setStatus(new Status(IStatus.ERROR, CDebugUIPlugin.getUniqueIdentifier(), exc.getDetailMessage(), exc));
} catch (DebugException exc) {
disassemblyRequest.setStatus(new Status(IStatus.ERROR, CDebugUIPlugin.getUniqueIdentifier(), exc.getMessage(), exc));
} finally {
disassemblyRequest.done();
}
}
};
Display.getDefault().asyncExec(op);
}
/*
* @see org.eclipse.cdt.debug.ui.infinitedisassembly.views.IDisassemblyRetrieval#asyncGetFrameAddress(org.eclipse.debug.core.model.IStackFrame, org.eclipse.cdt.debug.ui.infinitedisassembly.views.IDisassemblyRetrieval.AddressRequest)
*/
public void asyncGetFrameAddress(final IStackFrame stackFrame, final AddressRequest addressRequest) {
Runnable op= new Runnable() {
public void run() {
if (stackFrame instanceof ICStackFrame) {
addressRequest.setAddress(((ICStackFrame)stackFrame).getAddress().getValue());
} else {
addressRequest.cancel();
}
addressRequest.done();
}
};
Display.getDefault().asyncExec(op);
}
}

View file

@ -0,0 +1,555 @@
/*******************************************************************************
* Copyright (c) 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
* Freescale Semiconductor - refactoring
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.disassembly.dsf;
import java.math.BigInteger;
import org.eclipse.cdt.debug.core.cdi.CDIException;
import org.eclipse.cdt.debug.core.cdi.model.ICDIExpression;
import org.eclipse.cdt.debug.core.model.IAsmInstruction;
import org.eclipse.cdt.debug.core.model.IAsmSourceLine;
import org.eclipse.cdt.debug.core.model.ICDebugElement;
import org.eclipse.cdt.debug.core.model.ICDebugTarget;
import org.eclipse.cdt.debug.core.model.ICStackFrame;
import org.eclipse.cdt.debug.core.model.ICThread;
import org.eclipse.cdt.debug.core.model.ICType;
import org.eclipse.cdt.debug.core.model.ICValue;
import org.eclipse.cdt.debug.core.model.IDisassemblyBlock;
import org.eclipse.cdt.debug.internal.core.model.CDebugTarget;
import org.eclipse.cdt.debug.internal.core.model.CExpression;
import org.eclipse.cdt.debug.internal.core.model.CStackFrame;
import org.eclipse.cdt.debug.internal.ui.CDebugUIMessages;
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Position;
import com.ibm.icu.text.MessageFormat;
/**
* The CDI backend to the DSF disassembly view.
*
*/
public class DisassemblyBackendCdi implements IDisassemblyBackend, IDebugEventSetListener {
private IDisassemblyPartCallback fCallback;
private ICThread fTargetContext;
private String fCdiSessionId;
private ICStackFrame fTargetFrameContext;
private CDIDisassemblyRetrieval fDisassemblyRetrieval;
public DisassemblyBackendCdi() {
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#init(org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback)
*/
public void init(IDisassemblyPartCallback callback) {
assert callback != null;
fCallback = callback;
DebugPlugin.getDefault().addDebugEventListener(this);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#hasDebugContext()
*/
public boolean hasDebugContext() {
return fTargetContext != null;
}
/**
* Unlike DSF, CDI sessions don't have an ID. But to appease the DSF
* Disassembly view, we fabricate one.
*
* @param debugElement
* the debug element which represents the process being debugged
* @return the session ID
*/
private String getSessionId(ICDebugElement debugElement) {
return "cdi-" + System.identityHashCode(debugElement.getDebugTarget()); //$NON-NLS-1$
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#setDebugContext(org.eclipse.core.runtime.IAdaptable)
*/
public SetDebugContextResult setDebugContext(IAdaptable context) {
assert supportsDebugContext(context) : "caller should not have invoked us"; //$NON-NLS-1$
SetDebugContextResult result = new SetDebugContextResult();
result.sessionId = fCdiSessionId; // initial value; may change
ICDebugTarget cdiDebugTarget = (ICDebugTarget)((ICDebugElement)context).getDebugTarget();
String cdiSessionId = getSessionId(cdiDebugTarget);
fDisassemblyRetrieval = new CDIDisassemblyRetrieval(cdiDebugTarget);
if (!cdiSessionId.equals(fCdiSessionId)) {
fTargetContext = null;
if (context instanceof ICStackFrame) {
fTargetFrameContext = (ICStackFrame)context;
fTargetContext = (ICThread)fTargetFrameContext.getThread();
try {
// CDI frame levels are ordered opposite of DSF. Frame 0 is the
// root frame of the thread where in DSF it's the topmost frame
// (where the PC is). Do a little math to flip reverse the value
result.frameLevel = ((CStackFrame)((fTargetContext.getTopStackFrame()))).getLevel() - fTargetFrameContext.getLevel();
} catch (DebugException e) {
}
}
if (fTargetContext != null) {
result.sessionId = fCdiSessionId = cdiSessionId;
result.contextChanged = true;
}
}
else if (context instanceof ICStackFrame) {
if (context instanceof ICStackFrame) {
fTargetFrameContext = (ICStackFrame)context;
fTargetContext = (ICThread)fTargetFrameContext.getThread();
try {
// CDI frame levels are ordered opposite of DSF. Frame 0 is the
// root frame of the thread where in DSF it's the topmost frame
// (where the PC is). Do a little math to flip reverse the value
result.frameLevel = ((CStackFrame)((fTargetContext.getTopStackFrame()))).getLevel() - fTargetFrameContext.getLevel();
} catch (DebugException e) {
}
fCallback.gotoFrame(result.frameLevel);
}
}
return result;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#supportsDebugContext(org.eclipse.core.runtime.IAdaptable)
*/
public boolean supportsDebugContext(IAdaptable context) {
return supportsDebugContext_(context);
}
/**
* @param context
* @return
*/
public static boolean supportsDebugContext_(IAdaptable context) {
return (context != null) && (context.getAdapter(ICDebugElement.class) != null);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#clearDebugContext()
*/
public void clearDebugContext() {
fTargetContext= null;
fCdiSessionId = null;
fTargetFrameContext = null;
fDisassemblyRetrieval = null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#retrieveFrameAddress(int)
*/
public void retrieveFrameAddress(final int targetFrame) {
try {
IStackFrame stackFrame= fTargetContext.getStackFrames()[targetFrame];
fDisassemblyRetrieval.asyncGetFrameAddress(stackFrame, new IDisassemblyRetrieval.AddressRequest() {
@Override
public void done() {
fCallback.setUpdatePending(false);
if (!isCanceled()) {
BigInteger address= getAddress();
if (targetFrame == 0) {
fCallback.updatePC(address);
} else {
fCallback.gotoFrame(targetFrame, address);
}
}
}
});
} catch (DebugException exc) {
DisassemblyUtils.internalError(exc);
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#getFrameLevel()
*/
public int getFrameLevel() {
return fTargetFrameContext.getLevel();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#isSuspended()
*/
public boolean isSuspended() {
return fTargetContext != null && fTargetContext.isSuspended();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#getFrameFile()
*/
public String getFrameFile() {
return fTargetFrameContext != null ? fTargetFrameContext.getFile() : null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#getFrameLine()
*/
public int getFrameLine() {
return fTargetFrameContext.getFrameLineNumber();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyBackend#retrieveDisassembly(java.math.BigInteger, java.math.BigInteger, java.lang.String, boolean, boolean, boolean, int, int, int)
*/
public void retrieveDisassembly(final BigInteger startAddress,
BigInteger endAddress, String file, int lineNumber, int lines, final boolean mixed,
final boolean showSymbols, final boolean showDisassembly, int linesHint) {
if (fTargetContext == null || fTargetContext.isTerminated()) {
return;
}
final BigInteger addressLength= BigInteger.valueOf(lines * 4);
if (endAddress.subtract(startAddress).compareTo(addressLength) > 0) {
endAddress= startAddress.add(addressLength);
}
final BigInteger finalEndAddress= endAddress;
final IDisassemblyRetrieval.DisassemblyRequest disassemblyRequest= new IDisassemblyRetrieval.DisassemblyRequest() {
@Override
public void done() {
if (!isCanceled() && getDisassemblyBlock() != null) {
insertDisassembly(startAddress, getDisassemblyBlock(), mixed, showSymbols, showDisassembly);
} else {
final IStatus status= getStatus();
if (status != null && !status.isOK()) {
if (startAddress != null) {
fCallback.doScrollLocked(new Runnable() {
public void run() {
fCallback.insertError(startAddress, status.getMessage());
}
});
}
}
fCallback.setUpdatePending(false);
}
}
};
fDisassemblyRetrieval.asyncGetDisassembly(startAddress, finalEndAddress, file, lineNumber, lines, disassemblyRequest);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#insertSource(org.eclipse.jface.text.Position, java.math.BigInteger, java.lang.String, int)
*/
public Object insertSource(Position pos, BigInteger address,
String file, int lineNumber) {
ISourceLocator locator = fTargetContext.getLaunch().getSourceLocator();
if (locator instanceof ISourceLookupDirector) {
return ((ISourceLookupDirector)locator).getSourceElement(file);
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#hasFrameContext()
*/
public boolean hasFrameContext() {
return fTargetFrameContext != null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyBackend#gotoSymbol(java.lang.String)
*/
public void gotoSymbol(String symbol) {
if (fTargetFrameContext != null) {
try {
// This logic was lifted from CMemoryBlockRetrievalExtension.getExtendedMemoryBlock(String, Object)
CStackFrame cstackFrame = (CStackFrame)fTargetFrameContext;
ICDIExpression cdiExpression = cstackFrame.getCDITarget().createExpression(symbol);
CExpression cdtExpression = new CExpression(cstackFrame, cdiExpression, null);
IValue value = cdtExpression.getValue();
if (value instanceof ICValue) {
ICType type = ((ICValue)value).getType();
if (type != null) {
// get the address for the expression, allow all types
String rawExpr = cdtExpression.getExpressionString();
String voidExpr = "(void *)(" + rawExpr + ')'; //$NON-NLS-1$
String attempts[] = { rawExpr, voidExpr };
for (int i = 0; i < attempts.length; i++) {
String expr = attempts[i];
String addressStr = cstackFrame.evaluateExpressionToString(expr);
if (addressStr != null) {
try {
final BigInteger address = (addressStr.startsWith("0x")) ? new BigInteger(addressStr.substring(2), 16) : new BigInteger(addressStr); //$NON-NLS-1$
fCallback.asyncExec(new Runnable() {
public void run() {
fCallback.gotoAddress(address);
}});
} catch (NumberFormatException e) {
if (i >= attempts.length) {
throw new DebugException(new Status(IStatus.ERROR, CDebugUIPlugin.PLUGIN_ID,
MessageFormat.format(CDebugUIMessages.getString("DisassemblyBackendCdi_Symbol_Evaluation_Unusable"), new String[]{symbol}))); //$NON-NLS-1$
}
}
}
}
}
}
else {
throw new DebugException(new Status(IStatus.ERROR, CDebugUIPlugin.PLUGIN_ID,
MessageFormat.format(CDebugUIMessages.getString("DisassemblyBackendCdi_Symbol_Didnt_Evaluate"), new String[]{symbol}))); //$NON-NLS-1$
}
}
catch (final CDIException exc) {
fCallback.asyncExec(new Runnable() {
public void run() {
ErrorDialog.openError(fCallback.getSite().getShell(),
CDebugUIMessages.getString("DisassemblyBackendCdi_Error_Dlg_Title"), //$NON-NLS-1$
null, new Status(IStatus.ERROR, CDebugUIPlugin.PLUGIN_ID, exc.getLocalizedMessage()));
}});
}
catch (final DebugException exc) {
fCallback.asyncExec(new Runnable() {
public void run() {
ErrorDialog.openError(fCallback.getSite().getShell(),
CDebugUIMessages.getString("DisassemblyBackendCdi_Error_Dlg_Title"), //$NON-NLS-1$
null, exc.getStatus());
}});
}
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyBackend#retrieveDisassembly(java.lang.String, int, java.math.BigInteger, boolean, boolean, boolean)
*/
public void retrieveDisassembly(String file, int lines,
BigInteger endAddress, final boolean mixed, final boolean showSymbols,
final boolean showDisassembly) {
final IDisassemblyRetrieval.DisassemblyRequest disassemblyRequest= new IDisassemblyRetrieval.DisassemblyRequest() {
@Override
public void done() {
if (!isCanceled() && getDisassemblyBlock() != null) {
insertDisassembly(null, getDisassemblyBlock(), mixed, showSymbols, showDisassembly);
} else {
final IStatus status= getStatus();
if (status != null && !status.isOK()) {
fCallback.asyncExec(new Runnable() {
public void run() {
ErrorDialog.openError(fCallback.getSite().getShell(), "Error", null, getStatus()); //$NON-NLS-1$
}
});
}
fCallback.setUpdatePending(false);
}
}
};
assert !fCallback.getUpdatePending();
fCallback.setUpdatePending(true);
fDisassemblyRetrieval.asyncGetDisassembly(null, endAddress, file, 1, lines, disassemblyRequest);
}
private void insertDisassembly(BigInteger startAddress, IDisassemblyBlock disassemblyBlock, boolean mixed, boolean showSymbols, boolean showDisassembly) {
if (!fCallback.hasViewer() || fCdiSessionId == null) {
return;
}
if (!fCallback.getUpdatePending()) {
assert false;
return;
}
try {
fCallback.lockScroller();
final IDisassemblyDocument document = fCallback.getDocument(); // for convenience
IAsmSourceLine[] srcLines= disassemblyBlock.getSourceLines();
AddressRangePosition p = null;
Object srcElement= disassemblyBlock.getSourceElement();
for (int i = 0; i < srcLines.length; i++) {
IAsmSourceLine srcLine= srcLines[i];
// If the caller doesn't want mixed, set line number to -1 so we
// create a pure disassembly position object
int lineNumber= mixed ? srcLine.getLineNumber() - 1 : -1;
IAsmInstruction[] instructions= srcLine.getInstructions();
for (int j = 0; j < instructions.length; j++) {
IAsmInstruction instruction = instructions[j];
BigInteger address= instruction.getAdress().getValue();
if (startAddress == null || startAddress.compareTo(BigInteger.ZERO) < 0) {
startAddress = address;
fCallback.setGotoAddressPending(address);
}
if (p == null || !p.containsAddress(address)) {
p = fCallback.getPositionOfAddress(address);
}
if (p instanceof ErrorPosition && p.fValid) {
p.fValid = false;
document.addInvalidAddressRange(p);
} else if (p == null) {
return;
} else if (p.fValid) {
if (srcElement != null && lineNumber >= 0 || p.fAddressLength == BigInteger.ONE) {
// override probably unaligned disassembly
p.fValid = false;
document.addInvalidAddressRange(p);
} else {
return;
}
}
boolean hasSource= false;
String compilationPath= null;
if (srcElement != null && lineNumber >= 0) {
if (srcElement instanceof LocalFileStorage) {
compilationPath = ((LocalFileStorage)srcElement).getFullPath().toString();
}
else if (srcElement instanceof IFile) {
compilationPath = ((IFile)srcElement).getLocation().toString();
}
else {
assert false : "missing support for source element of type " + srcElement.getClass().toString(); //$NON-NLS-1$
}
if (compilationPath != null) {
p = fCallback.insertSource(p, address, compilationPath, lineNumber);
hasSource = fCallback.getStorageForFile(compilationPath) != null;
}
else {
hasSource = false;
}
}
// insert symbol label
final String functionName= instruction.getFunctionName();
if (functionName != null && functionName.length() > 0 && instruction.getOffset() == 0) {
p = document.insertLabel(p, address, functionName, showSymbols && (!hasSource || showDisassembly));
}
// determine instruction byte length
BigInteger instrLength= null;
if (j < instructions.length - 1) {
instrLength= instructions[j+1].getAdress().distanceTo(instruction.getAdress()).abs();
} else if (i < srcLines.length - 1) {
int nextSrcLineIdx= i+1;
while (nextSrcLineIdx < srcLines.length) {
IAsmInstruction[] nextInstrs= srcLines[nextSrcLineIdx].getInstructions();
if (nextInstrs.length > 0) {
instrLength= nextInstrs[0].getAdress().distanceTo(instruction.getAdress()).abs();
break;
}
++nextSrcLineIdx;
}
if (nextSrcLineIdx >= srcLines.length) {
break;
}
} else {
if (instructions.length == 1 && srcLines.length == 1) {
instrLength= p.fAddressLength;
}
}
if (instrLength == null) {
// cannot determine length of last instruction
break;
}
final String opCode;
// insert function name+offset instead of opcode bytes
if (functionName != null && functionName.length() > 0) {
opCode= functionName + '+' + instruction.getOffset();
} else {
opCode= ""; //$NON-NLS-1$
}
if (!showDisassembly && hasSource) {
p = document.insertDisassemblyLine(p, address, instrLength.intValue(), opCode, "", compilationPath, lineNumber); //$NON-NLS-1$
} else {
p = document.insertDisassemblyLine(p, address, instrLength.intValue(), opCode, instruction.getInstructionText(), compilationPath, lineNumber); //$NON-NLS-1
}
if (p == null) {
break;
}
}
}
} catch (BadLocationException e) {
// should not happen
DisassemblyUtils.internalError(e);
} finally {
fCallback.setUpdatePending(false);
fCallback.updateInvalidSource();
fCallback.unlockScroller();
fCallback.doPending();
fCallback.updateVisibleArea();
}
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse.debug.core.DebugEvent[])
*/
public void handleDebugEvents(DebugEvent[] events) {
for (DebugEvent event : events) {
if (event.getKind() == DebugEvent.TERMINATE) {
Object eventSource = event.getSource();
if ((eventSource instanceof CDebugTarget) && (getSessionId((CDebugTarget)eventSource).equals(fCdiSessionId))) {
fCallback.handleTargetEnded();
return;
}
}
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#dispose()
*/
public void dispose() {
DebugPlugin.getDefault().removeDebugEventListener(this);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#evaluateExpression(java.lang.String)
*/
public String evaluateExpression(String expression) {
// This is called to service text hovering. We either resolve the
// expression or we don't. No error reporting needed.
if (fTargetFrameContext != null) {
try {
// This logic was lifted from CMemoryBlockRetrievalExtension.getExtendedMemoryBlock(String, Object)
CStackFrame cstackFrame = (CStackFrame)fTargetFrameContext;
ICDIExpression cdiExpression = cstackFrame.getCDITarget().createExpression(expression);
CExpression cdtExpression = new CExpression(cstackFrame, cdiExpression, null);
IValue value = cdtExpression.getValue();
if (value instanceof ICValue) {
ICType type = ((ICValue)value).getType();
if (type != null) {
return cstackFrame.evaluateExpressionToString(cdtExpression.getExpressionString());
}
}
}
catch (Exception exc) {
}
}
return ""; //$NON-NLS-1$
}
}

View file

@ -0,0 +1,40 @@
/*******************************************************************************
* Copyright (c) 2010 Freescale Semiconductor, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Freescale Semiconductor - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.disassembly.dsf;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IAdapterFactory;
public class DisassemblyBackendCdiFactory implements IAdapterFactory {
private static final Class<?>[] ADAPTERS = { IDisassemblyBackend.class };
/* (non-Javadoc)
* @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class)
*/
@SuppressWarnings("rawtypes")
public Object getAdapter(Object adaptableObject, Class adapterType) {
if (IDisassemblyBackend.class.equals(adapterType)) {
if (adaptableObject instanceof IAdaptable && DisassemblyBackendCdi.supportsDebugContext_((IAdaptable)adaptableObject)) {
return new DisassemblyBackendCdi();
}
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList()
*/
@SuppressWarnings("rawtypes")
public Class[] getAdapterList() {
return ADAPTERS;
}
}

View file

@ -8,7 +8,7 @@
* Contributors: * Contributors:
* Wind River Systems - initial API and implementation * Wind River Systems - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model; package org.eclipse.cdt.debug.internal.ui.disassembly.dsf;
import java.math.BigInteger; import java.math.BigInteger;
@ -46,4 +46,11 @@ public class DisassemblyPosition extends AddressRangePosition {
return -1; return -1;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.AddressRangePosition#toString()
*/
@Override
public String toString() {
return super.toString() + "->[" + new String(fFunction) + ']'; //$NON-NLS-1$
}
} }

View file

@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright (c) 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
* Freescale Semiconductor - refactoring
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.disassembly.dsf;
import java.math.BigInteger;
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
import org.eclipse.core.runtime.Platform;
/**
* Some general utilities used by the DSF Disassembly view and its backends
*/
public class DisassemblyUtils {
/**
* Trace option. The view started out and continues to be in DSF but
* backends can be non-DSF.
*/
public final static boolean DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.cdt.dsf.ui/debug/disassembly")); //$NON-NLS-1$//$NON-NLS-2$
public static String getAddressText(BigInteger address) {
if (address == null) {
return "<null>"; //$NON-NLS-1$
}
if (address.compareTo(BigInteger.ZERO) < 0) {
return address.toString();
}
String hex = address.toString(16);
return "0x" + "0000000000000000".substring(hex.length() + (address.bitLength() <= 32 ? 8 : 0)) + hex; //$NON-NLS-1$ //$NON-NLS-2$
}
public static void internalError(Throwable e) {
if (DEBUG) {
System.err.println("Disassembly: Internal error"); //$NON-NLS-1$
CDebugUIPlugin.log(e);
}
}
public static BigInteger decodeAddress(String string) {
if (string.startsWith("0x")) { //$NON-NLS-1$
return new BigInteger(string.substring(2), 16);
}
return new BigInteger(string);
}
}

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007, 2008 Wind River Systems and others. * Copyright (c) 2007, 2010 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -8,7 +8,7 @@
* Contributors: * Contributors:
* Wind River Systems - initial API and implementation * Wind River Systems - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model; package org.eclipse.cdt.debug.internal.ui.disassembly.dsf;
import java.math.BigInteger; import java.math.BigInteger;
@ -37,4 +37,12 @@ public class ErrorPosition extends AddressRangePosition {
public int hashCode() { public int hashCode() {
return fHashCode; return fHashCode;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.AddressRangePosition#toString()
*/
@Override
public String toString() {
return super.toString() + "->[" + fHashCode + ']'; //$NON-NLS-1$
}
} }

View file

@ -0,0 +1,178 @@
/*******************************************************************************
* Copyright (c) 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
* Freescale Semiconductor - refactoring
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.disassembly.dsf;
import java.math.BigInteger;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.text.Position;
/**
* This is the main interface that connects the DSF Disassembly view to CDI and
* DSF backends. This interface is obtained through IAdaptable. A new instance
* is provided every time the adapter is requested. The caller must invoke
* {@link #dispose()} when it has no further use for the instance.
*/
public interface IDisassemblyBackend {
/**
* Used to return muliple results from
* {@link IDisassemblyBackend#setDebugContext(IAdaptable)}
*/
public class SetDebugContextResult {
/**
* The ID of the session associated with the context
*/
public String sessionId;
/**
* The frame represented by the context. 0 is the topmost frame (where
* the PC is)
*/
public int frameLevel;
/**
* Whether the context changed to another execution context (the parent
* elements of a thread, typically a process)
*/
public boolean contextChanged;
}
/**
* Called after instantiation
* @param callback
*/
void init(IDisassemblyPartCallback callback);
/**
* Indicates whether this backend support the provided debug context,
*
* @param context
* the debug context
* @return true if it is supported. Caller should invoke
* {@link #setDebugContext(IAdaptable)} with [context] only after
* first checking with this method
*/
boolean supportsDebugContext(IAdaptable context);
/**
* @return whether the backend has a debug context
*/
boolean hasDebugContext();
/**
* Called by the view when there has been a change to the active debug
* context. Should be called only if
* {@link #supportsDebugContext(IAdaptable)} first returns true.
*
* @param context
* the active debug context; must not be null
* @return information about the new context
*/
SetDebugContextResult setDebugContext(IAdaptable context);
/**
* Clear any knowledge of the current debug context.
*/
void clearDebugContext();
/**
* The implementation should end up calling DisassemblyPart.gotoFrame() if
* targetFrame > 0, or DisassemblyPart.gotoPC() otherwise.
*
* @param targetFrame
* the frame level to retrieve. Level 0 is the topmost frame
* (where the PC is)
*/
void retrieveFrameAddress(int targetFrame);
/**
* Get the frame of the current context
*
* @return the frame's level; 0 is the topmost frame (i.e., where the PC
* is). -1 if no frame context has been set.
*/
int getFrameLevel();
/**
* Indicates whether the current context is suspended.
*/
boolean isSuspended();
/**
* Indicates whether the current context is a frame.
*/
boolean hasFrameContext();
/**
* Returns the file associated with the current frame context, or null if
* the current context is not a frame or if the frame has no file
* association.
*/
String getFrameFile();
/**
* Returns the line number associated with the current frame context, or -1
* if current context is not a frame or if the frame has no file and line
* association.
*/
int getFrameLine();
/**
* Retrieves disassembly based on either (a) start and end address range, or
* (b) file, line number, and line count. If the caller specifies both sets
* of information, the implementation should honor (b) and ignore (a).
*
* @param startAddress
* @param endAddress
* @param file
* @param lineNumber
* @param lines
* @param mixed
* @param showSymbols
* @param showDisassembly
* @param linesHint
*/
void retrieveDisassembly(BigInteger startAddress, BigInteger endAddress, String file, int lineNumber, int lines, boolean mixed, boolean showSymbols, boolean showDisassembly, int linesHint);
Object insertSource(Position pos, BigInteger address, final String file, int lineNumber);
void gotoSymbol(String symbol);
/**
* Retrieves disassembly of the code generated by a source file, starting at
* the first line. Caller specifies the maximum number of disassembly lines
* that should result and a maximum address.
*
* @param file
* @param lines
* @param endAddress
* @param mixed
* @param showSymbols
* @param showDisassembly
*/
void retrieveDisassembly(String file, int lines, BigInteger endAddress, boolean mixed, boolean showSymbols, boolean showDisassembly);
/**
* Evaluate an expression for text hover
*
* @param expression
* the expression to be evaluated
* @return the result, or "" if it doesn't resolve, for whatever reason
*/
String evaluateExpression(String expression);
/**
* Called when the Disassembly view has no further use for this backend.
*/
void dispose();
}

View file

@ -0,0 +1,33 @@
/*******************************************************************************
* Copyright (c) 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
* Freescale Semiconductor - refactoring
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.disassembly.dsf;
import java.math.BigInteger;
import org.eclipse.jface.text.BadLocationException;
/**
* DSF Disassembly view backends (CDI and DSF) need this limited access to the
* editor/view Document.
*/
public interface IDisassemblyDocument {
void addInvalidAddressRange(AddressRangePosition p);
AddressRangePosition insertLabel(AddressRangePosition pos,
BigInteger address, String label, boolean showLabels)
throws BadLocationException;
AddressRangePosition insertDisassemblyLine(AddressRangePosition p,
BigInteger address, int intValue, String opCode, String string,
String compilationPath, int lineNumber) throws BadLocationException;
}

View file

@ -0,0 +1,73 @@
/*******************************************************************************
* Copyright (c) 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
* Freescale Semiconductor - refactoring
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.disassembly.dsf;
import java.math.BigInteger;
import org.eclipse.ui.IWorkbenchPartSite;
/**
* Implementations of {@link IDisassemblyBackend} are given this access back
* into the part (editor/view) that created them. Except where noted, methods
* must be invoked on the GUI thread. A disassembly backend has to call back
* into the editor/view to carry out its duties.
*
* <p>
* This interface was born of the refactoring which allowed the DSF Disassembly
* view to work with both DSF and CDI. Before that, the functionality of
* IDisasssemblyBackend was built into DisassemblyPart and thus there was no
* need for this interface. This interface merely exposes model (DSF/CDI)
* agnostic access to DisassemblyPart. It exposes methods that have been in
* DisassemblyPart all along. Documentation for those methods were sparse, and
* thus this interface is likewise. See the DisassemblyPart for any available
* documentation.
*/
public interface IDisassemblyPartCallback {
void gotoFrame(int frame);
void gotoFrameIfActive(int frame);
void updateVisibleArea();
void updateInvalidSource();
void retrieveDisassembly(final BigInteger startAddress, BigInteger endAddress, final int linesHint, boolean mixed, boolean ignoreFile);
void insertError(BigInteger address, String message);
int getAddressSize();
void addressSizeChanged(int addressSize);
AddressRangePosition getPositionOfAddress(BigInteger address);
void gotoFrame(int frame, BigInteger address);
void updatePC(BigInteger pc);
void doPending();
void doScrollLocked(final Runnable doit);
void lockScroller();
void unlockScroller();
void insertSource(AddressRangePosition pos);
AddressRangePosition insertSource(AddressRangePosition pos, BigInteger address, final String file, int lineNumber);
void setUpdatePending(boolean pending);
boolean getUpdatePending();
void setGotoAddressPending(BigInteger address);
BigInteger getGotoAddressPending();
IDisassemblyDocument getDocument();
Object getStorageForFile(String file);
void gotoAddress(BigInteger address);
IWorkbenchPartSite getSite();
boolean hasViewer();
/** Thread-safe */
void handleTargetSuspended();
/** Thread-safe */
void handleTargetResumed();
/** Thread-safe */
void handleTargetEnded();
/** Thread-safe */
void asyncExec(Runnable runnable);
}

View file

@ -0,0 +1,119 @@
/*******************************************************************************
* Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Anton Leherbauer (Wind River Systems) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.disassembly.dsf;
import java.math.BigInteger;
import org.eclipse.cdt.debug.core.model.IDisassemblyBlock;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.core.IRequest;
import org.eclipse.debug.core.model.IStackFrame;
/**
*/
public interface IDisassemblyRetrieval {
/**
*/
public static class Request implements IRequest {
private IStatus fStatus;
private boolean fCanceled;
/*
* @see org.eclipse.debug.core.IRequest#cancel()
*/
public void cancel() {
fCanceled= true;
}
/*
* @see org.eclipse.debug.core.IRequest#done()
*/
public void done() {
}
/*
* @see org.eclipse.debug.core.IRequest#getStatus()
*/
public IStatus getStatus() {
return fStatus;
}
/*
* @see org.eclipse.debug.core.IRequest#isCanceled()
*/
public boolean isCanceled() {
return fCanceled;
}
/*
* @see org.eclipse.debug.core.IRequest#setStatus(org.eclipse.core.runtime.IStatus)
*/
public void setStatus(IStatus status) {
fStatus= status;
}
}
/**
*/
public static class AddressRequest extends Request {
private BigInteger fAddress;
/**
* @return the address
*/
public BigInteger getAddress() {
return fAddress;
}
/**
* @param address the address to set
*/
public void setAddress(BigInteger address) {
fAddress= address;
}
}
public static class DisassemblyRequest extends Request {
IDisassemblyBlock fDisassemblyBlock;
/**
* @return the disassemblyBlock
*/
public IDisassemblyBlock getDisassemblyBlock() {
return fDisassemblyBlock;
}
/**
* @param disassemblyBlock the disassemblyBlock to set
*/
public void setDisassemblyBlock(IDisassemblyBlock disassemblyBlock) {
fDisassemblyBlock= disassemblyBlock;
}
}
/**
* @param stackFrame
* @param addressRequest
*/
void asyncGetFrameAddress(IStackFrame stackFrame, AddressRequest addressRequest);
/**
* @param startAddress
* @param endAddress
* @param file
* @param lines
* @param disassemblyRequest
*/
void asyncGetDisassembly(BigInteger startAddress, BigInteger endAddress, String file, int fileNumber, int lines,
DisassemblyRequest disassemblyRequest);
}

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007, 2008 Wind River Systems and others. * Copyright (c) 2007, 2010 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -8,7 +8,7 @@
* Contributors: * Contributors:
* Wind River Systems - initial API and implementation * Wind River Systems - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model; package org.eclipse.cdt.debug.internal.ui.disassembly.dsf;
import java.math.BigInteger; import java.math.BigInteger;
@ -29,4 +29,11 @@ public class LabelPosition extends AddressRangePosition {
fLabel = label; fLabel = label;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.AddressRangePosition#toString()
*/
@Override
public String toString() {
return super.toString() + "->[" + fLabel + ']'; //$NON-NLS-1$
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2009 QNX Software Systems and others. * Copyright (c) 2004, 2010 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -16,6 +16,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.debug.core.CDebugCorePlugin; import org.eclipse.cdt.debug.core.CDebugCorePlugin;
import org.eclipse.cdt.debug.core.model.ICDebugElement;
import org.eclipse.cdt.debug.internal.ui.CBreakpointUpdater; import org.eclipse.cdt.debug.internal.ui.CBreakpointUpdater;
import org.eclipse.cdt.debug.internal.ui.CDebugImageDescriptorRegistry; import org.eclipse.cdt.debug.internal.ui.CDebugImageDescriptorRegistry;
import org.eclipse.cdt.debug.internal.ui.CDebugModelPresentation; import org.eclipse.cdt.debug.internal.ui.CDebugModelPresentation;
@ -23,6 +24,7 @@ import org.eclipse.cdt.debug.internal.ui.CDebuggerPageAdapter;
import org.eclipse.cdt.debug.internal.ui.ColorManager; import org.eclipse.cdt.debug.internal.ui.ColorManager;
import org.eclipse.cdt.debug.internal.ui.EvaluationContextManager; import org.eclipse.cdt.debug.internal.ui.EvaluationContextManager;
import org.eclipse.cdt.debug.internal.ui.IInternalCDebugUIConstants; import org.eclipse.cdt.debug.internal.ui.IInternalCDebugUIConstants;
import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyBackendCdiFactory;
import org.eclipse.cdt.debug.internal.ui.disassembly.editor.DisassemblyEditorManager; import org.eclipse.cdt.debug.internal.ui.disassembly.editor.DisassemblyEditorManager;
import org.eclipse.cdt.debug.ui.sourcelookup.DefaultSourceLocator; import org.eclipse.cdt.debug.ui.sourcelookup.DefaultSourceLocator;
import org.eclipse.cdt.debug.ui.sourcelookup.OldDefaultSourceLocator; import org.eclipse.cdt.debug.ui.sourcelookup.OldDefaultSourceLocator;
@ -289,6 +291,9 @@ public class CDebugUIPlugin extends AbstractUIPlugin {
EvaluationContextManager.startup(); EvaluationContextManager.startup();
CDebugCorePlugin.getDefault().addCBreakpointListener( CBreakpointUpdater.getInstance() ); CDebugCorePlugin.getDefault().addCBreakpointListener( CBreakpointUpdater.getInstance() );
// Register the CDI backend for DSF's disassembly view
Platform.getAdapterManager().registerAdapters(new DisassemblyBackendCdiFactory(), ICDebugElement.class);
// We contribute actions to the platform's Variables view with a // We contribute actions to the platform's Variables view with a
// criteria to enable only when this plugin is loaded. This can lead to // criteria to enable only when this plugin is loaded. This can lead to
// some edge cases with broken behavior (273306). The solution is to // some edge cases with broken behavior (273306). The solution is to

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<component id="org.eclipse.cdt.dsf.ui" version="2">
<resource path="src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyPart.java" type="org.eclipse.cdt.dsf.debug.internal.ui.disassembly.DisassemblyPart">
<filter id="571473929">
<message_arguments>
<message_argument value="WorkbenchPart"/>
<message_argument value="DisassemblyPart"/>
</message_arguments>
</filter>
</resource>
</component>

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007, 2008 Wind River Systems and others. * Copyright (c) 2007, 2010 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -12,10 +12,9 @@ package org.eclipse.cdt.dsf.debug.internal.ui.disassembly;
import java.math.BigInteger; import java.math.BigInteger;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.AddressRangePosition; import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourceFileInfo; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourceFileInfo;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourcePosition;
import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.source.IAnnotationHover; import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.IAnnotationModel; import org.eclipse.jface.text.source.IAnnotationModel;

View file

@ -0,0 +1,960 @@
/*******************************************************************************
* Copyright (c) 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
* Freescale Semiconductor - refactoring
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.internal.ui.disassembly;
import static org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyUtils.DEBUG;
import static org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyUtils.internalError;
import java.math.BigInteger;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition;
import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyUtils;
import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.ErrorPosition;
import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend;
import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.Query;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IDisassembly;
import org.eclipse.cdt.dsf.debug.service.IExpressions;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
import org.eclipse.cdt.dsf.debug.service.IInstruction;
import org.eclipse.cdt.dsf.debug.service.IMixedInstruction;
import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.ISourceLookup;
import org.eclipse.cdt.dsf.debug.service.IStack;
import org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext;
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IResumedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext;
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMData;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.service.DsfSession.SessionEndedListener;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Position;
public class DisassemblyBackendDsf implements IDisassemblyBackend, SessionEndedListener {
private volatile IExecutionDMContext fTargetContext;
private DsfServicesTracker fServicesTracker;
private IFrameDMContext fTargetFrameContext;
protected IFrameDMData fTargetFrameData;
private String fDsfSessionId;
private IDisassemblyPartCallback fCallback;
/**
* Constructor
*/
public DisassemblyBackendDsf() {
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#init(org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyPartCallback)
*/
public void init(IDisassemblyPartCallback callback) {
assert callback != null;
fCallback = callback;
DsfSession.addSessionEndedListener(this);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#dispose()
*/
public void dispose() {
DsfSession.removeSessionEndedListener(this);
}
public static boolean supportsDebugContext_(IAdaptable context) {
return context.getAdapter(IDMVMContext.class) != null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#supportsDebugContext(org.eclipse.core.runtime.IAdaptable)
*/
public boolean supportsDebugContext(IAdaptable context) {
return supportsDebugContext_(context);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#hasDebugContext()
*/
public boolean hasDebugContext() {
return fTargetContext != null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#setDebugContext(org.eclipse.core.runtime.IAdaptable)
*/
public SetDebugContextResult setDebugContext(IAdaptable context) {
assert supportsDebugContext(context) : "caller should not have invoked us"; //$NON-NLS-1$
IDMVMContext vmContext = (IDMVMContext) context.getAdapter(IDMVMContext.class);
IDMContext dmContext = vmContext.getDMContext();
SetDebugContextResult result = new SetDebugContextResult();
result.sessionId = fDsfSessionId; // initial value; may change
String dsfSessionId = dmContext.getSessionId();
if (!dsfSessionId.equals(fDsfSessionId)) {
// switch to different session or initiate session
if (DEBUG) System.out.println("DisassemblyBackendDsf() " + dsfSessionId); //$NON-NLS-1$
fTargetContext= null;
if (dmContext instanceof IFrameDMContext) {
IFrameDMContext frame= (IFrameDMContext) dmContext;
IExecutionDMContext executionContext= DMContexts.getAncestorOfType(frame, IExecutionDMContext.class);
if (executionContext != null) {
fTargetContext= executionContext;
fTargetFrameContext= frame;
result.frameLevel = frame.getLevel();
}
}
if (fTargetContext != null) {
// remove ourselves as a listener with the previous session (context)
if (fDsfSessionId != null) {
final DsfSession prevSession = DsfSession.getSession(fDsfSessionId);
if (prevSession != null) {
try {
prevSession.getExecutor().execute(new DsfRunnable() {
public void run() {
prevSession.removeServiceEventListener(this);
}
});
} catch (RejectedExecutionException e) {
// Session is shut down.
}
}
}
result.sessionId = fDsfSessionId = dsfSessionId;
if (fServicesTracker != null) {
fServicesTracker.dispose();
}
fServicesTracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), fDsfSessionId);
result.contextChanged = true;
// add ourselves as a listener with the new session (context)
final DsfSession newSession = DsfSession.getSession(dsfSessionId);
if (newSession != null) {
try {
newSession.getExecutor().execute(new DsfRunnable() {
public void run() {
newSession.removeServiceEventListener(this);
}
});
} catch (RejectedExecutionException e) {
// Session is shut down.
}
}
}
} else if (dmContext instanceof IFrameDMContext) {
// switch to different frame
IFrameDMContext frame= (IFrameDMContext) dmContext;
final IDMContext[] parents= frame.getParents();
for (IDMContext parent : parents) {
if (parent instanceof IExecutionDMContext) {
fTargetContext= (IExecutionDMContext) parent;
fTargetFrameContext= frame;
fCallback.gotoFrameIfActive(frame.getLevel());
result.frameLevel = getFrameLevel();
break;
}
}
}
return result;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#clearDebugContext()
*/
public void clearDebugContext() {
final DsfSession session = DsfSession.getSession(fDsfSessionId);
if (session != null) {
try {
session.getExecutor().execute(new DsfRunnable() {
public void run() {
session.removeServiceEventListener(this);
}
});
} catch (RejectedExecutionException e) {
// Session is shut down.
}
}
fTargetContext= null;
if (fServicesTracker != null) {
fServicesTracker.dispose();
fServicesTracker= null;
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#retrieveFrameAddress(int)
*/
public void retrieveFrameAddress(final int frame) {
final DsfExecutor executor= getSession().getExecutor();
executor.execute(new DsfRunnable() {
public void run() {
retrieveFrameAddressInSessionThread(frame);
}});
}
void retrieveFrameAddressInSessionThread(final int frame) {
final IStack stack= fServicesTracker.getService(IStack.class);
final DsfExecutor executor= getSession().getExecutor();
// Our frame context is currently either un-set or it's set to the frame
// our caller is specifying. If un-set, then set it and reinvoke this
// method.
if (fTargetFrameContext == null) {
if (frame == 0) {
stack.getTopFrame(fTargetContext, new DataRequestMonitor<IFrameDMContext>(executor, null) {
@Override
protected void handleCompleted() {
fCallback.setUpdatePending(false);
fTargetFrameContext= getData();
if (fTargetFrameContext != null) {
retrieveFrameAddressInSessionThread(frame);
}
}
});
} else {
// TODO retrieve other stack frame
}
return;
}
else {
assert frame == fTargetFrameContext.getLevel();
}
stack.getFrameData(fTargetFrameContext, new DataRequestMonitor<IFrameDMData>(executor, null) {
@Override
protected void handleCompleted() {
fCallback.setUpdatePending(false);
IFrameDMData frameData= getData();
fTargetFrameData= frameData;
if (!isCanceled() && frameData != null) {
final IAddress address= frameData.getAddress();
final BigInteger addressValue= address.getValue();
if (DEBUG) System.out.println("retrieveFrameAddress done "+ DisassemblyUtils.getAddressText(addressValue)); //$NON-NLS-1$
fCallback.asyncExec(new Runnable() {
public void run() {
if (address.getSize() * 4 > fCallback.getAddressSize()) {
fCallback.addressSizeChanged(address.getSize() * 4);
}
if (frame == 0) {
fCallback.updatePC(addressValue);
} else {
fCallback.gotoFrame(frame, addressValue);
}
}
});
} else {
final IStatus status= getStatus();
if (status != null && !status.isOK()) {
fCallback.asyncExec(new Runnable() {
public void run() {
ErrorDialog.openError(fCallback.getSite().getShell(), "Error", null, getStatus()); //$NON-NLS-1$
}
});
}
}
}
});
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#isSuspended()
*/
public boolean isSuspended() {
DsfSession session = getSession();
if (session == null || !session.isActive()) {
return false;
}
if (session.getExecutor().isInExecutorThread()) {
IRunControl runControl = getRunControl();
if (runControl == null) {
return false;
} else {
return runControl.isSuspended(fTargetContext);
}
}
Query<Boolean> query = new Query<Boolean>() {
@Override
protected void execute(DataRequestMonitor<Boolean> rm) {
try {
IRunControl runControl = getRunControl();
if (runControl == null) {
rm.setData(false);
} else {
rm.setData(runControl.isSuspended(fTargetContext));
}
} finally {
rm.done();
}
}
};
session.getExecutor().execute(query);
try {
return query.get();
} catch (InterruptedException exc) {
} catch (ExecutionException exc) {
}
return false;
}
private DsfSession getSession() {
return DsfSession.getSession(fDsfSessionId);
}
private IRunControl getRunControl() {
return getService(IRunControl.class);
}
private <V> V getService(Class<V> serviceClass) {
if (fServicesTracker != null) {
return fServicesTracker.getService(serviceClass);
}
return null;
}
@DsfServiceEventHandler
public void handleEvent(IExitedDMEvent event) {
if (fTargetContext == null) {
return;
}
final IExecutionDMContext context= event.getDMContext();
if (context.equals(fTargetContext)
|| DMContexts.isAncestorOf(fTargetContext, context)) {
fCallback.asyncExec(new Runnable() {
public void run() {
fCallback.handleTargetEnded();
}});
}
}
@DsfServiceEventHandler
public void handleEvent(ISuspendedDMEvent event) {
if (fTargetContext == null) {
return;
}
final IExecutionDMContext context= event.getDMContext();
if (context.equals(fTargetContext)
|| DMContexts.isAncestorOf(fTargetContext, context)) {
fCallback.handleTargetSuspended();
}
}
@DsfServiceEventHandler
public void handleEvent(IResumedDMEvent event) {
if (fTargetContext == null) {
return;
}
final IExecutionDMContext context= event.getDMContext();
if (context.equals(fTargetContext)
|| DMContexts.isAncestorOf(fTargetContext, context)) {
fCallback.handleTargetResumed();
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.dsf.service.DsfSession.SessionEndedListener#sessionEnded(org.eclipse.cdt.dsf.service.DsfSession)
*/
public void sessionEnded(DsfSession session) {
if (session.getId().equals(fDsfSessionId)) {
clearDebugContext();
fCallback.handleTargetEnded();
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#getFrameLevel()
*/
public int getFrameLevel() {
if (fTargetFrameContext != null) {
return fTargetFrameContext.getLevel();
}
return -1;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#hasFrameContext()
*/
public boolean hasFrameContext() {
return fTargetFrameContext != null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#getFrameFile()
*/
public String getFrameFile() {
return fTargetFrameData.getFile();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#getFrameLine()
*/
public int getFrameLine() {
return fTargetFrameData.getLine();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.IDisassemblyBackend#retrieveDisassembly(java.math.BigInteger, java.math.BigInteger, java.lang.String, int, int, boolean, boolean, boolean, int)
*/
public void retrieveDisassembly(final BigInteger startAddress, BigInteger endAddress, final String file, final int lineNumber, final int lines, boolean mixed, final boolean showSymbols, final boolean showDisassembly, final int linesHint) {
final BigInteger finalEndAddress= endAddress;
DsfSession session = getSession();
if (session == null) {
return; // can happen during session termination
}
final DsfExecutor executor= session.getExecutor();
final IDisassemblyDMContext context= DMContexts.getAncestorOfType(fTargetContext, IDisassemblyDMContext.class);
if (mixed) {
final DataRequestMonitor<IMixedInstruction[]> disassemblyRequest= new DataRequestMonitor<IMixedInstruction[]>(executor, null) {
@Override
public void handleCompleted() {
final IMixedInstruction[] data= getData();
if (!isCanceled() && data != null) {
fCallback.asyncExec(new Runnable() {
public void run() {
if (!insertDisassembly(startAddress, finalEndAddress, data, showSymbols, showDisassembly)) {
// retry in non-mixed mode
fCallback.retrieveDisassembly(startAddress, finalEndAddress, linesHint, false, false);
}
}});
} else {
final IStatus status= getStatus();
if (status != null && !status.isOK()) {
if( file != null ) {
fCallback.asyncExec(new Runnable() {
public void run() {
fCallback.retrieveDisassembly(startAddress, finalEndAddress, linesHint, true, true);
}});
}
else {
fCallback.asyncExec(new Runnable() {
public void run() {
fCallback.doScrollLocked(new Runnable() {
public void run() {
fCallback.insertError(startAddress, status.getMessage());
}
});
}});
}
}
fCallback.setUpdatePending(false);
}
}
};
if (file != null) {
executor.execute(new Runnable() {
public void run() {
final IDisassembly disassembly= fServicesTracker.getService(IDisassembly.class);
if (disassembly == null) {
disassemblyRequest.cancel();
disassemblyRequest.done();
return;
}
disassembly.getMixedInstructions(context, file, lineNumber, lines*2, disassemblyRequest);
}});
} else {
executor.execute(new Runnable() {
public void run() {
final IDisassembly disassembly= fServicesTracker.getService(IDisassembly.class);
if (disassembly == null) {
disassemblyRequest.cancel();
disassemblyRequest.done();
return;
}
disassembly.getMixedInstructions(context, startAddress, finalEndAddress, disassemblyRequest);
}});
}
} else {
final DataRequestMonitor<IInstruction[]> disassemblyRequest= new DataRequestMonitor<IInstruction[]>(executor, null) {
@Override
public void handleCompleted() {
if (!isCanceled() && getData() != null) {
fCallback.asyncExec(new Runnable() {
public void run() {
insertDisassembly(startAddress, finalEndAddress, getData(), showSymbols, showDisassembly);
}});
} else {
final IStatus status= getStatus();
if (status != null && !status.isOK()) {
fCallback.asyncExec(new Runnable() {
public void run() {
fCallback.doScrollLocked(new Runnable() {
public void run() {
fCallback.insertError(startAddress, status.getMessage());
}
});
}});
}
fCallback.setUpdatePending(false);
}
}
};
if (file != null) {
executor.execute(new Runnable() {
public void run() {
final IDisassembly disassembly= fServicesTracker.getService(IDisassembly.class);
if (disassembly == null) {
disassemblyRequest.cancel();
disassemblyRequest.done();
return;
}
disassembly.getInstructions(context, file, lineNumber, lines, disassemblyRequest);
}});
} else {
executor.execute(new Runnable() {
public void run() {
final IDisassembly disassembly= fServicesTracker.getService(IDisassembly.class);
if (disassembly == null) {
disassemblyRequest.cancel();
disassemblyRequest.done();
return;
}
disassembly.getInstructions(context, startAddress, finalEndAddress, disassemblyRequest);
}});
}
}
}
private void insertDisassembly(BigInteger startAddress, BigInteger endAddress, IInstruction[] instructions, boolean showSymbols, boolean showDisassembly) {
if (!fCallback.hasViewer() || fDsfSessionId == null) {
return;
}
if (DEBUG) System.out.println("insertDisassembly "+ DisassemblyUtils.getAddressText(startAddress)); //$NON-NLS-1$
assert fCallback.getUpdatePending();
if (!fCallback.getUpdatePending()) {
// safe-guard in case something weird is going on
return;
}
try {
fCallback.lockScroller();
AddressRangePosition p= null;
for (int j = 0; j < instructions.length; j++) {
IInstruction instruction = instructions[j];
BigInteger address= instruction.getAdress();
if (startAddress == null || startAddress.compareTo(BigInteger.ZERO) < 0) {
startAddress = address;
fCallback.setGotoAddressPending(address);
}
if (p == null || !p.containsAddress(address)) {
p = fCallback.getPositionOfAddress(address);
}
if (p instanceof ErrorPosition && p.fValid) {
p.fValid = false;
fCallback.getDocument().addInvalidAddressRange(p);
} else if (p == null || p.fValid || address.compareTo(endAddress) > 0) {
if (DEBUG) System.out.println("Excess disassembly lines at " + DisassemblyUtils.getAddressText(address)); //$NON-NLS-1$
return;
}
boolean hasSource= false;
String compilationPath= null;
// insert symbol label
final String functionName= instruction.getFuntionName();
if (functionName != null && functionName.length() > 0 && instruction.getOffset() == 0) {
p = fCallback.getDocument().insertLabel(p, address, functionName, showSymbols && (!hasSource || showDisassembly));
}
// determine instruction byte length
BigInteger instrLength= null;
if (j < instructions.length - 1) {
instrLength= instructions[j+1].getAdress().subtract(instruction.getAdress()).abs();
} else if (instructions.length == 1) {
if (p.fAddressLength.compareTo(BigInteger.valueOf(8)) <= 0) {
instrLength= p.fAddressLength;
}
}
if (instrLength == null) {
// cannot determine length of last instruction
break;
}
final String opCode;
// insert function name+offset instead of opcode bytes
if (functionName != null && functionName.length() > 0) {
opCode= functionName + '+' + instruction.getOffset();
} else {
opCode= ""; //$NON-NLS-1$
}
p = fCallback.getDocument().insertDisassemblyLine(p, address, instrLength.intValue(), opCode, instruction.getInstruction(), compilationPath, -1);
if (p == null) {
break;
}
}
} catch (BadLocationException e) {
// should not happen
DisassemblyUtils.internalError(e);
} finally {
fCallback.setUpdatePending(false);
fCallback.updateInvalidSource();
fCallback.unlockScroller();
fCallback.doPending();
fCallback.updateVisibleArea();
}
}
/**
* @param startAddress
* an address the caller is hoping will be covered by this
* insertion. I.e., [mixedInstructions] may or may not contain
* that address; the caller wants to know if it does, and so we
* indicate that via our return value. Can be null or
* BigInteger(-1) to indicate n/a, in which case we return true
* as long as any instruction was inserted
* @param endAddress
* cut-off address. Any elements in [mixedInstructions] that
* extend beyond this address are ignored.
* @param mixedInstructions
* @param showSymbols
* @param showDisassembly
* @return whether [startAddress] was inserted
*/
private boolean insertDisassembly(BigInteger startAddress, BigInteger endAddress, IMixedInstruction[] mixedInstructions, boolean showSymbols, boolean showDisassembly) {
if (!fCallback.hasViewer() || fDsfSessionId == null) {
return true;
}
if (DEBUG) System.out.println("insertDisassembly "+ DisassemblyUtils.getAddressText(startAddress)); //$NON-NLS-1$
boolean updatePending = fCallback.getUpdatePending();
assert updatePending;
if (!updatePending) {
// safe-guard in case something weird is going on
return true;
}
// indicates whether [startAddress] was inserted
boolean insertedStartAddress = false;
try {
fCallback.lockScroller();
AddressRangePosition p= null;
for (int i = 0; i < mixedInstructions.length; ++i) {
IMixedInstruction mixedInstruction= mixedInstructions[i];
final String file= mixedInstruction.getFileName();
int lineNumber= mixedInstruction.getLineNumber() - 1;
IInstruction[] instructions= mixedInstruction.getInstructions();
for (int j = 0; j < instructions.length; ++j) {
IInstruction instruction = instructions[j];
BigInteger address= instruction.getAdress();
if (startAddress == null || startAddress.compareTo(BigInteger.ZERO) < 0) {
startAddress = address;
fCallback.setGotoAddressPending(address);
}
if (p == null || !p.containsAddress(address)) {
p = fCallback.getPositionOfAddress(address);
}
if (p instanceof ErrorPosition && p.fValid) {
p.fValid = false;
fCallback.getDocument().addInvalidAddressRange(p);
} else if (p == null || address.compareTo(endAddress) > 0) {
if (DEBUG) System.out.println("Excess disassembly lines at " + DisassemblyUtils.getAddressText(address)); //$NON-NLS-1$
return insertedStartAddress;
} else if (p.fValid) {
if (DEBUG) System.out.println("Excess disassembly lines at " + DisassemblyUtils.getAddressText(address)); //$NON-NLS-1$
if (file != null && lineNumber >= 0 || p.fAddressLength == BigInteger.ONE) {
// override probably unaligned disassembly
p.fValid = false;
fCallback.getDocument().addInvalidAddressRange(p);
} else {
return insertedStartAddress;
}
}
boolean hasSource= false;
if (file != null && lineNumber >= 0) {
p = fCallback.insertSource(p, address, file, lineNumber);
hasSource = fCallback.getStorageForFile(file) != null;
}
// insert symbol label
final String functionName= instruction.getFuntionName();
if (functionName != null && functionName.length() > 0 && instruction.getOffset() == 0) {
p = fCallback.getDocument().insertLabel(p, address, functionName, showSymbols && (!hasSource || showDisassembly));
}
// determine instruction byte length
BigInteger instrLength= null;
if (j < instructions.length - 1) {
instrLength= instructions[j+1].getAdress().subtract(instruction.getAdress()).abs();
} else if (i < mixedInstructions.length - 1) {
int nextSrcLineIdx= i+1;
while (nextSrcLineIdx < mixedInstructions.length) {
IInstruction[] nextInstrs= mixedInstructions[nextSrcLineIdx].getInstructions();
if (nextInstrs.length > 0) {
instrLength= nextInstrs[0].getAdress().subtract(instruction.getAdress()).abs();
break;
}
++nextSrcLineIdx;
}
if (nextSrcLineIdx >= mixedInstructions.length) {
break;
}
} else if (instructions.length == 1) {
if (p.fAddressLength.compareTo(BigInteger.valueOf(8)) <= 0) {
instrLength= p.fAddressLength;
}
}
if (instrLength == null) {
// cannot determine length of last instruction
break;
}
final String opCode;
// insert function name+offset instead of opcode bytes
if (functionName != null && functionName.length() > 0) {
opCode= functionName + '+' + instruction.getOffset();
} else {
opCode= ""; //$NON-NLS-1$
}
insertedStartAddress= insertedStartAddress || address.compareTo(startAddress) == 0;
p = fCallback.getDocument().insertDisassemblyLine(p, address, instrLength.intValue(), opCode, instruction.getInstruction(), file, lineNumber);
if (p == null && insertedStartAddress) {
break;
}
}
}
} catch (BadLocationException e) {
// should not happen
DisassemblyUtils.internalError(e);
} finally {
fCallback.setUpdatePending(false);
if (insertedStartAddress) {
fCallback.updateInvalidSource();
fCallback.unlockScroller();
fCallback.doPending();
fCallback.updateVisibleArea();
} else {
fCallback.unlockScroller();
}
}
return insertedStartAddress;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#insertSource(org.eclipse.jface.text.Position, java.math.BigInteger, java.lang.String, int)
*/
public Object insertSource(Position pos, BigInteger address, final String file, int lineNumber) {
Object sourceElement = null;
final ISourceLookupDMContext ctx= DMContexts.getAncestorOfType(fTargetContext, ISourceLookupDMContext.class);
final DsfExecutor executor= getSession().getExecutor();
Query<Object> query= new Query<Object>() {
@Override
protected void execute(final DataRequestMonitor<Object> rm) {
final DataRequestMonitor<Object> request= new DataRequestMonitor<Object>(executor, rm) {
@Override
protected void handleSuccess() {
rm.setData(getData());
rm.done();
}
};
final ISourceLookup lookup= getService(ISourceLookup.class);
lookup.getSource(ctx, file, request);
}
};
try {
getSession().getExecutor().execute(query);
sourceElement= query.get();
} catch (InterruptedException exc) {
DisassemblyUtils.internalError(exc);
} catch (ExecutionException exc) {
DisassemblyUtils.internalError(exc);
}
return sourceElement;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#gotoSymbol(java.lang.String)
*/
public void gotoSymbol(final String symbol) {
final DsfExecutor executor= getSession().getExecutor();
executor.execute(new DsfRunnable() {
public void run() {
final IExpressions expressions= getService(IExpressions.class);
if (expressions == null) {
return;
}
IExpressionDMContext exprDmc= expressions.createExpression(fTargetContext, '&'+symbol);
final FormattedValueDMContext valueDmc= expressions.getFormattedValueContext(exprDmc, IFormattedValues.HEX_FORMAT);
expressions.getFormattedExpressionValue(valueDmc, new DataRequestMonitor<FormattedValueDMData>(executor, null) {
@Override
protected void handleSuccess() {
FormattedValueDMData data= getData();
final String value= data.getFormattedValue();
final BigInteger address= DisassemblyUtils.decodeAddress(value);
if (address != null) {
fCallback.asyncExec(new Runnable() {
public void run() {
fCallback.gotoAddress(address);
}});
}
}
@Override
protected void handleError() {
fCallback.asyncExec(new Runnable() {
public void run() {
ErrorDialog.openError(fCallback.getSite().getShell(), "Error", null, getStatus()); //$NON-NLS-1$
}});
}
});
}});
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#retrieveDisassembly(java.lang.String, int, java.math.BigInteger, boolean, boolean, boolean)
*/
public void retrieveDisassembly(final String file, final int lines, final BigInteger endAddress, boolean mixed, final boolean showSymbols, final boolean showDisassembly) {
String debuggerPath= file;
// try reverse lookup
final ISourceLookupDMContext ctx= DMContexts.getAncestorOfType(fTargetContext, ISourceLookupDMContext.class);
final DsfExecutor executor= getSession().getExecutor();
Query<String> query= new Query<String>() {
@Override
protected void execute(final DataRequestMonitor<String> rm) {
final DataRequestMonitor<String> request= new DataRequestMonitor<String>(executor, rm) {
@Override
protected void handleSuccess() {
rm.setData(getData());
rm.done();
}
};
final ISourceLookup lookup= getService(ISourceLookup.class);
lookup.getDebuggerPath(ctx, file, request);
}
};
try {
getSession().getExecutor().execute(query);
debuggerPath= query.get();
} catch (InterruptedException exc) {
internalError(exc);
} catch (ExecutionException exc) {
internalError(exc);
}
final IDisassemblyDMContext context= DMContexts.getAncestorOfType(fTargetContext, IDisassemblyDMContext.class);
final String finalFile= debuggerPath;
final DataRequestMonitor<IMixedInstruction[]> disassemblyRequest= new DataRequestMonitor<IMixedInstruction[]>(executor, null) {
@Override
public void handleCompleted() {
final IMixedInstruction[] data= getData();
if (!isCanceled() && data != null) {
fCallback.asyncExec(new Runnable() {
public void run() {
if (!insertDisassembly(null, endAddress, data, showSymbols, showDisassembly)) {
// retry in non-mixed mode
retrieveDisassembly(file, lines, endAddress, false, showSymbols, showDisassembly);
}
}});
} else {
final IStatus status= getStatus();
if (status != null && !status.isOK()) {
fCallback.asyncExec(new Runnable() {
public void run() {
ErrorDialog.openError(fCallback.getSite().getShell(), "Error", null, getStatus()); //$NON-NLS-1$
}
});
}
fCallback.setUpdatePending(false);
}
}
};
assert !fCallback.getUpdatePending();
fCallback.setUpdatePending(true);
executor.execute(new Runnable() {
public void run() {
final IDisassembly disassembly= fServicesTracker.getService(IDisassembly.class);
if (disassembly == null) {
disassemblyRequest.cancel();
disassemblyRequest.done();
return;
}
disassembly.getMixedInstructions(context, finalFile, 1, lines, disassemblyRequest);
}});
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend#evaluateExpression(java.lang.String)
*/
public String evaluateExpression(final String expression) {
if (fTargetFrameContext == null) {
return null;
}
final DsfExecutor executor= DsfSession.getSession(fDsfSessionId).getExecutor();
Query<FormattedValueDMData> query= new Query<FormattedValueDMData>() {
@Override
protected void execute(final DataRequestMonitor<FormattedValueDMData> rm) {
IExecutionDMContext exeCtx = DMContexts.getAncestorOfType(fTargetFrameContext, IExecutionDMContext.class);
final IRunControl rc= getService(IRunControl.class);
if (rc == null || !rc.isSuspended(exeCtx)) {
rm.done();
return;
}
final IExpressions expressions= getService(IExpressions.class);
if (expressions == null) {
rm.done();
return;
}
IExpressionDMContext exprDmc= expressions.createExpression(fTargetFrameContext, expression);
final FormattedValueDMContext valueDmc= expressions.getFormattedValueContext(exprDmc, IFormattedValues.NATURAL_FORMAT);
expressions.getFormattedExpressionValue(valueDmc, new DataRequestMonitor<FormattedValueDMData>(executor, rm) {
@Override
protected void handleSuccess() {
FormattedValueDMData data= getData();
rm.setData(data);
rm.done();
}
});
}};
executor.execute(query);
FormattedValueDMData data= null;
try {
data= query.get();
} catch (InterruptedException exc) {
} catch (ExecutionException exc) {
}
if (data != null) {
return data.getFormattedValue();
}
return null;
}
}

View file

@ -0,0 +1,37 @@
/*******************************************************************************
* Copyright (c) 2010 Freescale Semiconductor, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Freescale Semiconductor - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.internal.ui.disassembly;
import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyBackend;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IAdapterFactory;
/**
*/
public class DisassemblyBackendDsfFactory implements IAdapterFactory {
private static final Class<?>[] ADAPTERS = { IDisassemblyBackend.class };
@SuppressWarnings("rawtypes")
public Object getAdapter(Object adaptableObject, Class adapterType) {
if (IDisassemblyBackend.class.equals(adapterType)) {
if (adaptableObject instanceof IAdaptable && DisassemblyBackendDsf.supportsDebugContext_((IAdaptable)adaptableObject)) {
return new DisassemblyBackendDsf();
}
}
return null;
}
@SuppressWarnings("rawtypes")
public Class[] getAdapterList() {
return ADAPTERS;
}
}

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007, 2009 Wind River Systems and others. * Copyright (c) 2007, 2010 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -10,25 +10,10 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.debug.internal.ui.disassembly; package org.eclipse.cdt.dsf.debug.internal.ui.disassembly;
import java.util.concurrent.ExecutionException; import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition;
import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyPosition;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.LabelPosition;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
import org.eclipse.cdt.dsf.concurrent.Query;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.AddressRangePosition;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyPosition;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.LabelPosition;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourcePosition;
import org.eclipse.cdt.dsf.debug.service.IExpressions;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.cdt.internal.ui.text.CWordFinder; import org.eclipse.cdt.internal.ui.text.CWordFinder;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
@ -112,48 +97,7 @@ public class DisassemblyTextHover implements ITextHover {
* @return expression value or <code>null</code> * @return expression value or <code>null</code>
*/ */
private String evaluateExpression(final String expr) { private String evaluateExpression(final String expr) {
final IFrameDMContext frameDmc= fDisassemblyPart.getTargetFrameContext(); return fDisassemblyPart.evaluateExpression(expr);
if (frameDmc == null) {
return null;
}
final DsfExecutor executor= fDisassemblyPart.getSession().getExecutor();
Query<FormattedValueDMData> query= new Query<FormattedValueDMData>() {
@Override
protected void execute(final DataRequestMonitor<FormattedValueDMData> rm) {
IExecutionDMContext exeCtx = DMContexts.getAncestorOfType(frameDmc, IExecutionDMContext.class);
final IRunControl rc= fDisassemblyPart.getService(IRunControl.class);
if (rc == null || !rc.isSuspended(exeCtx)) {
rm.done();
return;
}
final IExpressions expressions= fDisassemblyPart.getService(IExpressions.class);
if (expressions == null) {
rm.done();
return;
}
IExpressionDMContext exprDmc= expressions.createExpression(frameDmc, expr);
final FormattedValueDMContext valueDmc= expressions.getFormattedValueContext(exprDmc, IFormattedValues.NATURAL_FORMAT);
expressions.getFormattedExpressionValue(valueDmc, new DataRequestMonitor<FormattedValueDMData>(executor, rm) {
@Override
protected void handleSuccess() {
FormattedValueDMData data= getData();
rm.setData(data);
rm.done();
}
});
}};
executor.execute(query);
FormattedValueDMData data= null;
try {
data= query.get();
} catch (InterruptedException exc) {
} catch (ExecutionException exc) {
}
if (data != null) {
return data.getFormattedValue();
}
return null;
} }
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others. * Copyright (c) 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -22,6 +22,7 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.Job;
import static org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyUtils.internalError;
/** /**
* A job to find a suitable edition from the local history * A job to find a suitable edition from the local history
@ -69,7 +70,7 @@ class EditionFinderJob extends Job {
token.wait(1000); token.wait(1000);
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
DisassemblyPart.internalError(e); internalError(e);
} }
token = fDisassemblyPart.retrieveModuleTimestamp(fAddress); token = fDisassemblyPart.retrieveModuleTimestamp(fAddress);
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007, 2009 Wind River Systems and others. * Copyright (c) 2007, 2010 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -10,9 +10,9 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.debug.internal.ui.disassembly; package org.eclipse.cdt.dsf.debug.internal.ui.disassembly;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.AddressRangePosition; import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition;
import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyPosition;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyPosition;
import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.BadLocationException;
/** /**

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007, 2008 Wind River Systems and others. * Copyright (c) 2007, 2010 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -8,10 +8,13 @@
* Contributors: * Contributors:
* Wind River Systems - initial API and implementation * Wind River Systems - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model; package org.eclipse.cdt.dsf.debug.internal.ui.disassembly;
import java.math.BigInteger; import java.math.BigInteger;
import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourceFileInfo;
/** /**
* SourcePosition * SourcePosition
*/ */
@ -47,4 +50,12 @@ public class SourcePosition extends AddressRangePosition {
fLine = line; fLine = line;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.AddressRangePosition#toString()
*/
@Override
public String toString() {
return super.toString() + "->["+fFileInfo.fFileKey + ':' + fLine + ']'; //$NON-NLS-1$
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2008, 2009 Wind River Systems, Inc. and others. * Copyright (c) 2008, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -10,10 +10,11 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions; package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions;
import static org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyUtils.decodeAddress;
import java.math.BigInteger; import java.math.BigInteger;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.DisassemblyMessages; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.DisassemblyMessages;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.DisassemblyPart;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.IDisassemblyPart; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.IDisassemblyPart;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IDialogConstants;
@ -34,7 +35,7 @@ public final class ActionGotoAddress extends AbstractDisassemblyAction {
if (input == null || input.length() == 0) if (input == null || input.length() == 0)
return " "; //$NON-NLS-1$ return " "; //$NON-NLS-1$
try { try {
BigInteger address= DisassemblyPart.decodeAddress(input); BigInteger address= decodeAddress(input);
if (address.compareTo(BigInteger.ZERO) < 0) { if (address.compareTo(BigInteger.ZERO) < 0) {
return DisassemblyMessages.Disassembly_GotoAddressDialog_error_invalid_address; return DisassemblyMessages.Disassembly_GotoAddressDialog_error_invalid_address;
} }
@ -57,7 +58,7 @@ public final class ActionGotoAddress extends AbstractDisassemblyAction {
InputDialog dlg = new InputDialog(shell, dlgTitle, dlgLabel, defaultValue, validator); InputDialog dlg = new InputDialog(shell, dlgTitle, dlgLabel, defaultValue, validator);
if (dlg.open() == IDialogConstants.OK_ID) { if (dlg.open() == IDialogConstants.OK_ID) {
String value = dlg.getValue(); String value = dlg.getValue();
BigInteger address= DisassemblyPart.decodeAddress(value); BigInteger address= decodeAddress(value);
DsfUIPlugin.getDefault().getDialogSettings().put("gotoAddress", value); //$NON-NLS-1$ DsfUIPlugin.getDefault().getDialogSettings().put("gotoAddress", value); //$NON-NLS-1$
getDisassemblyPart().gotoAddress(address); getDisassemblyPart().gotoAddress(address);
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009 Texas Instruments, Inc. and others. * Copyright (c) 2009, 2010 Texas Instruments, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -16,6 +16,7 @@ import java.math.BigInteger;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.DisassemblyMessages; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.DisassemblyMessages;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.DisassemblyPart; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.DisassemblyPart;
import org.eclipse.jface.action.Action; import org.eclipse.jface.action.Action;
import static org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyUtils.decodeAddress;
public class JumpToAddressAction extends Action { public class JumpToAddressAction extends Action {
@ -37,7 +38,7 @@ public class JumpToAddressAction extends Action {
location = location.trim(); location = location.trim();
BigInteger address = null; BigInteger address = null;
try { try {
address = DisassemblyPart.decodeAddress(location); address = decodeAddress(location);
if (address.compareTo(BigInteger.ZERO) < 0) { if (address.compareTo(BigInteger.ZERO) < 0) {
address = null; address = null;
addressBar.setWarningIconVisible(true); addressBar.setWarningIconVisible(true);

View file

@ -18,6 +18,8 @@ import java.util.Iterator;
import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint; import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint;
import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint;
import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition;
import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.LabelPosition;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.IBreakpointLocationProvider; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.IBreakpointLocationProvider;
import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarker;

View file

@ -10,14 +10,23 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model; package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model;
import static org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyUtils.DEBUG;
import java.io.File; import java.io.File;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition;
import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyPosition;
import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.ErrorPosition;
import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyDocument;
import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.LabelPosition;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.SourcePosition;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.text.REDDocument; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.text.REDDocument;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.text.REDTextStore; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.text.REDTextStore;
import org.eclipse.core.resources.IStorage; import org.eclipse.core.resources.IStorage;
@ -32,21 +41,32 @@ import org.eclipse.jface.text.DocumentRewriteSessionType;
import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Position; import org.eclipse.jface.text.Position;
import org.eclipse.swt.widgets.Display;
/** /**
* DisassemblyDocument * DisassemblyDocument
*/ */
public class DisassemblyDocument extends REDDocument { public class DisassemblyDocument extends REDDocument implements IDisassemblyDocument {
public final static String CATEGORY_MODEL = "category_model"; //$NON-NLS-1$ public final static String CATEGORY_MODEL = "category_model"; //$NON-NLS-1$
public final static String CATEGORY_DISASSEMBLY = "category_disassembly"; //$NON-NLS-1$ public final static String CATEGORY_DISASSEMBLY = "category_disassembly"; //$NON-NLS-1$
public final static String CATEGORY_SOURCE = "category_source"; //$NON-NLS-1$ public final static String CATEGORY_SOURCE = "category_source"; //$NON-NLS-1$
public final static String CATEGORY_LABELS = "category_labels"; //$NON-NLS-1$ public final static String CATEGORY_LABELS = "category_labels"; //$NON-NLS-1$
private final static boolean DEBUG = false; /**
* For ease of troubleshooting, don't add or remove from this list directly.
* Use the add/remove methods. Note that we're not the only ones that
* manipulate the list. This list should be accessed only from the GUI thread
*/
private final List<AddressRangePosition> fInvalidAddressRanges = new ArrayList<AddressRangePosition>();
/**
* For ease of troubleshooting, don't add or remove from this list directly.
* Use the add/remove methods. Note that we're not the only ones that
* manipulate the list. This list should be accessed only from the GUI thread
*/
private final List<SourcePosition> fInvalidSource = new ArrayList<SourcePosition>();
private final ArrayList<AddressRangePosition> fInvalidAddressRanges = new ArrayList<AddressRangePosition>();
private final ArrayList<SourcePosition> fInvalidSource = new ArrayList<SourcePosition>();
private final Map<IStorage, SourceFileInfo> fFileInfoMap = new HashMap<IStorage, SourceFileInfo>(); private final Map<IStorage, SourceFileInfo> fFileInfoMap = new HashMap<IStorage, SourceFileInfo>();
private int fMaxFunctionLength = 0; private int fMaxFunctionLength = 0;
@ -88,14 +108,19 @@ public class DisassemblyDocument extends REDDocument {
*/ */
@Override @Override
public void dispose() { public void dispose() {
assert isGuiThread();
super.dispose(); super.dispose();
// cleanup source info // cleanup source info
for (Iterator<SourceFileInfo> iter = fFileInfoMap.values().iterator(); iter.hasNext();) { for (Iterator<SourceFileInfo> iter = fFileInfoMap.values().iterator(); iter.hasNext();) {
SourceFileInfo fi = iter.next(); SourceFileInfo fi = iter.next();
fi.dispose(); fi.dispose();
} }
fFileInfoMap.clear(); fFileInfoMap.clear();
fInvalidAddressRanges.clear(); fInvalidAddressRanges.clear();
fInvalidSource.clear(); fInvalidSource.clear();
} }
@ -109,12 +134,9 @@ public class DisassemblyDocument extends REDDocument {
completeInitialization(); completeInitialization();
} }
public List<AddressRangePosition> getInvalidAddressRanges() { public AddressRangePosition[] getInvalidAddressRanges() {
return fInvalidAddressRanges; assert isGuiThread();
} return fInvalidAddressRanges.toArray(new AddressRangePosition[fInvalidAddressRanges.size()]);
public List<SourcePosition> getInvalidSource() {
return fInvalidSource;
} }
public void setMaxOpcodeLength(int opcodeLength) { public void setMaxOpcodeLength(int opcodeLength) {
@ -690,9 +712,8 @@ public class DisassemblyDocument extends REDDocument {
if (list == null) { if (list == null) {
throw new BadPositionCategoryException(); throw new BadPositionCategoryException();
} }
int idx; if (DEBUG) System.out.println("Adding position to category <" + category + "> : " + pos); //$NON-NLS-1$ //$NON-NLS-2$
idx = computeIndexInPositionListLast(list, pos.fAddressOffset); list.add(computeIndexInPositionListLast(list, pos.fAddressOffset), pos);
list.add(idx, pos);
} }
/** /**
@ -771,7 +792,10 @@ public class DisassemblyDocument extends REDDocument {
@Override @Override
public void removePosition(String category, Position position) throws BadPositionCategoryException { public void removePosition(String category, Position position) throws BadPositionCategoryException {
super.removePosition(category, position); super.removePosition(category, position);
if (category != CATEGORY_MODEL && position instanceof AddressRangePosition) {
if (DEBUG && isOneOfOurs(category)) System.out.println("Removing position from category(" + category + ") :" + position); //$NON-NLS-1$ //$NON-NLS-2$
if (!category.equals(CATEGORY_MODEL) && position instanceof AddressRangePosition) {
super.removePosition(CATEGORY_MODEL, position); super.removePosition(CATEGORY_MODEL, position);
} }
} }
@ -781,6 +805,15 @@ public class DisassemblyDocument extends REDDocument {
if (toRemove.isEmpty()) { if (toRemove.isEmpty()) {
return; return;
} }
if (DEBUG && isOneOfOurs(category)) {
System.out.println("Removing positions from category(" + category + ')'); //$NON-NLS-1$
int i = 0;
for (AddressRangePosition pos : toRemove) {
System.out.println("[" + i++ +"] " + pos); //$NON-NLS-1$ //$NON-NLS-2$
}
}
List<Position> positions = (List<Position>) getDocumentManagedPositions().get(category); List<Position> positions = (List<Position>) getDocumentManagedPositions().get(category);
if (positions != null) { if (positions != null) {
positions.removeAll(toRemove); positions.removeAll(toRemove);
@ -857,6 +890,16 @@ public class DisassemblyDocument extends REDDocument {
pos.offset += delta; pos.offset += delta;
} }
} }
if (DEBUG) {
String escapedText = null;
if (text != null) {
escapedText = text.replace(new StringBuffer("\n"), new StringBuffer("\\n")); //$NON-NLS-1$ //$NON-NLS-2$
escapedText = escapedText.replace(new StringBuffer("\r"), new StringBuffer("\\r")); //$NON-NLS-1$ //$NON-NLS-2$
escapedText = escapedText.replace(new StringBuffer("\t"), new StringBuffer("\\t")); //$NON-NLS-1$ //$NON-NLS-2$
}
System.out.println("Calling AbstractDocument.replace("+insertPos.offset+','+replaceLength+",\""+escapedText+"\")"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
}
super.replace(insertPos.offset, replaceLength, text); super.replace(insertPos.offset, replaceLength, text);
} }
@ -869,6 +912,7 @@ public class DisassemblyDocument extends REDDocument {
*/ */
public AddressRangePosition insertAddressRange(AddressRangePosition pos, AddressRangePosition insertPos, String line, boolean addToModel) public AddressRangePosition insertAddressRange(AddressRangePosition pos, AddressRangePosition insertPos, String line, boolean addToModel)
throws BadLocationException { throws BadLocationException {
assert isGuiThread();
final BigInteger address = insertPos.fAddressOffset; final BigInteger address = insertPos.fAddressOffset;
BigInteger length = insertPos.fAddressLength; BigInteger length = insertPos.fAddressLength;
if (pos == null) { if (pos == null) {
@ -896,7 +940,7 @@ public class DisassemblyDocument extends REDDocument {
it.remove(); it.remove();
removeModelPosition(overlap); removeModelPosition(overlap);
if (!overlap.fValid) { if (!overlap.fValid) {
fInvalidAddressRanges.remove(overlap); removeInvalidAddressRange(overlap);
} }
} while(!pos.containsAddress(address.add(length.subtract(BigInteger.ONE)))); } while(!pos.containsAddress(address.add(length.subtract(BigInteger.ONE))));
} }
@ -914,7 +958,7 @@ public class DisassemblyDocument extends REDDocument {
newEndAddress = newStartAddress; newEndAddress = newStartAddress;
} else { } else {
replaceLength += pos.length; replaceLength += pos.length;
fInvalidAddressRanges.remove(pos); removeInvalidAddressRange(pos);
removeDisassemblyPosition(pos); removeDisassemblyPosition(pos);
pos = null; pos = null;
} }
@ -940,16 +984,12 @@ public class DisassemblyDocument extends REDDocument {
return pos; return pos;
} }
/** /* (non-Javadoc)
* @param pos * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyDocument#insertDisassemblyLine(org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition, java.math.BigInteger, int, java.lang.String, java.lang.String, java.lang.String, int)
* @param address
* @param length
* @param instruction
* @throws BadPositionCategoryException
* @throws BadLocationException
*/ */
public AddressRangePosition insertDisassemblyLine(AddressRangePosition pos, BigInteger address, int length, String opcode, String instruction, String file, int lineNr) public AddressRangePosition insertDisassemblyLine(AddressRangePosition pos, BigInteger address, int length, String opcode, String instruction, String file, int lineNr)
throws BadLocationException { throws BadLocationException {
assert isGuiThread();
String disassLine = null; String disassLine = null;
if (instruction == null || instruction.length() == 0) { if (instruction == null || instruction.length() == 0) {
disassLine = ""; //$NON-NLS-1$ disassLine = ""; //$NON-NLS-1$
@ -1037,6 +1077,7 @@ public class DisassemblyDocument extends REDDocument {
public AddressRangePosition insertErrorLine(AddressRangePosition pos, BigInteger address, BigInteger length, String line) public AddressRangePosition insertErrorLine(AddressRangePosition pos, BigInteger address, BigInteger length, String line)
throws BadLocationException { throws BadLocationException {
assert isGuiThread();
int hashCode = line.hashCode(); int hashCode = line.hashCode();
final long alignment = fErrorAlignment; final long alignment = fErrorAlignment;
if (alignment > 1 && !(pos instanceof ErrorPosition)) { if (alignment > 1 && !(pos instanceof ErrorPosition)) {
@ -1053,7 +1094,7 @@ public class DisassemblyDocument extends REDDocument {
if (pos.fAddressLength.compareTo(BigInteger.ZERO) == 0) { if (pos.fAddressLength.compareTo(BigInteger.ZERO) == 0) {
replace(pos, pos.length, null); replace(pos, pos.length, null);
removeModelPosition(pos); removeModelPosition(pos);
fInvalidAddressRanges.remove(pos); removeInvalidAddressRange(pos);
pos = null; pos = null;
} else { } else {
pos.fAddressOffset = pos.fAddressOffset.add(mergeLen); pos.fAddressOffset = pos.fAddressOffset.add(mergeLen);
@ -1081,7 +1122,7 @@ public class DisassemblyDocument extends REDDocument {
if (pos.fAddressLength.compareTo(BigInteger.ZERO) == 0) { if (pos.fAddressLength.compareTo(BigInteger.ZERO) == 0) {
replace(pos, pos.length, null); replace(pos, pos.length, null);
removeModelPosition(pos); removeModelPosition(pos);
fInvalidAddressRanges.remove(pos); removeInvalidAddressRange(pos);
pos = null; pos = null;
} }
if (DEBUG) checkConsistency(); if (DEBUG) checkConsistency();
@ -1101,7 +1142,7 @@ public class DisassemblyDocument extends REDDocument {
pos = insertAddressRange(pos, errorPos, errorLine, true); pos = insertAddressRange(pos, errorPos, errorLine, true);
addDisassemblyPosition(errorPos); addDisassemblyPosition(errorPos);
if (!errorPos.fValid) { if (!errorPos.fValid) {
fInvalidAddressRanges.add(errorPos); addInvalidAddressRange(errorPos);
} }
length = length.subtract(posLen); length = length.subtract(posLen);
address = address.add(posLen); address = address.add(posLen);
@ -1110,15 +1151,12 @@ public class DisassemblyDocument extends REDDocument {
return pos; return pos;
} }
/** /* (non-Javadoc)
* @param pos * @see org.eclipse.cdt.debug.internal.ui.disassembly.dsf.IDisassemblyDocument#insertLabel(org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition, java.math.BigInteger, java.lang.String, boolean)
* @param address
* @param label
* @throws BadLocationException
* @throws BadPositionCategoryException
*/ */
public AddressRangePosition insertLabel(AddressRangePosition pos, BigInteger address, String label, boolean showLabels) public AddressRangePosition insertLabel(AddressRangePosition pos, BigInteger address, String label, boolean showLabels)
throws BadLocationException { throws BadLocationException {
assert isGuiThread();
String labelLine = showLabels ? label + ":\n" : ""; //$NON-NLS-1$ //$NON-NLS-2$ String labelLine = showLabels ? label + ":\n" : ""; //$NON-NLS-1$ //$NON-NLS-2$
LabelPosition labelPos = getLabelPosition(address); LabelPosition labelPos = getLabelPosition(address);
if (labelPos != null) { if (labelPos != null) {
@ -1158,7 +1196,7 @@ public class DisassemblyDocument extends REDDocument {
pos.length = sourceLines.length(); pos.length = sourceLines.length();
pos.fLine = line; pos.fLine = line;
pos.fValid = true; pos.fValid = true;
fInvalidSource.remove(pos); removeInvalidSourcePosition(pos);
replace(pos, oldLength, sourceLines); replace(pos, oldLength, sourceLines);
if (!endOfSource) { if (!endOfSource) {
if (pos.length > 0) { if (pos.length > 0) {
@ -1167,7 +1205,7 @@ public class DisassemblyDocument extends REDDocument {
pos = new SourcePosition(pos.offset+pos.length, 0, pos.fAddressOffset, pos.fFileInfo, line, false); pos = new SourcePosition(pos.offset+pos.length, 0, pos.fAddressOffset, pos.fFileInfo, line, false);
addSourcePosition(pos); addSourcePosition(pos);
addModelPosition(pos); addModelPosition(pos);
fInvalidSource.add(pos); addInvalidSourcePositions(pos);
} else { } else {
//TLETODO need more checks for correct source pos //TLETODO need more checks for correct source pos
pos = oldPos; pos = oldPos;
@ -1188,6 +1226,7 @@ public class DisassemblyDocument extends REDDocument {
* @return * @return
*/ */
public AddressRangePosition insertInvalidSource(AddressRangePosition pos, BigInteger address, SourceFileInfo fi, int lineNr) { public AddressRangePosition insertInvalidSource(AddressRangePosition pos, BigInteger address, SourceFileInfo fi, int lineNr) {
assert isGuiThread();
SourcePosition sourcePos = getSourcePosition(address); SourcePosition sourcePos = getSourcePosition(address);
if (sourcePos != null) { if (sourcePos != null) {
return pos; return pos;
@ -1198,7 +1237,7 @@ public class DisassemblyDocument extends REDDocument {
pos = insertAddressRange(pos, sourcePos, sourceLine, true); pos = insertAddressRange(pos, sourcePos, sourceLine, true);
addSourcePosition(sourcePos); addSourcePosition(sourcePos);
assert !fInvalidSource.contains(sourcePos); assert !fInvalidSource.contains(sourcePos);
fInvalidSource.add(sourcePos); addInvalidSourcePositions(sourcePos);
} catch (BadLocationException e) { } catch (BadLocationException e) {
internalError(e); internalError(e);
} }
@ -1213,6 +1252,7 @@ public class DisassemblyDocument extends REDDocument {
* @return * @return
*/ */
public AddressRangePosition insertInvalidAddressRange(int offset, int replaceLength, BigInteger startAddress, BigInteger endAddress) { public AddressRangePosition insertInvalidAddressRange(int offset, int replaceLength, BigInteger startAddress, BigInteger endAddress) {
assert isGuiThread();
String periods = "...\n"; //$NON-NLS-1$ String periods = "...\n"; //$NON-NLS-1$
AddressRangePosition newPos = new AddressRangePosition(offset, periods.length(), startAddress, endAddress AddressRangePosition newPos = new AddressRangePosition(offset, periods.length(), startAddress, endAddress
.subtract(startAddress), false); .subtract(startAddress), false);
@ -1220,7 +1260,7 @@ public class DisassemblyDocument extends REDDocument {
addModelPositionFirst(newPos); addModelPositionFirst(newPos);
replace(newPos, replaceLength, periods); replace(newPos, replaceLength, periods);
addDisassemblyPosition(newPos); addDisassemblyPosition(newPos);
fInvalidAddressRanges.add(newPos); addInvalidAddressRange(newPos);
} catch (BadLocationException e) { } catch (BadLocationException e) {
internalError(e); internalError(e);
} }
@ -1232,6 +1272,7 @@ public class DisassemblyDocument extends REDDocument {
} }
public void deleteDisassemblyRange(BigInteger startAddress, BigInteger endAddress, boolean invalidate, boolean collapse) { public void deleteDisassemblyRange(BigInteger startAddress, BigInteger endAddress, boolean invalidate, boolean collapse) {
assert isGuiThread();
DocumentRewriteSession session = startRewriteSession(DocumentRewriteSessionType.STRICTLY_SEQUENTIAL); DocumentRewriteSession session = startRewriteSession(DocumentRewriteSessionType.STRICTLY_SEQUENTIAL);
try { try {
String replacement = invalidate ? "...\n" : null; //$NON-NLS-1$ String replacement = invalidate ? "...\n" : null; //$NON-NLS-1$
@ -1267,7 +1308,7 @@ public class DisassemblyDocument extends REDDocument {
lastPos.fAddressLength = lastPos.fAddressLength.add(pos.fAddressLength); lastPos.fAddressLength = lastPos.fAddressLength.add(pos.fAddressLength);
toRemove.add(pos); toRemove.add(pos);
if (!pos.fValid) { if (!pos.fValid) {
fInvalidAddressRanges.remove(pos); removeInvalidAddressRange(pos);
} }
pos = null; pos = null;
if (posEndAddress.compareTo(endAddress) < 0) { if (posEndAddress.compareTo(endAddress) < 0) {
@ -1293,7 +1334,7 @@ public class DisassemblyDocument extends REDDocument {
if (pos != null) { if (pos != null) {
if (pos.fValid && invalidate) { if (pos.fValid && invalidate) {
pos.fValid = false; pos.fValid = false;
fInvalidAddressRanges.add(pos); addInvalidAddressRange(pos);
} }
lastPos = pos; lastPos = pos;
} }
@ -1306,6 +1347,7 @@ public class DisassemblyDocument extends REDDocument {
} }
public void invalidateSource() { public void invalidateSource() {
assert isGuiThread();
Iterator<Position> it; Iterator<Position> it;
try { try {
it = getPositionIterator(CATEGORY_SOURCE, 0); it = getPositionIterator(CATEGORY_SOURCE, 0);
@ -1317,12 +1359,34 @@ public class DisassemblyDocument extends REDDocument {
SourcePosition srcPos = (SourcePosition)it.next(); SourcePosition srcPos = (SourcePosition)it.next();
if (srcPos != null && srcPos.fValid) { if (srcPos != null && srcPos.fValid) {
srcPos.fValid = false; srcPos.fValid = false;
assert !getInvalidSource().contains(srcPos); assert !fInvalidSource.contains(srcPos);
getInvalidSource().add(srcPos); addInvalidSourcePositions(srcPos);
} }
} }
} }
public SourcePosition[] getInvalidSourcePositions() {
assert isGuiThread();
return fInvalidSource.toArray(new SourcePosition[fInvalidSource.size()]);
}
public boolean addInvalidSourcePositions(SourcePosition srcPos) {
assert isGuiThread();
if (DEBUG) System.out.println("Adding invalid source position to list: " + srcPos); //$NON-NLS-1$
return fInvalidSource.add(srcPos);
}
public boolean removeInvalidSourcePosition(SourcePosition srcPos) {
assert isGuiThread();
if (DEBUG) System.out.println("Removing invalid source position from list: " + srcPos); //$NON-NLS-1$
return fInvalidSource.remove(srcPos);
}
public boolean hasInvalidSourcePositions() {
assert isGuiThread();
return fInvalidSource.size() > 0;
}
public void invalidateDisassemblyWithSource(boolean removeDisassembly) { public void invalidateDisassemblyWithSource(boolean removeDisassembly) {
for (Iterator<SourceFileInfo> it = fFileInfoMap.values().iterator(); it.hasNext();) { for (Iterator<SourceFileInfo> it = fFileInfoMap.values().iterator(); it.hasNext();) {
SourceFileInfo info = it.next(); SourceFileInfo info = it.next();
@ -1338,6 +1402,7 @@ public class DisassemblyDocument extends REDDocument {
* @throws BadLocationException * @throws BadLocationException
*/ */
public void deleteLineRange(int start, int end) throws BadLocationException { public void deleteLineRange(int start, int end) throws BadLocationException {
assert isGuiThread();
if (start >= end) { if (start >= end) {
return; return;
} }
@ -1365,9 +1430,9 @@ public class DisassemblyDocument extends REDDocument {
toRemove.add(p); toRemove.add(p);
if (!p.fValid) { if (!p.fValid) {
if (p instanceof SourcePosition) { if (p instanceof SourcePosition) {
getInvalidSource().remove(p); removeInvalidSourcePosition((SourcePosition)p);
} else { } else {
getInvalidAddressRanges().remove(p); removeInvalidAddressRange(p);
} }
} }
if (addressLength.compareTo(BigInteger.ZERO) > 0 && p.fAddressOffset.compareTo(endPos.fAddressOffset) >= 0) { if (addressLength.compareTo(BigInteger.ZERO) > 0 && p.fAddressOffset.compareTo(endPos.fAddressOffset) >= 0) {
@ -1446,4 +1511,35 @@ public class DisassemblyDocument extends REDDocument {
} }
} }
public void addInvalidAddressRange(AddressRangePosition pos) {
assert isGuiThread();
if (DEBUG) System.out.println("Adding to invalid range list: " + pos); //$NON-NLS-1$
fInvalidAddressRanges.add(pos);
}
public void removeInvalidAddressRanges(Collection<AddressRangePosition> positions) {
assert isGuiThread();
if (DEBUG) {
for (AddressRangePosition pos : positions)
System.out.println("Removing from invalid range list: " + pos); //$NON-NLS-1$
}
fInvalidAddressRanges.removeAll(positions);
}
public void removeInvalidAddressRange(AddressRangePosition pos) {
assert isGuiThread();
if (DEBUG) System.out.println("Removing from invalid range list: " + pos); //$NON-NLS-1$
fInvalidAddressRanges.remove(pos);
}
private static boolean isGuiThread() {
return Display.getCurrent() != null;
}
private static boolean isOneOfOurs(String category) {
return category.equals(CATEGORY_MODEL) ||
category.equals(CATEGORY_DISASSEMBLY) ||
category.equals(CATEGORY_LABELS) ||
category.equals(CATEGORY_SOURCE);
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007, 2008 Wind River Systems and others. * Copyright (c) 2007, 2010 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -12,6 +12,8 @@ package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model;
import java.math.BigInteger; import java.math.BigInteger;
import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyPosition;
/** /**
* DisassemblyWithSourcePosition * DisassemblyWithSourcePosition
*/ */
@ -43,4 +45,12 @@ public class DisassemblyWithSourcePosition extends DisassemblyPosition {
return fLine; return fLine;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyPosition#toString()
*/
@Override
public String toString() {
return super.toString() + "->["+fFile + ':' + fLine + ']'; //$NON-NLS-1$
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009 Wind River Systems, Inc. and others. * Copyright (c) 2009, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -13,9 +13,9 @@ package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional;
import java.math.BigInteger; import java.math.BigInteger;
import java.net.URI; import java.net.URI;
import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyPosition;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.SourcePosition;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.DisassemblyPosition;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourcePosition;
import org.eclipse.core.filesystem.URIUtil; import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResource;

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2006, 2008 Wind River Systems and others. * Copyright (c) 2006, 2010 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -11,7 +11,9 @@
package org.eclipse.cdt.dsf.internal.ui; package org.eclipse.cdt.dsf.internal.ui;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.DisassemblyBackendDsfFactory;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourceDocumentProvider; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourceDocumentProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
@ -55,6 +57,10 @@ public class DsfUIPlugin extends AbstractUIPlugin {
DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.cdt.dsf.ui/debug")); //$NON-NLS-1$//$NON-NLS-2$ DEBUG = "true".equals(Platform.getDebugOption("org.eclipse.cdt.dsf.ui/debug")); //$NON-NLS-1$//$NON-NLS-2$
fSourceDocumentProvider = new SourceDocumentProvider(); fSourceDocumentProvider = new SourceDocumentProvider();
// Register the DSF backend for our disassembly view (the CDT debug UI
// plugin registers the CDI one)
Platform.getAdapterManager().registerAdapters(new DisassemblyBackendDsfFactory(), IDMVMContext.class);
} }
/* /*