From ef4a1226feb2243457622ba1b306bd766402fb12 Mon Sep 17 00:00:00 2001 From: Anton Leherbauer Date: Wed, 29 Sep 2010 11:01:49 +0000 Subject: [PATCH] Bug 325277 - [disassembly] add IInstruction#getSize() to fill single-instruction gaps, allow large pseudo-mnemonics --- .../service/command/output/MIInstruction.java | 6 +-- .../ui/disassembly/DisassemblyBackendDsf.java | 52 +++++++++++-------- .../model/DisassemblyDocument.java | 2 +- .../debug/service/AbstractInstruction.java | 27 ++++++++++ .../cdt/dsf/debug/service/IInstruction.java | 9 +++- .../debug/service/IInstructionWithSize.java | 33 ++++++++++++ 6 files changed, 102 insertions(+), 27 deletions(-) create mode 100644 dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/AbstractInstruction.java create mode 100644 dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IInstructionWithSize.java diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIInstruction.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIInstruction.java index 8504511be06..bbfc6563f51 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIInstruction.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIInstruction.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 QNX Software Systems and others. + * Copyright (c) 2000, 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 @@ -14,9 +14,9 @@ package org.eclipse.cdt.dsf.mi.service.command.output; import java.math.BigInteger; -import org.eclipse.cdt.dsf.debug.service.IInstruction; +import org.eclipse.cdt.dsf.debug.service.AbstractInstruction; -public class MIInstruction implements IInstruction { +public class MIInstruction extends AbstractInstruction { // The parsed information BigInteger address; diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyBackendDsf.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyBackendDsf.java index c24c8279643..94315e9f216 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyBackendDsf.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyBackendDsf.java @@ -40,6 +40,7 @@ import org.eclipse.cdt.dsf.debug.service.IFormattedValues; 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.IInstruction; +import org.eclipse.cdt.dsf.debug.service.IInstructionWithSize; import org.eclipse.cdt.dsf.debug.service.IMixedInstruction; import org.eclipse.cdt.dsf.debug.service.IRunControl; import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; @@ -613,12 +614,17 @@ public class DisassemblyBackendDsf implements IDisassemblyBackend, SessionEndedL } // determine instruction byte length BigInteger instrLength= null; - if (j < instructions.length - 1) { - instrLength= instructions[j+1].getAdress().subtract(instruction.getAdress()).abs(); - } - if (instrLength == null) { - // cannot determine length of last instruction - break; + if (instruction instanceof IInstructionWithSize + && ((IInstructionWithSize)instruction).getSize() != null) { + instrLength= new BigInteger(((IInstructionWithSize)instruction).getSize().toString()); + } else { + if (j < instructions.length - 1) { + instrLength= instructions[j+1].getAdress().subtract(instruction.getAdress()).abs(); + } + if (instrLength == null) { + // cannot determine length of last instruction + break; + } } final String opCode; // insert function name+offset instead of opcode bytes @@ -667,7 +673,6 @@ public class DisassemblyBackendDsf implements IDisassemblyBackend, SessionEndedL * @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 to avoid a retry @@ -730,26 +735,31 @@ public class DisassemblyBackendDsf implements IDisassemblyBackend, SessionEndedL } // 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(); + if (instruction instanceof IInstructionWithSize + && ((IInstructionWithSize)instruction).getSize() != null) { + instrLength= new BigInteger(((IInstructionWithSize)instruction).getSize().toString()); + } else { + 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; } - ++nextSrcLineIdx; } - if (nextSrcLineIdx >= mixedInstructions.length) { + if (instrLength == null) { + // cannot determine length of last instruction break; } } - 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) { diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/DisassemblyDocument.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/DisassemblyDocument.java index db40d874e36..b654581402a 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/DisassemblyDocument.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/model/DisassemblyDocument.java @@ -697,7 +697,7 @@ public class DisassemblyDocument extends REDDocument implements IDisassemblyDocu if (functionLength > fMaxFunctionLength) { fMaxFunctionLength = functionLength; } - if (fNumberOfInstructions < 100) { + if (fNumberOfInstructions < 100 && fMeanSizeOfInstructions < 16.0) { fMeanSizeOfInstructions = (fMeanSizeOfInstructions * fNumberOfInstructions + pos.fAddressLength.floatValue()) / (++fNumberOfInstructions); } } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/AbstractInstruction.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/AbstractInstruction.java new file mode 100644 index 00000000000..6adeec12c10 --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/AbstractInstruction.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.dsf.debug.service; + +/** + * Implementers of {@link IInstruction} should extend this abstract class + * instead of implementing the interface directly. + * + * @since 2.2 + */ +public abstract class AbstractInstruction implements IInstructionWithSize { + /* + * @see org.eclipse.cdt.dsf.debug.service.IInstructionWithSize#getSize() + */ + public Integer getSize() { + // unkown size + return null; + } +} diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IInstruction.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IInstruction.java index 38974f15712..9f831ff1101 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IInstruction.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IInstruction.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2009 Ericsson and others. + * Copyright (c) 2008, 2010 Ericsson 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 @@ -14,9 +14,14 @@ package org.eclipse.cdt.dsf.debug.service; import java.math.BigInteger; /** - * Represents an assembly instruction + * Represents an assembly instruction. + *

+ * Implementers should extend {@link AbstractInstruction} instead of + * implementing this interface directly. + *

* * @since 1.0 + * @see IInstructionWithSize */ public interface IInstruction { diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IInstructionWithSize.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IInstructionWithSize.java new file mode 100644 index 00000000000..01995a2c0f3 --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/IInstructionWithSize.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2010 Nokia, 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: + * Nokia + * Wind River Systems + *******************************************************************************/ +package org.eclipse.cdt.dsf.debug.service; + +import org.eclipse.cdt.dsf.debug.service.IInstruction; + +/** + * Extension interface for instructions knowing their size. + *

+ * Implementers must extend {@link AbstractInstruction} instead of + * implementing this interface directly. + *

+ * @since 2.2 + * @noimplement This interface is not intended to be implemented by clients. + * @noextend This interface is not intended to be extended by clients. + */ +public interface IInstructionWithSize extends IInstruction { + + /** + * @return size of the instruction in bytes or null if unknown + */ + Integer getSize(); + +}