/******************************************************************************* | |
* Copyright (c) 2011 Nokia 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 - Initial API and implementation | |
*******************************************************************************/ | |
package org.eclipse.cdt.debug.edc.debugger.tests; | |
import java.math.BigInteger; | |
import java.util.Map; | |
import java.util.concurrent.TimeUnit; | |
import org.eclipse.cdt.core.IAddress; | |
import org.eclipse.cdt.debug.edc.IAddressExpressionEvaluator; | |
import org.eclipse.cdt.debug.edc.disassembler.EDCInstruction; | |
import org.eclipse.cdt.debug.edc.disassembler.IDisassembler; | |
import org.eclipse.cdt.debug.edc.internal.EDCDebugger; | |
import org.eclipse.cdt.debug.edc.internal.arm.ARMDisassembly; | |
import org.eclipse.cdt.debug.edc.internal.arm.RangeAndMode; | |
import org.eclipse.cdt.debug.edc.internal.arm.TargetEnvironmentARM; | |
import org.eclipse.cdt.debug.edc.internal.arm.disassembler.DisassemblerARM; | |
import org.eclipse.cdt.debug.edc.services.EDCServicesTracker; | |
import org.eclipse.cdt.debug.edc.services.ITargetEnvironment; | |
import org.eclipse.cdt.debug.edc.symbols.TypeUtils; | |
import org.eclipse.cdt.debug.edc.tests.EDCTestPlugin; | |
import org.eclipse.cdt.debug.edc.tests.TestUtils; | |
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; | |
import org.eclipse.cdt.dsf.concurrent.Query; | |
import org.eclipse.cdt.dsf.datamodel.DMContexts; | |
import org.eclipse.cdt.dsf.debug.service.IDisassembly; | |
import org.eclipse.cdt.dsf.debug.service.IInstruction; | |
import org.eclipse.cdt.dsf.debug.service.IRegisters; | |
import org.eclipse.cdt.dsf.service.DsfServicesTracker; | |
import org.eclipse.cdt.utils.Addr32; | |
import org.eclipse.core.runtime.CoreException; | |
import org.eclipse.core.runtime.IStatus; | |
import org.eclipse.core.runtime.Status; | |
import org.eclipse.ui.IViewPart; | |
import org.junit.AfterClass; | |
import org.junit.Assert; | |
import org.junit.BeforeClass; | |
import org.junit.Test; | |
/** | |
* use the available BlackFlagRVCT snapshot used for register frame tests | |
* to test the ARMDisassembly code | |
*/ | |
public class DisassemblyViewARMBlackFlagRVCT { | |
final static String DSF_DISASM_VIEW = "org.eclipse.cdt.dsf.debug.ui.disassembly.view"; | |
final static byte[] sARMBkptInstr = new byte[] { 0x01, 0, (byte) 0x9f, (byte) 0xef }; | |
final static byte[] sThumbBkptInstr = new byte[] { 0, (byte) 0xdf, (byte) 0xef }; | |
private static class ARMBlackFlagRVCTSnapshotAlbum extends SimpleDebuggerTest { | |
/* (non-Javadoc) | |
* @see org.eclipse.cdt.debug.edc.debugger.tests.SimpleDebuggerTest#getRequiredLaunchConfigurationType() | |
*/ | |
@Override | |
protected String getRequiredLaunchConfigurationType() { | |
return "com.nokia.cdt.debug.launch.systemTRKLaunch"; | |
} | |
@Override | |
public String getAlbumName() { | |
return "RegisterFrameTestsBlackFlagRVCT.dsa"; | |
} | |
static ARMBlackFlagRVCTSnapshotAlbum openAlbum() { | |
return new ARMBlackFlagRVCTSnapshotAlbum(); | |
} | |
} | |
private static ARMBlackFlagRVCTSnapshotAlbum armAlbum; | |
private static ARMDisassembly armDisasm; | |
private static IDisassembly.IDisassemblyDMContext disassemblyDMC; | |
private static IViewPart disasmView; | |
@BeforeClass | |
public static void establishARMDisassemblySnapshotSession() { | |
try { | |
TestUtils.showDebugPerspective(); | |
armAlbum = ARMBlackFlagRVCTSnapshotAlbum.openAlbum(); | |
armAlbum.launchAndWaitForSuspendedContext(); | |
if (armAlbum.launch == null) return; | |
EDCServicesTracker edcTracker | |
= new EDCServicesTracker(EDCDebugger.getBundleContext(), armAlbum.session.getId()); | |
Assert.assertNotNull(edcTracker); | |
armDisasm = edcTracker.getService(ARMDisassembly.class); | |
Assert.assertNotNull(armDisasm); | |
disassemblyDMC | |
= DMContexts.getAncestorOfType(armAlbum.threadDMC, IDisassembly.IDisassemblyDMContext.class); | |
disasmView = TestUtils.showView(DSF_DISASM_VIEW); | |
} catch (Exception e) { | |
Assert.fail(e.getLocalizedMessage()); | |
} | |
} | |
@AfterClass | |
public static void shutdown() throws Exception { | |
TestUtils.hideView(disasmView); | |
disassemblyDMC = null; | |
armDisasm = null; | |
armAlbum.shutdown(); | |
armAlbum = null; | |
} | |
@Test | |
public void testARMDisassembly() throws Exception { | |
armAlbum.openSnapshotAndWaitForSuspendedContext(0); | |
Thread.sleep(2500); // wait a little to allow the view to populate and do work | |
} | |
@Test | |
public void testARMDisassemblyGetInstructionsBigInteger() throws Exception { | |
// Use a Query to synchronize the downstream calls | |
Query<IInstruction[]> query = new Query<IInstruction[]>() { | |
@Override | |
protected void execute(final DataRequestMonitor<IInstruction[]> drm) { | |
BigInteger start = new BigInteger("78865830", 16), end = new BigInteger("78865864", 16); | |
armDisasm.getInstructions(disassemblyDMC, start, end, drm); | |
} | |
}; | |
armAlbum.session.getExecutor().execute(query); | |
IInstruction[] instrs = query.get(1, TimeUnit.SECONDS); | |
Assert.assertTrue("Query returned check", query.isDone()); | |
Assert.assertNotNull("Returned instructions null check", instrs); | |
Assert.assertEquals("Returned instructions array check", 22, instrs.length); | |
Assert.assertTrue("EDC Instruction check", instrs[0] instanceof EDCInstruction); | |
EDCInstruction edcInstr = (EDCInstruction)instrs[0]; | |
Assert.assertEquals("Full instruction check", "add\tr2,sp,#0x38", edcInstr.getInstruction()); | |
Assert.assertEquals("Address check", "2022070320", edcInstr.getAdress().toString()); | |
Assert.assertEquals("Args check", "r2,sp,#0x38", edcInstr.getArgs()); | |
Assert.assertNull("Function name check (null for this context)", edcInstr.getFunctionName()); | |
Assert.assertEquals("Offset check", 0, edcInstr.getOffset()); | |
// TODO need to change when EDCInstruction#opcode is implemented | |
Assert.assertNull("Opcode check (always null right now)", edcInstr.getOpcode()); | |
Assert.assertEquals("Size check", 2, (int)edcInstr.getSize()); | |
Assert.assertEquals("(length: 2) 78865830: add r2,sp,#0x38", edcInstr.toString()); | |
} | |
@Test | |
public void testInternalRangeAndMode() { | |
RangeAndMode ram = new RangeAndMode(new Addr32("123456"), null, false, false); | |
Assert.assertFalse("RangeAndMode.isThumbMode()", ram.isThumbMode()); | |
Assert.assertFalse("RangeAndMode.hasSymbols()", ram.hasSymbols()); | |
Assert.assertEquals("RangeAndMode.getStartAddress()", "123456", ram.getStartAddress().toString()); | |
Assert.assertNull("RangeAndMode.getEndAddress()", ram.getEndAddress()); | |
Assert.assertEquals("start = 0x0001e240, end = null, no symbols", ram.toString()); | |
ram.setThumbMode(true); | |
Assert.assertTrue("post RangeAndMode.setThumbMode()", ram.isThumbMode()); | |
ram.setHasSymbols(true); | |
Assert.assertTrue("post RangeAndMode.setHasSymbols()", ram.hasSymbols()); | |
ram.setStartAddress(new Addr32("123462")); | |
Assert.assertEquals("post RangeAndMode.setStartAddress()", "123462", ram.getStartAddress().toString()); | |
ram.setEndAddress(new Addr32("123478")); | |
Assert.assertEquals("post RangeAndMode.setEndAddress()", "123478", ram.getEndAddress().toString()); | |
Assert.assertEquals("start = 0x0001e246, end = 0x0001e256, thumb, symbols", ram.toString()); | |
} | |
@Test | |
public void testInternalTargetEnvironmentARM() throws Exception { | |
armAlbum.openSnapshotAndWaitForSuspendedContext(4); | |
final TargetEnvironmentARM env | |
= (TargetEnvironmentARM)armDisasm.getTargetEnvironmentService(); | |
Assert.assertNotNull(env); | |
Query<IAddress> query = new Query<IAddress>() { | |
@Override | |
protected void execute(final DataRequestMonitor<IAddress> drm) { | |
IAddressExpressionEvaluator evaluator | |
= env.getAddressExpressionEvaluator(); | |
DsfServicesTracker servicesTracker | |
= TestUtils.getDsfServicesTracker(armAlbum.session); | |
IRegisters regService = servicesTracker.getService(IRegisters.class); | |
try { | |
drm.setData(evaluator.evaluate(armAlbum.threadDMC, "lr", regService, null)); | |
} catch (CoreException e) { | |
drm.setStatus(new Status(IStatus.ERROR, EDCTestPlugin.PLUGIN_ID, | |
e.getLocalizedMessage())); | |
} | |
drm.done(); | |
} | |
}; | |
armAlbum.session.getExecutor().execute(query); | |
IAddress lrAddr = query.get(1, TimeUnit.SECONDS); | |
Assert.assertTrue(query.isDone()); | |
Assert.assertNotNull(lrAddr); | |
Assert.assertEquals("0x7886583d", lrAddr.toHexAddressString()); | |
} | |
@Test | |
public void testInternalTargetEnvironmentARMgetBasicTypeSizes() throws Exception { | |
armAlbum.openSnapshotAndWaitForSuspendedContext(4); | |
final TargetEnvironmentARM env | |
= (TargetEnvironmentARM)armDisasm.getTargetEnvironmentService(); | |
Assert.assertNotNull(env); | |
Map<Integer, Integer> basicTypeSizes = env.getBasicTypeSizes(); | |
Assert.assertEquals("Basic Type Size Test (long long)", | |
8, (int)basicTypeSizes.get(TypeUtils.BASIC_TYPE_LONG_LONG)); | |
} | |
@Test | |
public void testInternalTargetEnvironmentARMgetBreapointInstruction() throws Exception { | |
armAlbum.openSnapshotAndWaitForSuspendedContext(4); | |
final TargetEnvironmentARM env | |
= (TargetEnvironmentARM)armDisasm.getTargetEnvironmentService(); | |
Assert.assertNotNull(env); | |
byte[] bkptInst = env.getBreakpointInstruction(disassemblyDMC, new Addr32(0x788656e4)); | |
Assert.assertArrayEquals("Breakpoint Instruction Test", sThumbBkptInstr, bkptInst); | |
} | |
@Test | |
public void testInternalTargetEnvironmentARMgetDisassembler() { | |
TargetEnvironmentARM env | |
= (TargetEnvironmentARM)armDisasm.getTargetEnvironmentService(); | |
Assert.assertNotNull(env); | |
IDisassembler disassembler = env.getDisassembler(); | |
Assert.assertTrue("instanceof check", disassembler instanceof DisassemblerARM); | |
} | |
@Test | |
public void testInternalTargetEnvironmentARMgetEnumSize() { | |
TargetEnvironmentARM env | |
= (TargetEnvironmentARM)armDisasm.getTargetEnvironmentService(); | |
Assert.assertNotNull(env); | |
int enumSize = env.getEnumSize(); | |
Assert.assertEquals("Enum Size Test", 4, enumSize); | |
} | |
@Test | |
public void testInternalTargetEnvironmentARMgetLongestInstructionLength() { | |
TargetEnvironmentARM env | |
= (TargetEnvironmentARM)armDisasm.getTargetEnvironmentService(); | |
Assert.assertNotNull(env); | |
int longestInstLength = env.getLongestInstructionLength(); | |
Assert.assertEquals("Longest Instruction Length Test", 4, longestInstLength); | |
} | |
@Test | |
public void testInternalTargetEnvironmentARMgetMemoryCacheMinimumBlockSize() { | |
TargetEnvironmentARM env | |
= (TargetEnvironmentARM)armDisasm.getTargetEnvironmentService(); | |
Assert.assertNotNull(env); | |
int memoryCacheMinimumBlockSize = env.getMemoryCacheMinimumBlockSize(); | |
Assert.assertEquals("Memory Cache Minimum Block Size Test", 64, memoryCacheMinimumBlockSize); | |
} | |
@Test | |
public void testInternalTargetEnvironmentARMgetOS() { | |
TargetEnvironmentARM env | |
= (TargetEnvironmentARM)armDisasm.getTargetEnvironmentService(); | |
Assert.assertNotNull(env); | |
String os = env.getOS(); | |
Assert.assertEquals("OS Test", ITargetEnvironment.OS_UNKNOWN, os); | |
} | |
@Test | |
public void testInternalTargetEnvironmentARMgetPCRegisterID() { | |
TargetEnvironmentARM env | |
= (TargetEnvironmentARM)armDisasm.getTargetEnvironmentService(); | |
Assert.assertNotNull(env); | |
String pcRegID = env.getPCRegisterID(); | |
Assert.assertEquals("PC Register ID Test", "PC", pcRegID); | |
} | |
@Test | |
public void testInternalTargetEnvironmentARMgetPointerSize() { | |
TargetEnvironmentARM env | |
= (TargetEnvironmentARM)armDisasm.getTargetEnvironmentService(); | |
Assert.assertNotNull(env); | |
int pointerSize = env.getPointerSize(); | |
Assert.assertEquals("Pointer Size Test", 4, pointerSize); | |
} | |
@Test | |
public void coverageInternalTargetEnvironmentARMgetProperty() { | |
TargetEnvironmentARM env | |
= (TargetEnvironmentARM)armDisasm.getTargetEnvironmentService(); | |
Assert.assertNotNull(env); | |
Assert.assertNull("Property Test (no properties yet supported)", env.getProperty("x")); | |
} | |
@Test | |
public void testInternalTargetEnvironmentARMisCharSigned() { | |
TargetEnvironmentARM env | |
= (TargetEnvironmentARM)armDisasm.getTargetEnvironmentService(); | |
Assert.assertNotNull(env); | |
boolean isCharSigned = env.isCharSigned(); | |
Assert.assertFalse("Char Signed Test", isCharSigned); | |
} | |
@Test | |
public void testInternalTargetEnvironmentARMisLittleEndian() throws Exception { | |
armAlbum.openSnapshotAndWaitForSuspendedContext(4); | |
final TargetEnvironmentARM env | |
= (TargetEnvironmentARM)armDisasm.getTargetEnvironmentService(); | |
Assert.assertNotNull(env); | |
boolean isLittleEndian = env.isLittleEndian(disassemblyDMC); | |
Assert.assertTrue("Little Endian Test", isLittleEndian); | |
} | |
@Test | |
public void testInternalTargetEnvironmentARMisThumbMode() throws Exception { | |
armAlbum.openSnapshotAndWaitForSuspendedContext(4); | |
final TargetEnvironmentARM env | |
= (TargetEnvironmentARM)armDisasm.getTargetEnvironmentService(); | |
Assert.assertNotNull(env); | |
boolean isThumbMode = env.isThumbMode(disassemblyDMC, new Addr32(0x788656e4), false); | |
Assert.assertTrue("Thumb Mode Test", isThumbMode); | |
} | |
} |