1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 09:25:31 +02:00

Bug 325277 - [disassembly] add IInstruction#getSize() to fill single-instruction gaps, allow large pseudo-mnemonics

This commit is contained in:
Anton Leherbauer 2010-09-29 11:01:49 +00:00
parent 9883f18413
commit ef4a1226fe
6 changed files with 102 additions and 27 deletions

View file

@ -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;

View file

@ -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) {

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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.
* <p>
* Implementers should extend {@link AbstractInstruction} instead of
* implementing this interface directly.
* </p>
*
* @since 1.0
* @see IInstructionWithSize
*/
public interface IInstruction {

View file

@ -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.
* <p>
* Implementers must extend {@link AbstractInstruction} instead of
* implementing this interface directly.
* </p>
* @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 <code>null</code> if unknown
*/
Integer getSize();
}