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.actions;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.preferences;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
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
@ -40,4 +40,7 @@ CDTDebugModelPresentation.24=-Infinity
CDTDebugModelPresentation.25=(disabled)
CBreakpointWorkbenchAdapterFactory.0=C/C++ breakpoint
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
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -8,7 +8,7 @@
* Contributors:
* 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;
@ -63,4 +63,15 @@ public class AddressRangePosition extends Position {
// identity comparison
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:
* 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;
@ -45,5 +45,12 @@ public class DisassemblyPosition extends AddressRangePosition {
public int getLine() {
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
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -8,7 +8,7 @@
* Contributors:
* 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;
@ -37,4 +37,12 @@ public class ErrorPosition extends AddressRangePosition {
public int hashCode() {
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
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -8,7 +8,7 @@
* Contributors:
* 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;
@ -28,5 +28,12 @@ public class LabelPosition extends AddressRangePosition {
super(offset, length, addressOffset, BigInteger.ZERO);
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
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -16,6 +16,7 @@ import java.util.HashMap;
import java.util.Map;
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.CDebugImageDescriptorRegistry;
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.EvaluationContextManager;
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.ui.sourcelookup.DefaultSourceLocator;
import org.eclipse.cdt.debug.ui.sourcelookup.OldDefaultSourceLocator;
@ -289,6 +291,9 @@ public class CDebugUIPlugin extends AbstractUIPlugin {
EvaluationContextManager.startup();
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
// criteria to enable only when this plugin is loaded. This can lead 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
* are made available under the terms of the Eclipse Public License v1.0
* 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 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.SourceFileInfo;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourcePosition;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.source.IAnnotationHover;
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
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -10,25 +10,10 @@
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.internal.ui.disassembly;
import java.util.concurrent.ExecutionException;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
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.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.LabelPosition;
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.internal.ui.text.CWordFinder;
import org.eclipse.core.runtime.IStatus;
@ -112,48 +97,7 @@ public class DisassemblyTextHover implements ITextHover {
* @return expression value or <code>null</code>
*/
private String evaluateExpression(final String expr) {
final IFrameDMContext frameDmc= fDisassemblyPart.getTargetFrameContext();
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;
return fDisassemblyPart.evaluateExpression(expr);
}
}

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
* are made available under the terms of the Eclipse Public License v1.0
* 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.SubProgressMonitor;
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
@ -69,7 +70,7 @@ class EditionFinderJob extends Job {
token.wait(1000);
}
} catch (InterruptedException e) {
DisassemblyPart.internalError(e);
internalError(e);
}
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
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -10,9 +10,9 @@
*******************************************************************************/
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.DisassemblyPosition;
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
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -8,10 +8,13 @@
* Contributors:
* 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 org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourceFileInfo;
/**
* SourcePosition
*/
@ -46,5 +49,13 @@ public class SourcePosition extends AddressRangePosition {
fFileInfo = fileInfo;
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
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -10,10 +10,11 @@
*******************************************************************************/
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 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.internal.ui.DsfUIPlugin;
import org.eclipse.jface.dialogs.IDialogConstants;
@ -34,7 +35,7 @@ public final class ActionGotoAddress extends AbstractDisassemblyAction {
if (input == null || input.length() == 0)
return " "; //$NON-NLS-1$
try {
BigInteger address= DisassemblyPart.decodeAddress(input);
BigInteger address= decodeAddress(input);
if (address.compareTo(BigInteger.ZERO) < 0) {
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);
if (dlg.open() == IDialogConstants.OK_ID) {
String value = dlg.getValue();
BigInteger address= DisassemblyPart.decodeAddress(value);
BigInteger address= decodeAddress(value);
DsfUIPlugin.getDefault().getDialogSettings().put("gotoAddress", value); //$NON-NLS-1$
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
* are made available under the terms of the Eclipse Public License v1.0
* 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.DisassemblyPart;
import org.eclipse.jface.action.Action;
import static org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyUtils.decodeAddress;
public class JumpToAddressAction extends Action {
@ -37,7 +38,7 @@ public class JumpToAddressAction extends Action {
location = location.trim();
BigInteger address = null;
try {
address = DisassemblyPart.decodeAddress(location);
address = decodeAddress(location);
if (address.compareTo(BigInteger.ZERO) < 0) {
address = null;
addressBar.setWarningIconVisible(true);

View file

@ -18,6 +18,8 @@ import java.util.Iterator;
import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint;
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.core.resources.IFile;
import org.eclipse.core.resources.IMarker;

View file

@ -10,14 +10,23 @@
*******************************************************************************/
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.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
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.REDTextStore;
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.IRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.swt.widgets.Display;
/**
* 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_DISASSEMBLY = "category_disassembly"; //$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$
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>();
private final ArrayList<AddressRangePosition> fInvalidAddressRanges = new ArrayList<AddressRangePosition>();
private final ArrayList<SourcePosition> fInvalidSource = new ArrayList<SourcePosition>();
/**
* 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 Map<IStorage, SourceFileInfo> fFileInfoMap = new HashMap<IStorage, SourceFileInfo>();
private int fMaxFunctionLength = 0;
@ -88,14 +108,19 @@ public class DisassemblyDocument extends REDDocument {
*/
@Override
public void dispose() {
assert isGuiThread();
super.dispose();
// cleanup source info
for (Iterator<SourceFileInfo> iter = fFileInfoMap.values().iterator(); iter.hasNext();) {
SourceFileInfo fi = iter.next();
fi.dispose();
}
fFileInfoMap.clear();
fInvalidAddressRanges.clear();
fInvalidSource.clear();
}
@ -109,12 +134,9 @@ public class DisassemblyDocument extends REDDocument {
completeInitialization();
}
public List<AddressRangePosition> getInvalidAddressRanges() {
return fInvalidAddressRanges;
}
public List<SourcePosition> getInvalidSource() {
return fInvalidSource;
public AddressRangePosition[] getInvalidAddressRanges() {
assert isGuiThread();
return fInvalidAddressRanges.toArray(new AddressRangePosition[fInvalidAddressRanges.size()]);
}
public void setMaxOpcodeLength(int opcodeLength) {
@ -690,9 +712,8 @@ public class DisassemblyDocument extends REDDocument {
if (list == null) {
throw new BadPositionCategoryException();
}
int idx;
idx = computeIndexInPositionListLast(list, pos.fAddressOffset);
list.add(idx, pos);
if (DEBUG) System.out.println("Adding position to category <" + category + "> : " + pos); //$NON-NLS-1$ //$NON-NLS-2$
list.add(computeIndexInPositionListLast(list, pos.fAddressOffset), pos);
}
/**
@ -771,7 +792,10 @@ public class DisassemblyDocument extends REDDocument {
@Override
public void removePosition(String category, Position position) throws BadPositionCategoryException {
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);
}
}
@ -781,6 +805,15 @@ public class DisassemblyDocument extends REDDocument {
if (toRemove.isEmpty()) {
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);
if (positions != null) {
positions.removeAll(toRemove);
@ -857,6 +890,16 @@ public class DisassemblyDocument extends REDDocument {
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);
}
@ -869,6 +912,7 @@ public class DisassemblyDocument extends REDDocument {
*/
public AddressRangePosition insertAddressRange(AddressRangePosition pos, AddressRangePosition insertPos, String line, boolean addToModel)
throws BadLocationException {
assert isGuiThread();
final BigInteger address = insertPos.fAddressOffset;
BigInteger length = insertPos.fAddressLength;
if (pos == null) {
@ -896,7 +940,7 @@ public class DisassemblyDocument extends REDDocument {
it.remove();
removeModelPosition(overlap);
if (!overlap.fValid) {
fInvalidAddressRanges.remove(overlap);
removeInvalidAddressRange(overlap);
}
} while(!pos.containsAddress(address.add(length.subtract(BigInteger.ONE))));
}
@ -914,7 +958,7 @@ public class DisassemblyDocument extends REDDocument {
newEndAddress = newStartAddress;
} else {
replaceLength += pos.length;
fInvalidAddressRanges.remove(pos);
removeInvalidAddressRange(pos);
removeDisassemblyPosition(pos);
pos = null;
}
@ -940,16 +984,12 @@ public class DisassemblyDocument extends REDDocument {
return pos;
}
/**
* @param pos
* @param address
* @param length
* @param instruction
* @throws BadPositionCategoryException
* @throws BadLocationException
/* (non-Javadoc)
* @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)
*/
public AddressRangePosition insertDisassemblyLine(AddressRangePosition pos, BigInteger address, int length, String opcode, String instruction, String file, int lineNr)
throws BadLocationException {
assert isGuiThread();
String disassLine = null;
if (instruction == null || instruction.length() == 0) {
disassLine = ""; //$NON-NLS-1$
@ -1037,6 +1077,7 @@ public class DisassemblyDocument extends REDDocument {
public AddressRangePosition insertErrorLine(AddressRangePosition pos, BigInteger address, BigInteger length, String line)
throws BadLocationException {
assert isGuiThread();
int hashCode = line.hashCode();
final long alignment = fErrorAlignment;
if (alignment > 1 && !(pos instanceof ErrorPosition)) {
@ -1053,7 +1094,7 @@ public class DisassemblyDocument extends REDDocument {
if (pos.fAddressLength.compareTo(BigInteger.ZERO) == 0) {
replace(pos, pos.length, null);
removeModelPosition(pos);
fInvalidAddressRanges.remove(pos);
removeInvalidAddressRange(pos);
pos = null;
} else {
pos.fAddressOffset = pos.fAddressOffset.add(mergeLen);
@ -1081,7 +1122,7 @@ public class DisassemblyDocument extends REDDocument {
if (pos.fAddressLength.compareTo(BigInteger.ZERO) == 0) {
replace(pos, pos.length, null);
removeModelPosition(pos);
fInvalidAddressRanges.remove(pos);
removeInvalidAddressRange(pos);
pos = null;
}
if (DEBUG) checkConsistency();
@ -1101,7 +1142,7 @@ public class DisassemblyDocument extends REDDocument {
pos = insertAddressRange(pos, errorPos, errorLine, true);
addDisassemblyPosition(errorPos);
if (!errorPos.fValid) {
fInvalidAddressRanges.add(errorPos);
addInvalidAddressRange(errorPos);
}
length = length.subtract(posLen);
address = address.add(posLen);
@ -1110,15 +1151,12 @@ public class DisassemblyDocument extends REDDocument {
return pos;
}
/**
* @param pos
* @param address
* @param label
* @throws BadLocationException
* @throws BadPositionCategoryException
/* (non-Javadoc)
* @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)
*/
public AddressRangePosition insertLabel(AddressRangePosition pos, BigInteger address, String label, boolean showLabels)
throws BadLocationException {
assert isGuiThread();
String labelLine = showLabels ? label + ":\n" : ""; //$NON-NLS-1$ //$NON-NLS-2$
LabelPosition labelPos = getLabelPosition(address);
if (labelPos != null) {
@ -1158,7 +1196,7 @@ public class DisassemblyDocument extends REDDocument {
pos.length = sourceLines.length();
pos.fLine = line;
pos.fValid = true;
fInvalidSource.remove(pos);
removeInvalidSourcePosition(pos);
replace(pos, oldLength, sourceLines);
if (!endOfSource) {
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);
addSourcePosition(pos);
addModelPosition(pos);
fInvalidSource.add(pos);
addInvalidSourcePositions(pos);
} else {
//TLETODO need more checks for correct source pos
pos = oldPos;
@ -1188,6 +1226,7 @@ public class DisassemblyDocument extends REDDocument {
* @return
*/
public AddressRangePosition insertInvalidSource(AddressRangePosition pos, BigInteger address, SourceFileInfo fi, int lineNr) {
assert isGuiThread();
SourcePosition sourcePos = getSourcePosition(address);
if (sourcePos != null) {
return pos;
@ -1198,7 +1237,7 @@ public class DisassemblyDocument extends REDDocument {
pos = insertAddressRange(pos, sourcePos, sourceLine, true);
addSourcePosition(sourcePos);
assert !fInvalidSource.contains(sourcePos);
fInvalidSource.add(sourcePos);
addInvalidSourcePositions(sourcePos);
} catch (BadLocationException e) {
internalError(e);
}
@ -1213,6 +1252,7 @@ public class DisassemblyDocument extends REDDocument {
* @return
*/
public AddressRangePosition insertInvalidAddressRange(int offset, int replaceLength, BigInteger startAddress, BigInteger endAddress) {
assert isGuiThread();
String periods = "...\n"; //$NON-NLS-1$
AddressRangePosition newPos = new AddressRangePosition(offset, periods.length(), startAddress, endAddress
.subtract(startAddress), false);
@ -1220,7 +1260,7 @@ public class DisassemblyDocument extends REDDocument {
addModelPositionFirst(newPos);
replace(newPos, replaceLength, periods);
addDisassemblyPosition(newPos);
fInvalidAddressRanges.add(newPos);
addInvalidAddressRange(newPos);
} catch (BadLocationException e) {
internalError(e);
}
@ -1232,6 +1272,7 @@ public class DisassemblyDocument extends REDDocument {
}
public void deleteDisassemblyRange(BigInteger startAddress, BigInteger endAddress, boolean invalidate, boolean collapse) {
assert isGuiThread();
DocumentRewriteSession session = startRewriteSession(DocumentRewriteSessionType.STRICTLY_SEQUENTIAL);
try {
String replacement = invalidate ? "...\n" : null; //$NON-NLS-1$
@ -1267,7 +1308,7 @@ public class DisassemblyDocument extends REDDocument {
lastPos.fAddressLength = lastPos.fAddressLength.add(pos.fAddressLength);
toRemove.add(pos);
if (!pos.fValid) {
fInvalidAddressRanges.remove(pos);
removeInvalidAddressRange(pos);
}
pos = null;
if (posEndAddress.compareTo(endAddress) < 0) {
@ -1293,7 +1334,7 @@ public class DisassemblyDocument extends REDDocument {
if (pos != null) {
if (pos.fValid && invalidate) {
pos.fValid = false;
fInvalidAddressRanges.add(pos);
addInvalidAddressRange(pos);
}
lastPos = pos;
}
@ -1306,6 +1347,7 @@ public class DisassemblyDocument extends REDDocument {
}
public void invalidateSource() {
assert isGuiThread();
Iterator<Position> it;
try {
it = getPositionIterator(CATEGORY_SOURCE, 0);
@ -1317,11 +1359,33 @@ public class DisassemblyDocument extends REDDocument {
SourcePosition srcPos = (SourcePosition)it.next();
if (srcPos != null && srcPos.fValid) {
srcPos.fValid = false;
assert !getInvalidSource().contains(srcPos);
getInvalidSource().add(srcPos);
assert !fInvalidSource.contains(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) {
for (Iterator<SourceFileInfo> it = fFileInfoMap.values().iterator(); it.hasNext();) {
@ -1338,6 +1402,7 @@ public class DisassemblyDocument extends REDDocument {
* @throws BadLocationException
*/
public void deleteLineRange(int start, int end) throws BadLocationException {
assert isGuiThread();
if (start >= end) {
return;
}
@ -1365,9 +1430,9 @@ public class DisassemblyDocument extends REDDocument {
toRemove.add(p);
if (!p.fValid) {
if (p instanceof SourcePosition) {
getInvalidSource().remove(p);
removeInvalidSourcePosition((SourcePosition)p);
} else {
getInvalidAddressRanges().remove(p);
removeInvalidAddressRange(p);
}
}
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
* are made available under the terms of the Eclipse Public License v1.0
* 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 org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyPosition;
/**
* DisassemblyWithSourcePosition
*/
@ -42,5 +44,13 @@ public class DisassemblyWithSourcePosition extends DisassemblyPosition {
public int getLine() {
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
* are made available under the terms of the Eclipse Public License v1.0
* 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.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.DisassemblyPosition;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model.SourcePosition;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IFile;
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
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -11,7 +11,9 @@
package org.eclipse.cdt.dsf.internal.ui;
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.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
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$
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);
}
/*