From eeba5abcbaffc6d555a4b937948ae5569bc4138d Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Mon, 18 Aug 2008 16:59:11 +0000 Subject: [PATCH] [244435] - Added registers to the PDA debugger exmple. --- .../dd/examples/pdavm/PDAVirtualMachine.java | 353 ++++- .../pdavm/tests/vmtest10.pda | 38 + .../pdavm/tests/vmtest_children.pda | 8 + .../samples/registers.pda | 72 + .../samples/structures.pda | 15 + .../examples/pda/service/PDAExpressions.java | 235 ++- .../dd/examples/pda/service/PDARegisters.java | 1273 +++++------------ .../dd/examples/pda/service/PDAStack.java | 11 +- .../pda/service/commands/PDABitField.java | 44 + .../service/commands/PDAChildrenCommand.java | 38 + .../pda/service/commands/PDADataCommand.java | 6 +- .../service/commands/PDAGroupsCommand.java | 35 + ...aCommandResult.java => PDAListResult.java} | 6 +- .../pda/service/commands/PDARegister.java | 45 + .../service/commands/PDARegistersCommand.java | 35 + .../commands/PDARegistersCommandResult.java | 41 + .../dd/tests/pda/service/command/Test10.java | 82 ++ 17 files changed, 1344 insertions(+), 993 deletions(-) create mode 100644 plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest10.pda create mode 100644 plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest_children.pda create mode 100644 plugins/org.eclipse.dd.examples.pda/samples/registers.pda create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDABitField.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAChildrenCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAGroupsCommand.java rename plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/{PDADataCommandResult.java => PDAListResult.java} (89%) create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDARegister.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDARegistersCommand.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDARegistersCommandResult.java create mode 100644 plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test10.java diff --git a/plugins/org.eclipse.dd.examples.pda/pdavm/src/org/eclipse/dd/examples/pdavm/PDAVirtualMachine.java b/plugins/org.eclipse.dd.examples.pda/pdavm/src/org/eclipse/dd/examples/pdavm/PDAVirtualMachine.java index c404c054b44..e1ca15c6cdd 100644 --- a/plugins/org.eclipse.dd.examples.pda/pdavm/src/org/eclipse/dd/examples/pdavm/PDAVirtualMachine.java +++ b/plugins/org.eclipse.dd.examples.pda/pdavm/src/org/eclipse/dd/examples/pdavm/PDAVirtualMachine.java @@ -19,12 +19,14 @@ import java.io.PrintStream; import java.io.StringWriter; import java.net.ServerSocket; import java.net.Socket; +import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.StringTokenizer; +import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -34,16 +36,41 @@ import java.util.regex.Pattern; @SuppressWarnings("serial") public class PDAVirtualMachine { - class Stack extends LinkedList { + static class Stack extends LinkedList { + @Override public Object pop() { return isEmpty() ? 0 : remove(size() - 1); } + @Override public void push(Object value) { add(value); } } + + static class Register { + Register(String name) { + fName = name; + } + String fName; + String fGroup = ""; + boolean fIsWriteable = true; + Map fBitFields = new LinkedHashMap(0); + int fValue; + } + static class BitField { + BitField(String name) { + fName = name; + } + String fName; + int fBitOffset; + int fBitCount; + Map fMnemonics = new LinkedHashMap(0); + } + + Map fRegisters = new LinkedHashMap(0); + class Args { final String[] fArgs; @@ -69,6 +96,15 @@ public class PDAVirtualMachine { return 0; } + boolean getNextBooleanArg() { + String arg = getNextStringArg(); + try { + return Boolean.parseBoolean(arg); + } catch (NumberFormatException e) { + } + return false; + } + Object getNextIntOrStringArg() { String arg = getNextStringArg(); try { @@ -133,7 +169,7 @@ public class PDAVirtualMachine { int fNextThreadId = 1; - private boolean fStarted = true; + boolean fStarted = true; /** * The code is stored as an array of strings, each line of the source file * being one entry in the array. @@ -144,7 +180,9 @@ public class PDAVirtualMachine { final Map fLabels; /** Each stack frame is a mapping of variable names to values. */ - class Frame extends LinkedHashMap { + class Frame { + final Map fLocalVariables = new LinkedHashMap(); + /** * The name of the function in this frame */ @@ -160,8 +198,63 @@ public class PDAVirtualMachine { fFunction = function; fPC = pc; } + + void set(String name, Object value) { + if (name.startsWith("$")) { + setRegisterValue(name, value); + } else { + fLocalVariables.put(name, value); + } + } + + Object get(String name) { + if (name.startsWith("$")) { + return getRegisterValue(name); + } else { + return fLocalVariables.get(name); + } + } } + void setRegisterValue(String name, Object value) { + Register reg = fRegisters.get(getRegisterPartOfName(name)); + if (reg == null) return; + String bitFieldName = getBitFieldPartOfName(name); + if (bitFieldName != null) { + BitField bitField = reg.fBitFields.get(bitFieldName); + if (bitField == null) return; + Integer intValue = null; + if (value instanceof Integer) { + intValue = (Integer)value; + } else if (value instanceof String) { + intValue = bitField.fMnemonics.get(value); + } + if (intValue != null) { + int bitFieldMask = 2^(bitField.fBitCount - 1); + int registerMask = ~(bitFieldMask << bitField.fBitOffset); + int bitFieldValue = intValue & bitFieldMask; + reg.fValue = (reg.fValue & registerMask) | (bitFieldValue << bitField.fBitOffset); + } + } else if (value instanceof Integer) { + reg.fValue = ((Integer)value).intValue(); + } + } + + Object getRegisterValue(String name) { + Register reg = fRegisters.get(getRegisterPartOfName(name)); + if (reg == null) return null; + String bitFieldName = getBitFieldPartOfName(name); + if (bitFieldName != null) { + BitField bitField = reg.fBitFields.get(bitFieldName); + if (bitField == null) return null; + int bitFieldMask = 2^(bitField.fBitCount - 1); + int registerMask = bitFieldMask << bitField.fBitOffset; + return (reg.fValue & registerMask) >> bitField.fBitOffset; + } else { + return reg.fValue; + } + } + /** * Breakpoints are stored per each each line of code. The boolean indicates * whether the whole VM should suspend or just the triggering thread. @@ -385,7 +478,7 @@ public class PDAVirtualMachine { String instruction = thread.fThreadCode[thread.fCurrentFrame.fPC]; thread.fCurrentFrame.fPC++; doOneInstruction(thread, instruction); - if (thread.fCurrentFrame.fPC > thread.fThreadCode.length) { + if (thread.fCurrentFrame.fPC >= thread.fThreadCode.length) { // Thread reached end of code, exit from the thread. thread.fRun = false; } else if (thread.fStepReturn) { @@ -446,6 +539,7 @@ public class PDAVirtualMachine { else if (op.equals("branch_not_zero")) iBranchNotZero(thread, args); else if (op.equals("call")) iCall(thread, args); else if (op.equals("dec")) iDec(thread, args); + else if (op.equals("def")) iDef(thread, args); else if (op.equals("dup")) iDup(thread, args); else if (op.equals("exec")) iExec(thread, args); else if (op.equals("halt")) iHalt(thread, args); @@ -571,15 +665,18 @@ public class PDAVirtualMachine { } Args args = new Args(tokens.toArray(new String[tokens.size()])); - if ("clear".equals(command)) debugClearBreakpoint(args); + if ("children".equals(command)) debugChildren(args); + else if ("clear".equals(command)) debugClearBreakpoint(args); else if ("data".equals(command)) debugData(args); else if ("drop".equals(command)) debugDropFrame(args); else if ("eval".equals(command)) debugEval(args); else if ("eventstop".equals(command)) debugEventStop(args); else if ("exit".equals(command)) debugExit(); else if ("frame".equals(command)) debugFrame(args); + else if ("groups".equals(command)) debugGroups(args); else if ("popdata".equals(command)) debugPop(args); else if ("pushdata".equals(command)) debugPush(args); + else if ("registers".equals(command)) debugRegisters(args); else if ("resume".equals(command)) debugResume(args); else if ("set".equals(command)) debugSetBreakpoint(args); else if ("setdata".equals(command)) debugSetData(args); @@ -600,6 +697,37 @@ public class PDAVirtualMachine { } } + void debugChildren(Args args) { + PDAThread thread = args.getThreadArg(); + if (thread == null) { + sendCommandResponse("error: invalid thread\n"); + return; + } + + int sfnumber = args.getNextIntArg(); + String var = args.getNextStringArg(); + + Frame frame = sfnumber >= thread.fFrames.size() + ? thread.fCurrentFrame : thread.fFrames.get(sfnumber); + + String varDot = var + "."; + List children = new ArrayList(); + for (String localVar : frame.fLocalVariables.keySet()) { + if (localVar.startsWith(varDot) && localVar.indexOf('.', varDot.length() + 1) == -1) { + children.add(localVar); + } + } + + StringBuffer result = new StringBuffer(); + for (String child : children) { + result.append(child); + result.append('|'); + } + result.append('\n'); + + sendCommandResponse(result.toString()); + } + void debugClearBreakpoint(Args args) { int line = args.getNextIntArg(); @@ -609,6 +737,43 @@ public class PDAVirtualMachine { private static Pattern fPackPattern = Pattern.compile("%([a-fA-F0-9][a-fA-F0-9])"); + void debugData(Args args) { + PDAThread thread = args.getThreadArg(); + if (thread == null) { + sendCommandResponse("error: invalid thread\n"); + return; + } + + StringBuffer result = new StringBuffer(); + for (Object val : thread.fStack) { + result.append(val); + result.append('|'); + } + result.append('\n'); + sendCommandResponse(result.toString()); + } + + void debugDropFrame(Args args) { + PDAThread thread = args.getThreadArg(); + if (thread == null) { + sendCommandResponse("error: invalid thread\n"); + return; + } + + if (!thread.fFrames.isEmpty()) { + thread.fCurrentFrame = thread.fFrames.remove(thread.fFrames.size() - 1); + } + thread.fCurrentFrame.fPC--; + sendCommandResponse("ok\n"); + if (fSuspendVM != null) { + sendDebugEvent("vmresumed drop", false); + sendDebugEvent("vmsuspended " + thread.fID + " drop", false); + } else { + sendDebugEvent("resumed " + thread.fID + " drop", false); + sendDebugEvent("suspended " + thread.fID + " drop", false); + } + } + void debugEval(Args args) { if (fSuspendVM != null) { sendCommandResponse("error: cannot evaluate while vm is suspended\n"); @@ -665,43 +830,6 @@ public class PDAVirtualMachine { sendDebugEvent("resumed " + thread.fID + " eval", false); } - void debugData(Args args) { - PDAThread thread = args.getThreadArg(); - if (thread == null) { - sendCommandResponse("error: invalid thread\n"); - return; - } - - StringBuffer result = new StringBuffer(); - for (Object val : thread.fStack) { - result.append(val); - result.append('|'); - } - result.append('\n'); - sendCommandResponse(result.toString()); - } - - void debugDropFrame(Args args) { - PDAThread thread = args.getThreadArg(); - if (thread == null) { - sendCommandResponse("error: invalid thread\n"); - return; - } - - if (!thread.fFrames.isEmpty()) { - thread.fCurrentFrame = thread.fFrames.remove(thread.fFrames.size() - 1); - } - thread.fCurrentFrame.fPC--; - sendCommandResponse("ok\n"); - if (fSuspendVM != null) { - sendDebugEvent("vmresumed drop", false); - sendDebugEvent("vmsuspended " + thread.fID + " drop", false); - } else { - sendDebugEvent("resumed " + thread.fID + " drop", false); - sendDebugEvent("suspended " + thread.fID + " drop", false); - } - } - void debugEventStop(Args args) { String event = args.getNextStringArg(); int stop = args.getNextIntArg(); @@ -732,6 +860,20 @@ public class PDAVirtualMachine { sendCommandResponse(printFrame(frame) + "\n"); } + void debugGroups(Args args) { + TreeSet groups = new TreeSet(); + for (Register reg : fRegisters.values()) { + groups.add(reg.fGroup); + } + StringBuffer response = new StringBuffer(); + for (String group : groups) { + response.append(group); + response.append('|'); + } + response.append('\n'); + sendCommandResponse(response.toString()); + } + void debugPop(Args args) { PDAThread thread = args.getThreadArg(); if (thread == null) { @@ -755,6 +897,38 @@ public class PDAVirtualMachine { sendCommandResponse("ok\n"); } + void debugRegisters(Args args) { + String group = args.getNextStringArg(); + + StringBuffer response = new StringBuffer(); + for (Register reg : fRegisters.values()) { + if (group.equals(reg.fGroup)) { + response.append(reg.fName); + response.append(' '); + response.append(reg.fIsWriteable); + for (BitField bitField : reg.fBitFields.values()) { + response.append('|'); + response.append(bitField.fName); + response.append(' '); + response.append(bitField.fBitOffset); + response.append(' '); + response.append(bitField.fBitCount); + response.append(' '); + for (Map.Entry mnemonicEntry : bitField.fMnemonics.entrySet()) { + response.append(mnemonicEntry.getKey()); + response.append(' '); + response.append(mnemonicEntry.getValue()); + response.append(' '); + } + } + + response.append('#'); + } + } + response.append('\n'); + sendCommandResponse(response.toString()); + } + void debugResume(Args args) { PDAThread thread = args.getThreadArg(); if (thread == null) { @@ -814,9 +988,9 @@ public class PDAVirtualMachine { Object val = args.getNextIntOrStringArg(); if (sfnumber >= thread.fFrames.size()) { - thread.fCurrentFrame.put(var, val); + thread.fCurrentFrame.set(var, val); } else { - thread.fFrames.get(sfnumber).put(var, val); + thread.fFrames.get(sfnumber).set(var, val); } sendCommandResponse("ok\n"); } @@ -859,9 +1033,11 @@ public class PDAVirtualMachine { buf.append(frame.fPC); buf.append('|'); buf.append(frame.fFunction); - for (String var : frame.keySet()) { - buf.append('|'); - buf.append(var); + for (String var : frame.fLocalVariables.keySet()) { + if (var.indexOf('.') == -1) { + buf.append('|'); + buf.append(var); + } } return buf.toString(); } @@ -1062,6 +1238,52 @@ public class PDAVirtualMachine { thread.fStack.push(val); } + void iDef(PDAThread thread, Args args) { + String type = args.getNextStringArg(); + + String name = args.getNextStringArg(); + String regName = getRegisterPartOfName(name); + String bitFieldName = getBitFieldPartOfName(name); + + if ("register".equals(type)) { + Register reg = new Register(regName); + reg.fGroup = args.getNextStringArg(); + fRegisters.put(regName, reg); + reg.fIsWriteable = args.getNextBooleanArg(); + } else if ("bitfield".equals(type)) { + Register reg = fRegisters.get(regName); + if (reg == null) return; + BitField bitField = new BitField(bitFieldName); + bitField.fBitOffset = args.getNextIntArg(); + bitField.fBitCount = args.getNextIntArg(); + reg.fBitFields.put(bitFieldName, bitField); + } else if ("mnemonic".equals(type)) { + Register reg = fRegisters.get(regName); + if (reg == null) return; + BitField bitField = reg.fBitFields.get(bitFieldName); + if (bitField == null) return; + bitField.fMnemonics.put(args.getNextStringArg(), args.getNextIntArg()); + } + sendDebugEvent("registers", false); + } + + private String getRegisterPartOfName(String name) { + if (name.startsWith("$")) { + int end = name.indexOf('.'); + end = end != -1 ? end : name.length(); + return name.substring(1, end); + } + return null; + } + + private String getBitFieldPartOfName(String name) { + int start = name.indexOf('.'); + if (name.startsWith("$") && start != -1) { + return name.substring(start + 1, name.length()); + } + return null; + } + void iDup(PDAThread thread, Args args) { Object val = thread.fStack.pop(); thread.fStack.push(val); @@ -1095,7 +1317,7 @@ public class PDAVirtualMachine { String arg = args.getNextStringArg(); if (arg.startsWith("$")) { String var = arg.substring(1); - thread.fCurrentFrame.put(var, thread.fStack.pop()); + thread.fCurrentFrame.set(var, thread.fStack.pop()); String key = thread.fCurrentFrame.fFunction + "::" + var; if (fWatchpoints.containsKey(key) && (fWatchpoints.get(key) & 2) != 0) { fSuspendVM = thread.fID + " watch write " + key; @@ -1107,21 +1329,26 @@ public class PDAVirtualMachine { void iPush(PDAThread thread, Args args) { String arg = args.getNextStringArg(); - if (arg.startsWith("$")) { - String var = arg.substring(1); - Object val = thread.fCurrentFrame.containsKey(var) ? thread.fCurrentFrame.get(var) : ""; - thread.fStack.push(val); - String key = thread.fCurrentFrame.fFunction + "::" + var; - if (fWatchpoints.containsKey(key) && (fWatchpoints.get(key) & 1) != 0) { - fSuspendVM = thread.fID + " watch read " + key; + while (arg.length() != 0) { + if (arg.startsWith("$")) { + String var = arg.substring(1); + Object val = thread.fCurrentFrame.get(var); + if (val == null) val = ""; + thread.fStack.push(val); + String key = thread.fCurrentFrame.fFunction + "::" + var; + if (fWatchpoints.containsKey(key) && (fWatchpoints.get(key) & 1) != 0) { + fSuspendVM = thread.fID + " watch read " + key; + } + } else { + Object val = arg; + try { + val = Integer.parseInt(arg); + } catch (NumberFormatException e) { + } + thread.fStack.push(val); } - } else { - Object val = arg; - try { - val = Integer.parseInt(arg); - } catch (NumberFormatException e) { - } - thread.fStack.push(val); + + arg = args.getNextStringArg(); } } @@ -1137,7 +1364,7 @@ public class PDAVirtualMachine { void iVar(PDAThread thread, Args args) { String var = args.getNextStringArg(); - thread.fCurrentFrame.put(var, 0); + thread.fCurrentFrame.set(var, 0); } void iInternalEndEval(PDAThread thread, Args args) { diff --git a/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest10.pda b/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest10.pda new file mode 100644 index 00000000000..837277f5ff3 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest10.pda @@ -0,0 +1,38 @@ +def register $reg1 group1 true +def register $reg2 group1 false +def register $reg3 group2 true +def bitfield $reg1.field1 0 2 +def bitfield $reg1.field2 2 2 +def mnemonic $reg1.field2 zero 0 +def mnemonic $reg1.field2 one 1 +def mnemonic $reg1.field2 two 2 +def mnemonic $reg1.field2 three 3 +push 1 +pop $$reg1 +push $$reg1 +output +push 2 +pop $$reg1.field1 +push $$reg1.field1 +output +push 4 +pop $$reg1.field1 +push $$reg1.field1 +output +push 1 +pop $$reg1.field2 +push $$reg1 +output +push zero +pop $$reg1.field2 +push $$reg1.field2 +output +push $$reg1 +output +push 2 +pop $$reg1.field2 +push $$reg1.field2 +output +push $$reg1 +output +halt \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest_children.pda b/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest_children.pda new file mode 100644 index 00000000000..b0bbd163d7d --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest_children.pda @@ -0,0 +1,8 @@ +var a +var a.b +var a.c +push 1 +pop $a.b +push $a.b +output +halt diff --git a/plugins/org.eclipse.dd.examples.pda/samples/registers.pda b/plugins/org.eclipse.dd.examples.pda/samples/registers.pda new file mode 100644 index 00000000000..97fd8d4094d --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/samples/registers.pda @@ -0,0 +1,72 @@ +def register $pc General true +def register $sp General true +def register $status General true +def bitfield $status.BITS_00_07 0 8 +def bitfield $status.BITS_08_15 8 8 +def bitfield $status.BITS_16_23 16 8 +def bitfield $status.BITS_24_31 24 8 +def mnemonic $status.BITS_24_31 three 3 +def mnemonic $status.BITS_24_31 twelve 12 +def mnemonic $status.BITS_24_31 fourty_eight 48 +def mnemonic $status.BITS_24_31 one_nighty_two 192 +def register $stackdepth General true +def register $stack[0] General true +def register $stack[1] General true +def register $stack[2] General true +def register $stack[3] General true +def register $stack[4] General true +push 103 +pop $$pc +push 306 +push 2 +pop $$sp +push 400 +pop $$status +push 5 +pop $$stackdepth +push 12 +pop $$stack[0] +push 45 +pop $$stack[1] +push 146 +pop $$stack[2] +push 215 +pop $$stack[3] +push 251 +pop $$stack[4] +push 306 +pop $$stack[5] +def register $total-instructions Analysis false +def register $add-instructions Analysis false +def register $call-instructions Analysis false +def register $dec-instructions Analysis false +def register $dup-instructions Analysis false +def register $halt-instructions Analysis false +def register $output-instructions Analysis false +def register $pop-instructions Analysis false +def register $push-instructions Analysis false +def register $return-instructions Analysis false +def register $var-instructions Analysis false +push 1046 +pop $$total-instructions +push 12 +pop $$add-instructions +push 24 +pop $$call-instructions +push 36 +pop $$dec-instructions +push 50 +pop $$dup-instructions +push 62 +pop $$halt-instructions +push 74 +pop $$output-instructions +push 106 +pop $$pop-instructions +push 120 +pop $$push-instructions +push 132 +pop $$return-instructions +push 144 +pop $$var-instructions +halt \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/samples/structures.pda b/plugins/org.eclipse.dd.examples.pda/samples/structures.pda index 97858b0791d..b6f7cbf62ab 100644 --- a/plugins/org.eclipse.dd.examples.pda/samples/structures.pda +++ b/plugins/org.eclipse.dd.examples.pda/samples/structures.pda @@ -1,8 +1,23 @@ push one two three push 1 2 3 +push I II III var x +var x.a +var x.b var y +var y.c +var y.d +var y.d.1 +var y.d.2 +var y.d.3 pop $x +pop $x.a +pop $x.b pop $y +pop $y.c +pop $y.d +pop $y.d.1 +pop $y.d.2 +pop $y.d.3 push Done output \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java index 83aa46c71c2..fe2dd1d4543 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAExpressions.java @@ -21,7 +21,6 @@ import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.service.IExpressions; -import org.eclipse.dd.dsf.debug.service.IStack; import org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext; import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent; import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent; @@ -32,7 +31,9 @@ import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.dd.examples.pda.service.commands.PDAChildrenCommand; import org.eclipse.dd.examples.pda.service.commands.PDACommandResult; +import org.eclipse.dd.examples.pda.service.commands.PDAListResult; import org.eclipse.dd.examples.pda.service.commands.PDASetVarCommand; import org.eclipse.dd.examples.pda.service.commands.PDAVarCommand; import org.osgi.framework.BundleContext; @@ -163,7 +164,7 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions { private PDACommandControl fCommandControl; - private IStack fStack; + private PDAStack fStack; private CommandCache fCommandCache; @@ -188,7 +189,7 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions { private void doInitialize(final RequestMonitor rm) { fCommandControl = getServicesTracker().getService(PDACommandControl.class); - fStack = getServicesTracker().getService(IStack.class); + fStack = getServicesTracker().getService(PDAStack.class); fCommandCache = new CommandCache(getSession(), fCommandControl); getSession().addServiceEventListener(this, null); @@ -212,19 +213,23 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions { public IExpressionDMContext createExpression(IDMContext ctx, String expression) { // Create an expression based on the given context and string expression. - // The PDA debugger can only evaluate variables as expressions and only - // in context of a frame. PDAThreadDMContext threadCtx = DMContexts.getAncestorOfType(ctx, PDAThreadDMContext.class); - IFrameDMContext frameCtx = DMContexts.getAncestorOfType(ctx, IFrameDMContext.class); - if (threadCtx != null && frameCtx != null) { + if (threadCtx != null) { + // The PDA debugger can only evaluate variables as expressions and only + // in context of a frame, so if a frame is not given, create a top-level frame. + IFrameDMContext frameCtx = DMContexts.getAncestorOfType(ctx, IFrameDMContext.class); + if (frameCtx == null) { + frameCtx = fStack.getFrameDMContext(threadCtx, 0); + } + return new ExpressionDMContext(getSession().getId(), frameCtx, expression); - } else { - // If the thread or a frame cannot be found in context, return an "invalid" - // expression context, because a null return value is not allowed. - // Evaluating an invalid expression context will always yield an - // error. - return new InvalidExpressionDMContext(getSession().getId(), ctx, expression); - } + } + + // If the thread cannot be found in context, return an "invalid" + // expression context, because a null return value is not allowed. + // Evaluating an invalid expression context will always yield an + // error. + return new InvalidExpressionDMContext(getSession().getId(), ctx, expression); } public void getBaseExpressions(IExpressionDMContext exprContext, DataRequestMonitor rm) { @@ -246,25 +251,99 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions { } } - public void getSubExpressionCount(IExpressionDMContext exprCtx, DataRequestMonitor rm) { - PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported"); + public void getSubExpressionCount(final IExpressionDMContext exprCtx, final DataRequestMonitor rm) { + if (exprCtx instanceof ExpressionDMContext) { + final PDAThreadDMContext threadCtx = DMContexts.getAncestorOfType(exprCtx, PDAThreadDMContext.class); + final IFrameDMContext frameCtx = DMContexts.getAncestorOfType(exprCtx, IFrameDMContext.class); + + // First retrieve the stack depth, needed to properly calculate + // the frame index that is used by the PDAVarCommand. + fStack.getStackDepth( + frameCtx, 0, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + // Calculate the frame index. + int frameId = getData() - frameCtx.getLevel() - 1; + + // Send the command to evaluate the variable. + fCommandCache.execute( + new PDAChildrenCommand(threadCtx, frameId, exprCtx.getExpression()), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + rm.setData(getData().fValues.length); + rm.done(); + } + }); + } + }); + } else { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid context"); + } } public void getSubExpressions(IExpressionDMContext exprCtx, DataRequestMonitor rm) { - PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported"); + getSubExpressions(exprCtx, -1, -1, rm); } - public void getSubExpressions(IExpressionDMContext exprCtx, int startIndex, int length, - DataRequestMonitor rm) + public void getSubExpressions(final IExpressionDMContext exprCtx, final int startIndexArg, final int lengthArg, + final DataRequestMonitor rm) { - PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported"); + if (exprCtx instanceof ExpressionDMContext) { + final PDAThreadDMContext threadCtx = DMContexts.getAncestorOfType(exprCtx, PDAThreadDMContext.class); + final IFrameDMContext frameCtx = DMContexts.getAncestorOfType(exprCtx, IFrameDMContext.class); + + // First retrieve the stack depth, needed to properly calculate + // the frame index that is used by the PDAVarCommand. + fStack.getStackDepth( + frameCtx, 0, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + // Calculate the frame index. + int frameId = getData() - frameCtx.getLevel() - 1; + + // Send the command to evaluate the variable. + fCommandCache.execute( + new PDAChildrenCommand(threadCtx, frameId, exprCtx.getExpression()), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + int start = startIndexArg > 0 ? startIndexArg : 0; + int end = lengthArg > 0 ? (start + lengthArg) : getData().fValues.length; + IExpressionDMContext[] contexts = new IExpressionDMContext[end - start]; + for (int i = start; i < end && i < getData().fValues.length; i++) { + contexts[i] = new ExpressionDMContext( + getSession().getId(), frameCtx, getData().fValues[i]); + } + rm.setData(contexts); + rm.done(); + } + }); + } + }); + } else { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid context"); + } } - public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor rm) { - // PDA debugger doesn't support formatting the expression. Natural - // formatting is the only available option. - rm.setData(new String[] { NATURAL_FORMAT }); - rm.done(); + public void getAvailableFormats(IFormattedDataDMContext dmc, final DataRequestMonitor rm) { + getFormattedExpressionValue( + new FormattedValueDMContext(this, dmc, NATURAL_FORMAT), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + try { + Integer.parseInt(getData().getFormattedValue()); + rm.setData(new String[] { NATURAL_FORMAT, STRING_FORMAT, HEX_FORMAT, DECIMAL_FORMAT, OCTAL_FORMAT, BINARY_FORMAT }); + rm.done(); + } catch (NumberFormatException e) { + rm.setData(new String[] { NATURAL_FORMAT, STRING_FORMAT }); + rm.done(); + } + } + }); } public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext exprCtx, String formatId) { @@ -275,6 +354,7 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions { public void getFormattedExpressionValue(FormattedValueDMContext formattedCtx, final DataRequestMonitor rm) { + final String formatId = formattedCtx.getFormatID(); final ExpressionDMContext exprCtx = DMContexts.getAncestorOfType(formattedCtx, ExpressionDMContext.class); if (exprCtx != null) { final PDAThreadDMContext threadCtx = DMContexts.getAncestorOfType(exprCtx, PDAThreadDMContext.class); @@ -296,21 +376,95 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions { new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleSuccess() { - rm.setData(new FormattedValueDMData(getData().fResponseText)); - rm.done(); + if (NATURAL_FORMAT.equals(formatId) || STRING_FORMAT.equals(formatId)) { + rm.setData(new FormattedValueDMData(getData().fResponseText)); + rm.done(); + } else { + int result; + try { + int intResult = Integer.parseInt(getData().fResponseText); + String formattedResult = ""; + if (HEX_FORMAT.equals(formatId)) { + formattedResult = Integer.toHexString(intResult); + StringBuffer prefix = new StringBuffer("0x"); + for (int i = 0; i < 8 - formattedResult.length(); i++) { + prefix.append('0'); + } + prefix.append(formattedResult); + formattedResult = prefix.toString(); + } else if (OCTAL_FORMAT.equals(formatId)) { + formattedResult = Integer.toOctalString(intResult); + StringBuffer prefix = new StringBuffer("0c"); + for (int i = 0; i < 16 - formattedResult.length(); i++) { + prefix.append('0'); + } + prefix.append(formattedResult); + formattedResult = prefix.toString(); + } else if (BINARY_FORMAT.equals(formatId)) { + formattedResult = Integer.toBinaryString(intResult); + StringBuffer prefix = new StringBuffer("0b"); + for (int i = 0; i < 32 - formattedResult.length(); i++) { + prefix.append('0'); + } + prefix.append(formattedResult); + formattedResult = prefix.toString(); + } else if (DECIMAL_FORMAT.equals(formatId)) { + formattedResult = Integer.toString(intResult); + } else { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid format"); + } + rm.setData(new FormattedValueDMData(formattedResult)); + rm.done(); + } catch (NumberFormatException e) { + PDAPlugin.failRequest(rm, REQUEST_FAILED, "Cannot format value"); + } + } } - }); + }); } }); } else { PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid expression context " + formattedCtx); - rm.done(); } } + public void writeExpression(final IExpressionDMContext exprCtx, final String exprValue, String formatId, final RequestMonitor rm) { + writeExpression(exprCtx, exprValue, formatId, true, rm); + } + + /** + * Method to write an expression, with an additional parameter to suppress + * issuing of the expression changed event. + * @see IExpressions#writeExpression(org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext, String, String, RequestMonitor) + */ + public void writeExpression(final IExpressionDMContext exprCtx, String formattedExprValue, String formatId, + final boolean sendEvent, final RequestMonitor rm) + { + String value = null; + try { + int intValue = 0; + if (HEX_FORMAT.equals(formatId)) { + if (formattedExprValue.startsWith("0x")) formattedExprValue = formattedExprValue.substring(2); + value = Integer.toString( Integer.parseInt(formattedExprValue, 16) ); + } else if (DECIMAL_FORMAT.equals(formatId)) { + value = Integer.toString( Integer.parseInt(formattedExprValue, 10) ); + } else if (OCTAL_FORMAT.equals(formatId)) { + if (formattedExprValue.startsWith("0c")) formattedExprValue = formattedExprValue.substring(2); + value = Integer.toString( Integer.parseInt(formattedExprValue, 8) ); + } else if (BINARY_FORMAT.equals(formatId)) { + if (formattedExprValue.startsWith("0b")) formattedExprValue = formattedExprValue.substring(2); + value = Integer.toString( Integer.parseInt(formattedExprValue, 2) ); + } + } catch (NumberFormatException e) { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Value not formatted properly"); + } + + final String exprValue = value != null ? value : formattedExprValue; + + if (exprCtx instanceof ExpressionDMContext) { final PDAThreadDMContext threadCtx = DMContexts.getAncestorOfType(exprCtx, PDAThreadDMContext.class); final IFrameDMContext frameCtx = DMContexts.getAncestorOfType(exprCtx, IFrameDMContext.class); @@ -331,7 +485,13 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions { new DataRequestMonitor(getExecutor(), rm) { @Override protected void handleSuccess() { - getSession().dispatchEvent(new ExpressionChangedDMEvent(exprCtx), getProperties()); + if (sendEvent) { + getSession().dispatchEvent(new ExpressionChangedDMEvent(exprCtx), getProperties()); + } + // An expression changed, clear the cache corresponding to + // this event. Since the var evaluate commands, use the thread + // context, we have to clear all the cache entries for that thread. + fCommandCache.reset(DMContexts.getAncestorOfType(exprCtx, PDAThreadDMContext.class)); rm.done(); } }); @@ -339,7 +499,6 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions { }); } else { PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid expression context " + exprCtx); - rm.done(); } } @@ -352,7 +511,6 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions { getFormattedExpressionValue((FormattedValueDMContext) dmc, (DataRequestMonitor) rm); } else { PDAPlugin.failRequest(rm, INVALID_HANDLE, "Unknown DMC type"); - rm.done(); } } @@ -362,7 +520,7 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions { // will fail. Also reset the cache unless it was a step command. fCommandCache.setContextAvailable(e.getDMContext(), false); if (!e.getReason().equals(StateChangeReason.STEP)) { - fCommandCache.reset(); + fCommandCache.reset(e.getDMContext()); } } @@ -371,6 +529,15 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions { public void eventDispatched(ISuspendedDMEvent e) { // Enable sending commands to target and clear the cache. fCommandCache.setContextAvailable(e.getDMContext(), true); - fCommandCache.reset(); + fCommandCache.reset(e.getDMContext()); } + + @DsfServiceEventHandler + public void eventDispatched(ExpressionChangedDMEvent e) { + // An expression changed, clear the cache corresponding to + // this event. Since the var evaluate commands, use the thread + // context, we have to clear all the cache entries for that thread. + fCommandCache.reset(DMContexts.getAncestorOfType(e.getDMContext(), PDAThreadDMContext.class)); + } + } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARegisters.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARegisters.java index 08944cfa3a1..287f6517c88 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARegisters.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDARegisters.java @@ -12,50 +12,244 @@ package org.eclipse.dd.examples.pda.service; import java.math.BigInteger; import java.util.Hashtable; +import java.util.Map; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.RequestMonitor; import org.eclipse.dd.dsf.datamodel.AbstractDMContext; +import org.eclipse.dd.dsf.datamodel.AbstractDMEvent; import org.eclipse.dd.dsf.datamodel.DMContexts; import org.eclipse.dd.dsf.datamodel.IDMContext; import org.eclipse.dd.dsf.debug.service.IRegisters; import org.eclipse.dd.dsf.debug.service.IRunControl; -import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext; +import org.eclipse.dd.dsf.debug.service.command.CommandCache; +import org.eclipse.dd.dsf.debug.service.command.IEventListener; import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; import org.eclipse.dd.examples.pda.PDAPlugin; +import org.eclipse.dd.examples.pda.service.commands.PDABitField; +import org.eclipse.dd.examples.pda.service.commands.PDAGroupsCommand; +import org.eclipse.dd.examples.pda.service.commands.PDAListResult; +import org.eclipse.dd.examples.pda.service.commands.PDARegister; +import org.eclipse.dd.examples.pda.service.commands.PDARegistersCommand; +import org.eclipse.dd.examples.pda.service.commands.PDARegistersCommandResult; import org.osgi.framework.BundleContext; /** * */ -public class PDARegisters extends AbstractDsfService implements IRegisters { - +public class PDARegisters extends AbstractDsfService + implements IRegisters, IEventListener +{ + + private static class RegisterGroupDMContext extends AbstractDMContext implements IRegisterGroupDMContext { + final private String fName; + + public RegisterGroupDMContext(String sessionId, PDAVirtualMachineDMContext dmc, String groupName) { + super(sessionId, new IDMContext[] { dmc }); + fName = groupName; + } + + @Override + public boolean equals(Object other) { + return ((super.baseEquals(other)) && + (((RegisterGroupDMContext) other).fName.equals(fName))); + } + + @Override + public int hashCode() { return super.baseHashCode() + fName.hashCode(); } + + @Override + public String toString() { return baseToString() + ".group[" + fName + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ + } + + private static class RegisterDMContext extends AbstractDMContext implements IRegisterDMContext { + final private PDARegister fRegister; + + public RegisterDMContext(String sessionId, PDAThreadDMContext thread, RegisterGroupDMContext group, PDARegister reg) { + super(sessionId, new IDMContext[] { thread, group }); + fRegister = reg; + } + + @Override + public boolean equals(Object other) { + return ((super.baseEquals(other)) && + (((RegisterDMContext) other).fRegister.fName.equals(fRegister.fName))); + } + + @Override + public int hashCode() { return super.baseHashCode() + fRegister.fName.hashCode(); } + @Override + public String toString() { return baseToString() + ".register[" + fRegister.fName + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ + } + /* - * Internal control variables. + * Support class used to construct BitField DMCs. */ + private static class BitFieldDMContext extends AbstractDMContext implements IBitFieldDMContext { + + final private PDABitField fBitField; + + public BitFieldDMContext(String sessionId, RegisterDMContext reg, PDABitField bitField) { + super(sessionId, new IDMContext[] { reg }); + + fBitField = bitField; + } + + /* + * Required common manipulation routines. + */ + @Override + public boolean equals(Object other) { + if (other instanceof BitFieldDMContext) { + BitFieldDMContext dmc = (BitFieldDMContext) other; + return( (super.baseEquals(other)) && + (dmc.fBitField.fName.equals(fBitField.fName))); + } else { + return false; + } + } + + @Override + public int hashCode() { return super.baseHashCode() + fBitField.fName.hashCode(); } + + @Override + public String toString() { return baseToString() + ".bitfield[" + fBitField.fName + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ + } + + private static class RegisterGroupDMData implements IRegisterGroupDMData { + + final private String fName; + + public RegisterGroupDMData(String name) { + fName = name; + } + public String getName() { return fName; } + public String getDescription() { return "Description of the " + fName + " register group"; } + } + + private static class RegisterDMData implements IRegisterDMData { + + final private PDARegister fRegister; + + public RegisterDMData(PDARegister reg) { + fRegister = reg; + } + + public boolean isReadable() { return true; } + public boolean isReadOnce() { return false; } + public boolean isWriteable() { return fRegister.fWritable; } + public boolean isWriteOnce() { return false; } + public boolean hasSideEffects() { return false; } + public boolean isVolatile() { return true; } + + public boolean isFloat() { return false; } + public String getName() { return fRegister.fName; } + public String getDescription() { return "Description of the " + fRegister.fName + " register"; } + } + + private static class Mnemonic implements IMnemonic { + Mnemonic(String name, String value, int numBits) { + fName = name; + fValue = new BigInteger(value); + fNumBits = numBits; + } + final private String fName; + final private BigInteger fValue; + final private int fNumBits; + + public String getShortName() { return fName; } + public String getLongName() { return fName; } + + public BigInteger getValue() { return fValue; } + public int getBitCount() { return fNumBits; } + + @Override + public boolean equals( Object element ) { + if ( element instanceof Mnemonic ) { + Mnemonic mnem = (Mnemonic) element; + return ( mnem.fName.equals( fName ) ) && + ( mnem.fValue.equals( fValue ) ) && + ( mnem.fNumBits == fNumBits ); + } + return false ; + } + } + + private class BitFieldDMData implements IBitFieldDMData { + + final private PDABitField fBitField; + final private IBitGroup[] fBitGroups; + final private Mnemonic[] fMnemonics; + final private BigInteger fValue; + final private Mnemonic fMnemonicValue; + + public BitFieldDMData(PDABitField bitField, String value) { + fBitField = bitField; + fValue = new BigInteger(value); + + fBitGroups = new IBitGroup[] { + new IBitGroup() { + public int startBit() { return fBitField.fOffset; } + public int bitCount() { return fBitField.fCount; } + } + }; + + fMnemonics = new Mnemonic[fBitField.fMnemonics.size()]; + Mnemonic mnemonicValue = null; + int i = 0; + for (Map.Entry mnemonicEntry : fBitField.fMnemonics.entrySet()) { + fMnemonics[i] = new Mnemonic(mnemonicEntry.getKey(), mnemonicEntry.getValue(), fBitField.fCount); + if (fValue.equals(fMnemonics[i].fValue)) { + mnemonicValue = fMnemonics[i]; + } + i++; + } + fMnemonicValue = mnemonicValue; + } + + + public IBitGroup[] getBitGroup() { return fBitGroups; } + public IMnemonic[] getMnemonics() { return fMnemonics; } + + public boolean isZeroBasedNumbering() { return true; } + public boolean isZeroBitLeftMost() { return true; } + public boolean isReadable() { return true; } + public boolean isReadOnce() { return false; } + public boolean isWriteable() { return true; } + public boolean isWriteOnce() { return false; } + public boolean hasSideEffects() { return false; } + public boolean isFloat() { return false; } + + public String getName() { return fBitField.fName; } + public String getDescription() { return "Description of the " + fBitField.fName + " bit field"; } + + public IMnemonic getCurrentMnemonicValue() { return fMnemonicValue; } + } + + private static class RegisterChangedDMEvent extends AbstractDMEvent implements IRegisterChangedDMEvent { + RegisterChangedDMEvent(IRegisterDMContext registerDmc) { + super(registerDmc); + } + } + + private PDACommandControl fCommandControl; + private PDAExpressions fExpressions; + private CommandCache fNamesCache; + public PDARegisters(DsfSession session) { super(session); } - /* - * (non-Javadoc) - * @see org.eclipse.dd.dsf.service.AbstractDsfService#getBundleContext() - */ @Override protected BundleContext getBundleContext() { return PDAPlugin.getBundleContext(); } - /* - * (non-Javadoc) - * @see org.eclipse.dd.dsf.service.AbstractDsfService#initialize(org.eclipse.dd.dsf.concurrent.RequestMonitor) - */ @Override public void initialize(final RequestMonitor requestMonitor) { super.initialize( @@ -67,232 +261,196 @@ public class PDARegisters extends AbstractDsfService implements IRegisters { } private void doInitialize(RequestMonitor requestMonitor) { - /* - * Sign up so we see events. We use these events to decide how to manage - * any local caches we are providing as well as the lower level register - * cache we create to get/set registers on the target. - */ - getSession().addServiceEventListener(this, null); + + fCommandControl = getServicesTracker().getService(PDACommandControl.class); + fExpressions = getServicesTracker().getService(PDAExpressions.class); - /* - * Make ourselves known so clients can use us. - */ + // Create the cache to store the register definitions. This cache + // only needs to be reset upon the "registers" event and is available + // all the time. + fNamesCache = new CommandCache(getSession(), fCommandControl); + fNamesCache.setContextAvailable(fCommandControl.getVirtualMachineDMContext(), true); + + // Add the register service as a listener to PDA events, to catch + // the "registers" events from the command control. + fCommandControl.addEventListener(this); + + // Sign up so we see events. We use these events to decide how to manage + // any local caches we are providing as well as the lower level register + // cache we create to get/set registers on the target. + getSession().addServiceEventListener(this, null); + + // Make ourselves known so clients can use us. register(new String[]{IRegisters.class.getName(), PDARegisters.class.getName()}, new Hashtable()); requestMonitor.done(); } - /* - * (non-Javadoc) - * @see org.eclipse.dd.dsf.service.AbstractDsfService#shutdown(org.eclipse.dd.dsf.concurrent.RequestMonitor) - */ @Override public void shutdown(RequestMonitor requestMonitor) { unregister(); - getSession().removeServiceEventListener(this); + fCommandControl.removeEventListener(this); + getSession().removeServiceEventListener(this); super.shutdown(requestMonitor); } - /* - * These are the public interfaces for this service. - * - * (non-Javadoc) - * @see org.eclipse.dd.dsf.debug.service.IRegisters#getRegisterGroups(org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext, org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) - */ - public void getRegisterGroups(IDMContext ctx, DataRequestMonitor rm ) { - PDAVirtualMachineDMContext execDmc = DMContexts.getAncestorOfType(ctx, PDAVirtualMachineDMContext.class); - if (execDmc == null) { - rm.setStatus( new Status( IStatus.ERROR , PDAPlugin.PLUGIN_ID , INVALID_HANDLE , "Container context not found", null ) ) ; //$NON-NLS-1$ - rm.done(); + public void getRegisterGroups(IDMContext ctx, final DataRequestMonitor rm ) { + final PDAVirtualMachineDMContext dmc = DMContexts.getAncestorOfType(ctx, PDAVirtualMachineDMContext.class); + if (dmc == null) { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Container context not found"); //$NON-NLS-1$ return; } - MIRegisterGroupDMC generalGroupDMC = new MIRegisterGroupDMC( this , execDmc, 0 , "General" ) ; //$NON-NLS-1$ - MIRegisterGroupDMC analysisGroupDMC = new MIRegisterGroupDMC( this , execDmc, 0 , "Analysis" ) ; //$NON-NLS-1$ - - rm.setData( new MIRegisterGroupDMC[] { generalGroupDMC, analysisGroupDMC } ) ; - rm.done() ; + fNamesCache.execute( + new PDAGroupsCommand(dmc), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + IRegisterGroupDMContext[] groups = new IRegisterGroupDMContext[getData().fValues.length]; + for (int i = 0; i < getData().fValues.length; i++) { + groups[i] = new RegisterGroupDMContext(getSession().getId(), dmc, getData().fValues[i]); + } + rm.setData(groups); + rm.done(); + }; + }); } - /* - * (non-Javadoc) - * @see org.eclipse.dd.dsf.debug.service.IRegisters#getRegisters(org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) - */ - public void getRegisters(final IDMContext dmc, final DataRequestMonitor rm) { - final MIRegisterGroupDMC groupDmc = DMContexts.getAncestorOfType(dmc, MIRegisterGroupDMC.class); + public void getRegisters(final IDMContext ctx, final DataRequestMonitor rm) { + final PDAThreadDMContext execDmc = DMContexts.getAncestorOfType(ctx, PDAThreadDMContext.class); + if ( execDmc == null ) { + PDAPlugin.failRequest(rm, INVALID_HANDLE , "Thread context not found"); //$NON-NLS-1$ + return; + } + + final RegisterGroupDMContext groupDmc = DMContexts.getAncestorOfType(ctx, RegisterGroupDMContext.class); if ( groupDmc == null ) { - rm.setStatus( new Status( IStatus.ERROR , PDAPlugin.PLUGIN_ID , INVALID_HANDLE , "RegisterGroup context not found", null ) ) ; //$NON-NLS-1$ - rm.done(); + PDAPlugin.failRequest(rm, INVALID_HANDLE , "Group context not found"); //$NON-NLS-1$ return; } - String[] names = null;; - - if ( groupDmc.getName().equals( "General") ) { - - names = new String[] { "pc" , - "sp" , - "status" , - "stackdepth" , - "stack[0]" , - "stack[1]" , - "stack[2]" , - "stack[3]" , - "stack[4]" , - "stack[5]" } ; - } - else if ( groupDmc.getName().equals( "Analysis") ) { - - names = new String[] { "total-instructions" , - "add-instructions" , - "call-instructions" , - "dec-instructions" , - "dup-instructions" , - "halt-instructions" , - "output-instructions" , - "pop-instructions" , - "push-instructions" , - "return-instructions" , - "var-instructions" } ; - } - else { - rm.setStatus(new Status(IStatus.ERROR , PDAPlugin.PLUGIN_ID , INTERNAL_ERROR , "Invalid group = " + groupDmc , null)); //$NON-NLS-1$ - rm.done(); - } + fNamesCache.execute( + new PDARegistersCommand(execDmc, groupDmc != null ? groupDmc.fName : null), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + IRegisterDMContext[] groups = new IRegisterDMContext[getData().fRegisters.length]; + for (int i = 0; i < getData().fRegisters.length; i++) { + groups[i] = new RegisterDMContext(getSession().getId(), execDmc, groupDmc, getData().fRegisters[i]); + } + rm.setData(groups); + rm.done(); + }; + }); - IExecutionDMContext executionDmc = DMContexts.getAncestorOfType(dmc, IExecutionDMContext.class); - - if(executionDmc == null) - rm.setData(makeRegisterDMCs(groupDmc, names)); - else - rm.setData(makeRegisterDMCs(groupDmc, executionDmc, names)); - rm.done(); } - /* - * (non-Javadoc) - * @see org.eclipse.dd.dsf.debug.service.IRegisters#getBitFields(org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) - */ - public void getBitFields( IDMContext regDmc , DataRequestMonitor rm ) { + public void getBitFields( IDMContext dmc , DataRequestMonitor rm ) { - MIRegisterDMC registerDmc = DMContexts.getAncestorOfType(regDmc, MIRegisterDMC.class); + RegisterDMContext registerDmc = DMContexts.getAncestorOfType(dmc, RegisterDMContext.class); if ( registerDmc == null ) { - rm.setStatus( new Status( IStatus.ERROR , PDAPlugin.PLUGIN_ID , INVALID_HANDLE , "No register in context: " + regDmc , null ) ) ; //$NON-NLS-1$ - rm.done(); + PDAPlugin.failRequest(rm,INVALID_HANDLE, "No register in context: " + dmc) ; //$NON-NLS-1$ return; } - MIBitFieldDMC[] bitFieldDMCs = null; + PDABitField[] bitFields = registerDmc.fRegister.fBitFields; + BitFieldDMContext[] bitFieldDMCs = new BitFieldDMContext[bitFields.length]; - if ( registerDmc.getName().equals( "status") ) { - bitFieldDMCs = new MIBitFieldDMC[4]; - bitFieldDMCs[ 0 ] = new MIBitFieldDMC( PDARegisters.this, registerDmc, 0, "BITS_00_07" ) ; //$NON-NLS-1$ - bitFieldDMCs[ 1 ] = new MIBitFieldDMC( PDARegisters.this, registerDmc, 1, "BITS_08_15" ) ; //$NON-NLS-1$ - bitFieldDMCs[ 2 ] = new MIBitFieldDMC( PDARegisters.this, registerDmc, 2, "BITS_16_23" ) ; //$NON-NLS-1$ - bitFieldDMCs[ 3 ] = new MIBitFieldDMC( PDARegisters.this, registerDmc, 3, "BITS_24_31" ) ; //$NON-NLS-1$ - } - else { - bitFieldDMCs = new MIBitFieldDMC[0]; + for (int i = 0; i < bitFields.length; i++) { + bitFieldDMCs[i] = new BitFieldDMContext(getSession().getId(), registerDmc, bitFields[i]); } rm.setData(bitFieldDMCs) ; rm.done(); } - /* - * (non-Javadoc) - * @see org.eclipse.dd.dsf.debug.service.IRegisters#writeRegister(org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext, java.lang.String, java.lang.String, org.eclipse.dd.dsf.concurrent.RequestMonitor) - */ - public void writeRegister(IRegisterDMContext regCtx, final String regValue, final String formatId, final RequestMonitor rm) { - MIRegisterGroupDMC grpDmc = DMContexts.getAncestorOfType(regCtx, MIRegisterGroupDMC.class); - if ( grpDmc == null ) { - rm.setStatus( new Status( IStatus.ERROR , PDAPlugin.PLUGIN_ID , INVALID_HANDLE , "RegisterGroup context not found" , null ) ) ; //$NON-NLS-1$ - rm.done(); - return; + public void writeRegister(final IRegisterDMContext regCtx, String regValue, String formatId, final RequestMonitor rm) { + if (regCtx instanceof RegisterDMContext) { + IExpressionDMContext exprCtx = createRegisterExpressionDmc( (RegisterDMContext)regCtx ); + fExpressions.writeExpression( + exprCtx, regValue, formatId, false, + new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + generateRegisterChangedEvent( (RegisterDMContext)regCtx ); + rm.done(); + } + }); + + } else { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid context"); //$NON-NLS-1$ } - - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Register is read only at this time", null)); //$NON-NLS-1$ - rm.done(); + } - /* - * (non-Javadoc) - * @see org.eclipse.dd.dsf.debug.service.IRegisters#writeBitField(org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMContext, java.lang.String, java.lang.String, org.eclipse.dd.dsf.concurrent.RequestMonitor) - */ - public void writeBitField(IBitFieldDMContext bitFieldCtx, String bitFieldValue, String formatId, RequestMonitor rm) { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Writing bit field not supported", null)); //$NON-NLS-1$ - rm.done(); + public void writeBitField(final IBitFieldDMContext bitFieldCtx, String bitFieldValue, String formatId, final RequestMonitor rm) { + if (bitFieldCtx instanceof BitFieldDMContext) { + IExpressionDMContext exprCtx = createBitFieldExpressionDmc( (BitFieldDMContext)bitFieldCtx ); + fExpressions.writeExpression( + exprCtx, bitFieldValue, formatId, false, + new RequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + generateRegisterChangedEvent( + DMContexts.getAncestorOfType(bitFieldCtx, RegisterDMContext.class) ); + rm.done(); + } + }); + } else { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid context"); //$NON-NLS-1$ + } } - /* - * (non-Javadoc) - * @see org.eclipse.dd.dsf.debug.service.IRegisters#writeBitField(org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMContext, org.eclipse.dd.dsf.debug.service.IRegisters.IMnemonic, org.eclipse.dd.dsf.concurrent.RequestMonitor) - */ public void writeBitField(IBitFieldDMContext bitFieldCtx, IMnemonic mnemonic, RequestMonitor rm) { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Writing bit field not supported", null)); //$NON-NLS-1$ - rm.done(); + if (mnemonic instanceof Mnemonic) { + writeBitField(bitFieldCtx, ((Mnemonic)mnemonic).fValue.toString(), NATURAL_FORMAT, rm); + } else { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid mnemonic"); //$NON-NLS-1$ + } } - /* - * (non-Javadoc) - * @see org.eclipse.dd.dsf.debug.service.IFormattedValues#getAvailableFormats(org.eclipse.dd.dsf.debug.service.IFormattedValues.IFormattedDataDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) - */ public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor rm) { - - rm.setData(new String[] { HEX_FORMAT, DECIMAL_FORMAT, OCTAL_FORMAT, BINARY_FORMAT, NATURAL_FORMAT }); - rm.done(); + IExpressionDMContext exprCtx = null; + if ( dmc instanceof RegisterDMContext ) { + exprCtx = createRegisterExpressionDmc((RegisterDMContext)dmc); + } else if ( dmc instanceof BitFieldDMContext ) { + exprCtx = createBitFieldExpressionDmc((BitFieldDMContext)dmc); + } + if (exprCtx != null) { + fExpressions.getAvailableFormats(exprCtx, rm); + } else { + throw new IllegalArgumentException("Invalid register/bit field context " + dmc); + } } - /* - * (non-Javadoc) - * @see org.eclipse.dd.dsf.debug.service.IFormattedValues#getFormattedValueContext(org.eclipse.dd.dsf.debug.service.IFormattedValues.IFormattedDataDMContext, java.lang.String) - */ public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext dmc, String formatId) { - if ( dmc instanceof MIRegisterDMC ) { - MIRegisterDMC regDmc = (MIRegisterDMC) dmc; - return( new FormattedValueDMContext( this, regDmc, formatId)); + IExpressionDMContext exprCtx = null; + if ( dmc instanceof RegisterDMContext ) { + exprCtx = createRegisterExpressionDmc((RegisterDMContext)dmc); + } else if ( dmc instanceof BitFieldDMContext ) { + exprCtx = createBitFieldExpressionDmc((BitFieldDMContext)dmc); } - else if ( dmc instanceof MIBitFieldDMC ) { - MIBitFieldDMC bitFieldDmc = (MIBitFieldDMC) dmc; - return( new FormattedValueDMContext( this, bitFieldDmc, formatId)); + if (exprCtx != null) { + return fExpressions.getFormattedValueContext(exprCtx, formatId); + } else { + throw new IllegalArgumentException("Invalid register/bit field context " + dmc); } - - return null; } - /* - * (non-Javadoc) - * @see org.eclipse.dd.dsf.debug.service.IRegisters#findRegisterGroup(org.eclipse.dd.dsf.datamodel.IDMContext, java.lang.String, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) - */ public void findRegisterGroup(IDMContext ctx, String name, DataRequestMonitor rm) { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Finding a Register Group context not supported", null)); //$NON-NLS-1$ - rm.done(); + PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Finding context not supported"); //$NON-NLS-1$ } - /* - * (non-Javadoc) - * @see org.eclipse.dd.dsf.debug.service.IRegisters#findRegister(org.eclipse.dd.dsf.datamodel.IDMContext, java.lang.String, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) - */ public void findRegister(IDMContext ctx, String name, DataRequestMonitor rm) { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Finding a Register context not supported", null)); //$NON-NLS-1$ - rm.done(); + PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Finding context not supported"); //$NON-NLS-1$ } - /* - * (non-Javadoc) - * @see org.eclipse.dd.dsf.debug.service.IRegisters#findBitField(org.eclipse.dd.dsf.datamodel.IDMContext, java.lang.String, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) - */ public void findBitField(IDMContext ctx, String name, DataRequestMonitor rm) { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, NOT_SUPPORTED, "Finding a Register Group context not supported", null)); //$NON-NLS-1$ - rm.done(); + PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Finding context not supported"); //$NON-NLS-1$ } - /* - * (non-Javadoc) - * @see org.eclipse.dd.dsf.datamodel.IDMService#getModelData(org.eclipse.dd.dsf.datamodel.IDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) - */ @SuppressWarnings("unchecked") public void getModelData(IDMContext dmc, DataRequestMonitor rm) { /* @@ -302,737 +460,70 @@ public class PDARegisters extends AbstractDsfService implements IRegisters { * data mine by talking to the Debug Engine. */ - if (dmc instanceof MIRegisterGroupDMC) { - getRegisterGroupData((MIRegisterGroupDMC)dmc, (DataRequestMonitor)rm); - } else if (dmc instanceof MIRegisterDMC) { - getRegisterData((MIRegisterDMC)dmc, (DataRequestMonitor)rm); - } else if (dmc instanceof MIBitFieldDMC) { - getBitFieldData((MIBitFieldDMC) dmc, (DataRequestMonitor)rm); + if (dmc instanceof RegisterGroupDMContext) { + getRegisterGroupData((RegisterGroupDMContext)dmc, (DataRequestMonitor)rm); + } else if (dmc instanceof RegisterDMContext) { + getRegisterData((RegisterDMContext)dmc, (DataRequestMonitor)rm); + } else if (dmc instanceof BitFieldDMContext) { + getBitFieldData((BitFieldDMContext) dmc, (DataRequestMonitor)rm); } else if (dmc instanceof FormattedValueDMContext) { getFormattedExpressionValue((FormattedValueDMContext)dmc, (DataRequestMonitor)rm); } else { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, -1, "Unknown DMC type", null)); //$NON-NLS-1$ - rm.done(); + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Unknown DMC type"); //$NON-NLS-1$ } } - /* - * (non-Javadoc) - * @see org.eclipse.dd.dsf.debug.service.IFormattedValues#getFormattedExpressionValue(org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) - */ public void getFormattedExpressionValue(FormattedValueDMContext dmc, DataRequestMonitor rm) { - if (dmc.getParents().length == 1 && dmc.getParents()[0] instanceof MIRegisterDMC) { - getRegisterDataValue( (MIRegisterDMC) dmc.getParents()[0], dmc.getFormatID(), rm); - } - else if (dmc.getParents().length == 1 && dmc.getParents()[0] instanceof MIBitFieldDMC) { - getBitFieldDataValue( (MIBitFieldDMC) dmc.getParents()[0], dmc.getFormatID(), rm); - } else { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$ - rm.done(); - } + fExpressions.getFormattedExpressionValue(dmc, rm); } - /* - * (non-Javadoc) - * @see org.eclipse.dd.dsf.debug.service.IRegisters#getRegisterGroupData(org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterGroupDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) - */ public void getRegisterGroupData(IRegisterGroupDMContext regGroupDmc, DataRequestMonitor rm) { - - MIRegisterGroupDMC groupDmc = (MIRegisterGroupDMC) regGroupDmc; - - /* - * Register group layout : - * - * + General - * + Analysis - */ - - if ( groupDmc.getName().equals( "General" ) ) { - rm.setData( new RegisterGroupData( "General", "General Purpose Control Registers") ) ; //$NON-NLS-1$ //$NON-NLS-2$ - } - else if ( groupDmc.getName().equals( "Analysis" ) ) { - rm.setData( new RegisterGroupData( "Analysis", "Code Analysis Registers") ) ; //$NON-NLS-1$ //$NON-NLS-2$ - } - else { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown register group", null)); //$NON-NLS-1$ - } - - rm.done(); - } - - /* - * (non-Javadoc) - * @see org.eclipse.dd.dsf.debug.service.IRegisters#getRegisterData(org.eclipse.dd.dsf.debug.service.IRegisters.IRegisterDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) - */ - public void getRegisterData(IRegisterDMContext regDmc , DataRequestMonitor rm) { - if (regDmc instanceof MIRegisterDMC) { - MIRegisterDMC pdaRegDmc = (MIRegisterDMC)regDmc; - String regName = pdaRegDmc.getName(); - String regDesc = BLANK_STRING; - boolean foundReg = false; - boolean isWriteable = false ; - - if ( regName.equalsIgnoreCase( "pc" ) ) { foundReg = true ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "sp" ) ) { foundReg = true ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "status" ) ) { foundReg = true ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stackdepth" ) ) { foundReg = true ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[0]" ) ) { foundReg = true ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[1]" ) ) { foundReg = true ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[2]" ) ) { foundReg = true ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[3]" ) ) { foundReg = true ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[4]" ) ) { foundReg = true ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[5]" ) ) { foundReg = true ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "total-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "add-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "call-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "dec-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "dup-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "halt-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "output-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "pop-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "push-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "return-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "var-instructions" ) ) { foundReg = true ; } //$NON-NLS-1$ - - if ( regName.equalsIgnoreCase( "pc" ) ) { isWriteable = false ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "sp" ) ) { isWriteable = false ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "status" ) ) { isWriteable = false ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stackdepth" ) ) { isWriteable = false ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[0]" ) ) { isWriteable = false ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[1]" ) ) { isWriteable = false ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[2]" ) ) { isWriteable = false ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[3]" ) ) { isWriteable = false ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[4]" ) ) { isWriteable = false ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[5]" ) ) { isWriteable = false ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "total-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "add-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "call-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "dec-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "dup-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "halt-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "output-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "pop-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "push-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "return-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "var-instructions" ) ) { isWriteable = false ; } //$NON-NLS-1$ - - if ( regName.equalsIgnoreCase( "pc" ) ) { regDesc = "Program Counter" ; } //$NON-NLS-1$ //$NON-NLS-2$ - else if ( regName.equalsIgnoreCase( "sp" ) ) { regDesc = "Stack Pointer" ; } //$NON-NLS-1$ //$NON-NLS-2$ - else if ( regName.equalsIgnoreCase( "status" ) ) { regDesc = "CPU Status" ; } //$NON-NLS-1$ //$NON-NLS-2$ - else if ( regName.equalsIgnoreCase( "stackdepth" ) ) { regDesc = "Current depth of the pushdown stack" ; } //$NON-NLS-1$ //$NON-NLS-2$ - else if ( regName.equalsIgnoreCase( "stack[0]" ) ) { regDesc = "Stack entry" ; } //$NON-NLS-1$ //$NON-NLS-2$ - else if ( regName.equalsIgnoreCase( "stack[1]" ) ) { regDesc = "Stack entry" ; } //$NON-NLS-1$ //$NON-NLS-2$ - else if ( regName.equalsIgnoreCase( "stack[2]" ) ) { regDesc = "Stack entry" ; } //$NON-NLS-1$ //$NON-NLS-2$ - else if ( regName.equalsIgnoreCase( "stack[3]" ) ) { regDesc = "Stack entry" ; } //$NON-NLS-1$ //$NON-NLS-2$ - else if ( regName.equalsIgnoreCase( "stack[4]" ) ) { regDesc = "Stack entry" ; } //$NON-NLS-1$ //$NON-NLS-2$ - else if ( regName.equalsIgnoreCase( "stack[5]" ) ) { regDesc = "Stack entry" ; } //$NON-NLS-1$ //$NON-NLS-2$ - else if ( regName.equalsIgnoreCase( "total-instructions" ) ) { regDesc = "Total # of instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ - else if ( regName.equalsIgnoreCase( "add-instructions" ) ) { regDesc = "# of 'addr' instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ - else if ( regName.equalsIgnoreCase( "call-instructions" ) ) { regDesc = "# of 'call' instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ - else if ( regName.equalsIgnoreCase( "dec-instructions" ) ) { regDesc = "# of 'dec' instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ - else if ( regName.equalsIgnoreCase( "dup-instructions" ) ) { regDesc = "# of 'dup' instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ - else if ( regName.equalsIgnoreCase( "halt-instructions" ) ) { regDesc = "# of 'halt' instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ - else if ( regName.equalsIgnoreCase( "output-instructions" ) ) { regDesc = "# of 'output' instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ - else if ( regName.equalsIgnoreCase( "pop-instructions" ) ) { regDesc = "# of 'pop' instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ - else if ( regName.equalsIgnoreCase( "push-instructions" ) ) { regDesc = "# of 'push' instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ - else if ( regName.equalsIgnoreCase( "return-instructions" ) ) { regDesc = "# of 'return' instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ - else if ( regName.equalsIgnoreCase( "var-instructions" ) ) { regDesc = "# of 'var' instructions in the current program" ; } //$NON-NLS-1$ //$NON-NLS-2$ - - if ( foundReg ) { - rm.setData(new RegisterData(regName, regDesc, false, isWriteable)); - rm.done(); - } - else { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown register", null)); //$NON-NLS-1$ - rm.done(); - } + if (regGroupDmc instanceof RegisterGroupDMContext) { + rm.setData(new RegisterGroupDMData( ((RegisterGroupDMContext)regGroupDmc).fName )); + rm.done(); } else { - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown DMC type", null)); //$NON-NLS-1$ + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid context"); //$NON-NLS-1$ + } + } + + public void getRegisterData(IRegisterDMContext regDmc , DataRequestMonitor rm) { + if (regDmc instanceof RegisterDMContext) { + rm.setData(new RegisterDMData( ((RegisterDMContext)regDmc).fRegister )); rm.done(); + } else { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid context"); //$NON-NLS-1$ } } - /* - * (non-Javadoc) - * @see org.eclipse.dd.dsf.debug.service.IRegisters#getBitFieldData(org.eclipse.dd.dsf.debug.service.IRegisters.IBitFieldDMContext, org.eclipse.dd.dsf.concurrent.DataRequestMonitor) - */ - public void getBitFieldData(IBitFieldDMContext dmc, DataRequestMonitor rm) { + public void getBitFieldData(IBitFieldDMContext dmc, final DataRequestMonitor rm) { + if ( !(dmc instanceof BitFieldDMContext) ) { + PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid context"); //$NON-NLS-1$ + } + final BitFieldDMContext bitFieldDmc = (BitFieldDMContext) dmc; - MIBitFieldDMC bitFieldDmc = (MIBitFieldDMC) dmc; - IMnemonic[] EmptyMnemonic = new IMnemonic[0]; - BitFieldData bData = null; - - if ( bitFieldDmc.getName().equals( "BITS_00_07" ) ) { - - bData = new BitFieldData( bitFieldDmc.getName(), "Status Bits 00 - 07", new BigInteger( "0" ) , true, true, true, false, false, false, false, false); - - IBitGroup[] bitGroups = new IBitGroup[1]; - - BitGroupData bGroup = new BitGroupData(); - - bGroup.setBitCount(8); - bGroup.setStartBit(0); - - bitGroups[0] = bGroup; - - bData.addBitGroups(bitGroups); - bData.addMnemonics(EmptyMnemonic); - } - else if ( bitFieldDmc.getName().equals( "BITS_08_15" ) ) { - - bData = new BitFieldData( bitFieldDmc.getName(), "Status Bits 08 - 15", new BigInteger( "0" ) , true, true, true, false, false, false, false, false); - - IBitGroup[] bitGroups = new IBitGroup[1]; - - BitGroupData bGroup = new BitGroupData(); - - bGroup.setBitCount(8); - bGroup.setStartBit(8); - - bitGroups[0] = bGroup; - - bData.addBitGroups(bitGroups); - bData.addMnemonics(EmptyMnemonic); - } - else if ( bitFieldDmc.getName().equals( "BITS_16_23" ) ) { - - bData = new BitFieldData( bitFieldDmc.getName(), "Status Bits 16 - 23", new BigInteger( "0" ) , true, true, true, false, false, false, false, false); - - IBitGroup[] bitGroups = new IBitGroup[1]; - - BitGroupData bGroup = new BitGroupData(); - - bGroup.setBitCount(8); - bGroup.setStartBit(16); - - bitGroups[0] = bGroup; - - bData.addBitGroups(bitGroups); - bData.addMnemonics(EmptyMnemonic); - } - else if ( bitFieldDmc.getName().equals( "BITS_24_31" ) ) { - - bData = new BitFieldData( bitFieldDmc.getName(), "Status Bits 24 - 31", new BigInteger( "255" ) , true, true, true, false, false, false, false, false); - - IBitGroup[] bitGroups = new IBitGroup[1]; - - BitGroupData bGroup = new BitGroupData(); - - bGroup.setBitCount(8); - bGroup.setStartBit(24); - - bitGroups[0] = bGroup; - - bData.addBitGroups(bitGroups); - bData.addMnemonics(EmptyMnemonic); - } - - rm.setData(bData); - rm.done(); + IExpressionDMContext bitFieldExprDmc = createBitFieldExpressionDmc(bitFieldDmc); + FormattedValueDMContext formattedBitFieldDmc = + fExpressions.getFormattedValueContext(bitFieldExprDmc, NATURAL_FORMAT); + fExpressions.getFormattedExpressionValue( + formattedBitFieldDmc, + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + rm.setData(new BitFieldDMData(bitFieldDmc.fBitField, getData().getFormattedValue())); + rm.done(); + } + }); } - private void getRegisterDataValue( final MIRegisterDMC regDmc, final String formatId, final DataRequestMonitor rm) { - IExecutionDMContext miExecDmc = DMContexts.getAncestorOfType(regDmc, IExecutionDMContext.class); - if(miExecDmc == null){ - // Set value to blank if execution dmc is not present - rm.setData( new FormattedValueDMData( BLANK_STRING ) ); - rm.done(); - return; - } - - String regName = regDmc.getName() ; - String value = BLANK_STRING; - - if ( HEX_FORMAT.equals( formatId ) || NATURAL_FORMAT.equals( formatId ) ) { - - if ( regName.equalsIgnoreCase( "pc" ) ) { value = "0x00000043" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "sp" ) ) { value = "0x000000C6" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "status" ) ) { value = "0x000000FF" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stackdepth" ) ) { value = "0x00000005" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[0]" ) ) { value = "0x0000000A" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[1]" ) ) { value = "0x00000025" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[2]" ) ) { value = "0x00000066" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[3]" ) ) { value = "0x0000008D" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[4]" ) ) { value = "0x000000A9" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[5]" ) ) { value = "0x000000C6" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "total-instructions" ) ) { value = "0x00000226" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "add-instructions" ) ) { value = "0x0000000A" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "call-instructions" ) ) { value = "0x00000014" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "dec-instructions" ) ) { value = "0x0000001E" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "dup-instructions" ) ) { value = "0x00000028" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "halt-instructions" ) ) { value = "0x00000032" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "output-instructions" ) ) { value = "0x0000003C" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "pop-instructions" ) ) { value = "0x00000046" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "push-instructions" ) ) { value = "0x00000050" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "return-instructions" ) ) { value = "0x0000005A" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "var-instructions" ) ) { value = "0x00000064" ; } //$NON-NLS-1$ - - rm.setData( new FormattedValueDMData( value ) ); - rm.done(); - return; - } - - if ( OCTAL_FORMAT.equals( formatId ) ) { - - if ( regName.equalsIgnoreCase( "pc" ) ) { value = "00000103" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "sp" ) ) { value = "00000306" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "status" ) ) { value = "00000400" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stackdepth" ) ) { value = "00000005" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[0]" ) ) { value = "00000012" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[1]" ) ) { value = "00000045" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[2]" ) ) { value = "00000146" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[3]" ) ) { value = "00000215" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[4]" ) ) { value = "00000251" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[5]" ) ) { value = "00000306" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "total-instructions" ) ) { value = "00001046" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "add-instructions" ) ) { value = "00000012" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "call-instructions" ) ) { value = "00000024" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "dec-instructions" ) ) { value = "00000036" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "dup-instructions" ) ) { value = "00000050" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "halt-instructions" ) ) { value = "00000062" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "output-instructions" ) ) { value = "00000074" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "pop-instructions" ) ) { value = "00000106" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "push-instructions" ) ) { value = "00000120" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "return-instructions" ) ) { value = "00000132" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "var-instructions" ) ) { value = "00000144" ; } //$NON-NLS-1$ - - rm.setData( new FormattedValueDMData( value ) ); - rm.done(); - return; - } - - if ( BINARY_FORMAT.equals( formatId ) ) { - - if ( regName.equalsIgnoreCase( "pc" ) ) { value = "0b00000000000000000000000001000011" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "sp" ) ) { value = "0b00000000000000000000000011000110" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "status" ) ) { value = "0b00000000000000000000001001010101" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stackdepth" ) ) { value = "0b00000000000000000000000000000101" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[0]" ) ) { value = "0b00000000000000000000000000001010" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[1]" ) ) { value = "0b00000000000000000000000000100101" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[2]" ) ) { value = "0b00000000000000000000000001100110" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[3]" ) ) { value = "0b00000000000000000000000010001101" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[4]" ) ) { value = "0b00000000000000000000000010101001" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[5]" ) ) { value = "0b00000000000000000000000011000110" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "total-instructions" ) ) { value = "0b00000000000000000000001000100110" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "add-instructions" ) ) { value = "0b00000000000000000000000000001010" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "call-instructions" ) ) { value = "0b00000000000000000000000000010100" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "dec-instructions" ) ) { value = "0b00000000000000000000000000011110" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "dup-instructions" ) ) { value = "0b00000000000000000000000000101000" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "halt-instructions" ) ) { value = "0b00000000000000000000000000110010" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "output-instructions" ) ) { value = "0b00000000000000000000000000111100" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "pop-instructions" ) ) { value = "0b00000000000000000000000001000110" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "push-instructions" ) ) { value = "0b00000000000000000000000001010000" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "return-instructions" ) ) { value = "0b00000000000000000000000001011010" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "var-instructions" ) ) { value = "0b00000000000000000000000001100100" ; } //$NON-NLS-1$ - - rm.setData( new FormattedValueDMData( value ) ); - rm.done(); - return; - } - - if ( DECIMAL_FORMAT.equals( formatId ) ) { - - if ( regName.equalsIgnoreCase( "pc" ) ) { value = "67" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "sp" ) ) { value = "198" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "status" ) ) { value = "256" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stackdepth" ) ) { value = "5" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[0]" ) ) { value = "10" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[1]" ) ) { value = "37" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[2]" ) ) { value = "102" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[3]" ) ) { value = "141" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[4]" ) ) { value = "169" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "stack[5]" ) ) { value = "198" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "total-instructions" ) ) { value = "550" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "add-instructions" ) ) { value = "10" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "call-instructions" ) ) { value = "20" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "dec-instructions" ) ) { value = "30" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "dup-instructions" ) ) { value = "40" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "halt-instructions" ) ) { value = "50" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "output-instructions" ) ) { value = "60" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "pop-instructions" ) ) { value = "70" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "push-instructions" ) ) { value = "80" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "return-instructions" ) ) { value = "90" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "var-instructions" ) ) { value = "100" ; } //$NON-NLS-1$ - - rm.setData( new FormattedValueDMData( value ) ); - rm.done(); - return; - } - - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown number format", null)); //$NON-NLS-1$ - rm.done(); + private IExpressionDMContext createRegisterExpressionDmc(RegisterDMContext dmc) { + return fExpressions.createExpression(dmc, "$" + dmc.fRegister.fName); } - - private void getBitFieldDataValue( final MIBitFieldDMC regDmc, final String formatId, final DataRequestMonitor rm) { - IExecutionDMContext miExecDmc = DMContexts.getAncestorOfType(regDmc, IExecutionDMContext.class); - if(miExecDmc == null){ - // Set value to blank if execution dmc is not present - rm.setData( new FormattedValueDMData( BLANK_STRING ) ); - rm.done(); - return; - } - String regName = regDmc.getName() ; - String value = BLANK_STRING; - - if ( HEX_FORMAT.equals( formatId ) || NATURAL_FORMAT.equals( formatId ) ) { - - if ( regName.equalsIgnoreCase( "BITS_00_07" ) ) { value = "0x00" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "BITS_08_15" ) ) { value = "0x00" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "BITS_16_23" ) ) { value = "0x00" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "BITS_24_31" ) ) { value = "0xFF" ; } //$NON-NLS-1$ - - rm.setData( new FormattedValueDMData( value ) ); - rm.done(); - return; - } - - if ( OCTAL_FORMAT.equals( formatId ) ) { - - if ( regName.equalsIgnoreCase( "BITS_00_07" ) ) { value = "0000" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "BITS_08_15" ) ) { value = "0000" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "BITS_16_23" ) ) { value = "0000" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "BITS_24_31" ) ) { value = "0377" ; } //$NON-NLS-1$ - - rm.setData( new FormattedValueDMData( value ) ); - rm.done(); - return; - } - - if ( BINARY_FORMAT.equals( formatId ) ) { - - if ( regName.equalsIgnoreCase( "BITS_00_07" ) ) { value = "0b00000000" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "BITS_08_15" ) ) { value = "0b00000000" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "BITS_16_23" ) ) { value = "0b00000000" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "BITS_24_31" ) ) { value = "0b11111111" ; } //$NON-NLS-1$ - - rm.setData( new FormattedValueDMData( value ) ); - rm.done(); - return; - } - - if ( DECIMAL_FORMAT.equals( formatId ) ) { - - if ( regName.equalsIgnoreCase( "BITS_00_07" ) ) { value = "0" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "BITS_08_15" ) ) { value = "0" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "BITS_16_23" ) ) { value = "0" ; } //$NON-NLS-1$ - else if ( regName.equalsIgnoreCase( "BITS_24_31" ) ) { value = "255" ; } //$NON-NLS-1$ - - rm.setData( new FormattedValueDMData( value ) ); - rm.done(); - return; - } - - rm.setStatus(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown number format", null)); //$NON-NLS-1$ - rm.done(); + private IExpressionDMContext createBitFieldExpressionDmc(BitFieldDMContext dmc) { + RegisterDMContext regDmc = DMContexts.getAncestorOfType(dmc, RegisterDMContext.class); + return fExpressions.createExpression(dmc, "$" + regDmc.fRegister.fName + "." + dmc.fBitField.fName); } - private static final String BLANK_STRING = ""; //$NON-NLS-1$ - - /* - * Support class used to construct Register Group DMCs. - */ - - private static class MIRegisterGroupDMC extends AbstractDMContext implements IRegisterGroupDMContext { - - private int fGroupNo; - private String fGroupName; - - public MIRegisterGroupDMC(PDARegisters service, PDAVirtualMachineDMContext execDmc, int groupNo, String groupName) { - super(service.getSession().getId(), new IDMContext[] { execDmc }); - fGroupNo = groupNo; - fGroupName = groupName; - } - - public int getGroupNo() { return fGroupNo; } - public String getName() { return fGroupName; } - - @Override - public boolean equals(Object other) { - return ((super.baseEquals(other)) && (((MIRegisterGroupDMC) other).fGroupNo == fGroupNo) && - (((MIRegisterGroupDMC) other).fGroupName.equals(fGroupName))); - } - - @Override - public int hashCode() { return super.baseHashCode() ^ fGroupNo; } - @Override - public String toString() { return baseToString() + ".group[" + fGroupNo + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ - } - - /* - * Support class used to construct Register DMCs. - */ - - private static class MIRegisterDMC extends AbstractDMContext implements IRegisterDMContext { - - private int fRegNo; - private String fRegName; - - public MIRegisterDMC(PDARegisters service, MIRegisterGroupDMC group, int regNo, String regName) { - super(service.getSession().getId(), - new IDMContext[] { group }); - fRegNo = regNo; - fRegName = regName; - } - - public MIRegisterDMC(PDARegisters service, MIRegisterGroupDMC group, IExecutionDMContext execDmc, int regNo, String regName) { - super(service.getSession().getId(), new IDMContext[] { execDmc, group }); - fRegNo = regNo; - fRegName = regName; - } - - public int getRegNo() { return fRegNo; } - public String getName() { return fRegName; } - - @Override - public boolean equals(Object other) { - return ((super.baseEquals(other)) && (((MIRegisterDMC) other).fRegNo == fRegNo) && - (((MIRegisterDMC) other).fRegName.equals(fRegName))); - } - - @Override - public int hashCode() { return super.baseHashCode() ^ fRegNo; } - @Override - public String toString() { return baseToString() + ".register[" + fRegNo + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ - } - - /* - * Support class used to construct BitField DMCs. - */ - private static class MIBitFieldDMC extends AbstractDMContext implements IBitFieldDMContext { - - private int fBitFieldNo; - private String fBitFieldName; - - public MIBitFieldDMC(PDARegisters service, MIRegisterDMC reg, int bitFieldNo, String bitFieldName) { - super(service.getSession().getId(), new IDMContext[] { reg }); - - fBitFieldNo = bitFieldNo; - fBitFieldName = bitFieldName; - } - - /* - * Getters. - */ - public int getBitFieldNo() { return fBitFieldNo; } - public String getName() { return fBitFieldName; } - - /* - * Required common manipulation routines. - */ - @Override - public boolean equals(Object other) { - if (other instanceof MIBitFieldDMC) { - - MIBitFieldDMC dmc = (MIBitFieldDMC) other; - - return( (super.baseEquals(other)) && - (dmc.fBitFieldNo == fBitFieldNo) && - (dmc.fBitFieldName.equals(fBitFieldName))); - } else { - return false; - } - } - - @Override - public int hashCode() { return super.baseHashCode() + fBitFieldName.hashCode(); } - @Override - public String toString() { return baseToString() + ".BitField[" + fBitFieldNo + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ - } - - static class RegisterGroupData implements IRegisterGroupDMData { - - private String fGrpName; - private String fGrpDesc; - - public RegisterGroupData( String grpName, String desc ) { - fGrpName = grpName; - fGrpDesc = desc; - } - public String getName() { return fGrpName; } - public String getDescription() { return fGrpDesc; } - } - - static class RegisterData implements IRegisterDMData { - - private String fRegName; - private String fRegDesc; - private boolean fIsFloat; - private boolean fIsWriteable; - - public RegisterData(String regName, String regDesc, boolean isFloat, boolean isWriteable ) { - - fRegName = regName; - fRegDesc = regDesc; - fIsFloat = isFloat; - fIsWriteable = isWriteable; - } - - public boolean isReadable() { return true; } - public boolean isReadOnce() { return false; } - public boolean isWriteable() { return fIsWriteable; } - public boolean isWriteOnce() { return false; } - public boolean hasSideEffects() { return false; } - public boolean isVolatile() { return true; } - - public boolean isFloat() { return fIsFloat; } - public String getName() { return fRegName; } - public String getDescription() { return fRegDesc; } - } - - /* - * Used to create the a list of register data model contexts given a string list. - */ - private MIRegisterDMC[] makeRegisterDMCs(MIRegisterGroupDMC groupDmc, String[] regNames) { - return makeRegisterDMCs(groupDmc, null, regNames); - } - - /* - * Used to create the a list of register data model contexts given a string list. - */ - private MIRegisterDMC[] makeRegisterDMCs(MIRegisterGroupDMC groupDmc, IExecutionDMContext execDmc, String[] regNames) { - MIRegisterDMC[] regDmcList = new MIRegisterDMC[regNames.length]; - int regNo = 0 ; - for (String regName : regNames) { - if(execDmc != null) - regDmcList[regNo] = new MIRegisterDMC(this, groupDmc, execDmc, regNo, regName); - else - regDmcList[regNo] = new MIRegisterDMC(this, groupDmc, regNo, regName); - regNo++; - } - - return regDmcList; - } - - private class BitGroupData implements IBitGroup { - - private int fStartBit = 0; - private int fBitCount = 0; - - public void setStartBit( int startbit ) { - fStartBit = startbit; - } - - public void setBitCount( int bitcount ) { - fBitCount = bitcount; - } - - public int startBit() { return fStartBit; } - public int bitCount() { return fBitCount; } - } - - private class MnemonicData implements IMnemonic { - - private String fShortName; - private String fLongName; - private BigInteger fValue; - private int fNumBits; - - public void setShortName( String name ) { fShortName = name; } - public void setLongName( String name ) { fLongName = name; } - public void setValue( BigInteger value ) { fValue = value; } - public void setNumBits( int numBits ) { fNumBits = numBits; } - - public String getShortName() { return fShortName; } - public String getLongName() { return fLongName; } - - public BigInteger getValue() { return fValue; } - public int getBitCount() { return fNumBits; } - - @Override - public boolean equals( Object element ) { - if ( element instanceof MnemonicData ) { - MnemonicData mnem = (MnemonicData) element; - return ( mnem.fShortName.equals( fShortName ) ) && - ( mnem.fLongName.equals( fLongName ) ) && - ( mnem.fValue.equals( fValue ) ) && - ( mnem.fNumBits == fNumBits ); - } - return false ; - } - } - - private class BitFieldData implements IBitFieldDMData { - - private String fRegName; - private String fDesc; - private IBitGroup[] fBitGroups; - private IMnemonic[] fMnemonics; - private boolean fIsZeroBasedNumbering; - private boolean fIsZeroBitLeftMost; - private boolean fIsReadable; - private boolean fIsReadOnce; - private boolean fIsWriteable; - private boolean fIsWriteOnce; - private boolean fHasSideEffects; - private boolean fIsFloat; - private BigInteger fValue; - - public BitFieldData(String regName, String desc, BigInteger value, - boolean isZeroBasedNumbering, boolean isZeroBitLeftMost, boolean isReadable, - boolean isReadOnce, boolean isWriteable, boolean isWriteOnce, - boolean hasSideEffects, boolean isFloat ) { - - fRegName = regName; - fDesc = desc; - fValue = value; - fIsZeroBasedNumbering = isZeroBasedNumbering; - fIsZeroBitLeftMost = isZeroBitLeftMost; - fIsReadable = isReadable; - fIsReadOnce = isReadOnce; - fIsWriteable = isWriteable; - fIsWriteOnce = isWriteOnce; - fHasSideEffects = hasSideEffects; - fIsFloat = isFloat; - } - - public void addBitGroups( IBitGroup[] groups ) { fBitGroups = groups; } - public void addMnemonics( IMnemonic[] mnemonics ) { fMnemonics = mnemonics; } - - public IBitGroup[] getBitGroup() { return fBitGroups; } - public IMnemonic[] getMnemonics() { return fMnemonics; } - - public boolean isZeroBasedNumbering() { return fIsZeroBasedNumbering; } - public boolean isZeroBitLeftMost() { return fIsZeroBitLeftMost; } - public boolean isReadable() { return fIsReadable; } - public boolean isReadOnce() { return fIsReadOnce; } - public boolean isWriteable() { return fIsWriteable; } - public boolean isWriteOnce() { return fIsWriteOnce; } - public boolean hasSideEffects() { return fHasSideEffects; } - public boolean isFloat() { return fIsFloat; } - - public String getName() { return fRegName; } - public String getDescription() { return fDesc; } - - public IMnemonic getCurrentMnemonicValue() { - - for ( IMnemonic mnem : fMnemonics ) { - if ( ((MnemonicData) mnem).fValue.equals( fValue ) ){ - return mnem; - } - } - return null; - } - } - - /* - * Event handling section. These event handlers control the caching state of the - * register caches. This service creates several cache objects. Not all of which - * need to be flushed. These handlers maintain the state of the caches. - */ - - public static class RegisterChangedDMEvent implements IRegisters.IRegisterChangedDMEvent { - - private final IRegisterDMContext fRegisterDmc; - - RegisterChangedDMEvent(IRegisterDMContext registerDMC) { - fRegisterDmc = registerDMC; - } - - public IRegisterDMContext getDMContext() { - return fRegisterDmc; - } - } @DsfServiceEventHandler public void eventDispatched(IRunControl.IResumedDMEvent e) { @@ -1047,8 +538,14 @@ public class PDARegisters extends AbstractDsfService implements IRegisters { public void eventDispatched(final IRegisters.IRegisterChangedDMEvent e) { } - @SuppressWarnings("unused") - private void generateRegisterChangedEvent(IRegisterDMContext dmc ) { + private void generateRegisterChangedEvent(RegisterDMContext dmc ) { getSession().dispatchEvent(new RegisterChangedDMEvent(dmc), getProperties()); } + + public void eventReceived(Object output) { + if (!(output instanceof String)) return; + if ("registers".equals(output)) { + fNamesCache.reset(); + } + } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java index daddf809821..1ec0d4696fd 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/PDAStack.java @@ -445,6 +445,13 @@ public class PDAStack extends AbstractDsfService implements IStack2 { PDAPlugin.failRequest(rm, IDsfStatusConstants.INVALID_HANDLE, "Unknown context type"); } } + + /** + * Returns a frame context for the given thread and level; + */ + public IFrameDMContext getFrameDMContext(PDAThreadDMContext thread, int level) { + return new FrameDMContext(getSession().getId(), thread, level); + } @DsfServiceEventHandler public void eventDispatched(IResumedDMEvent e) { @@ -452,7 +459,7 @@ public class PDAStack extends AbstractDsfService implements IStack2 { // fail. Also reset the cache unless it was a step command. fCommandCache.setContextAvailable(e.getDMContext(), false); if (!e.getReason().equals(StateChangeReason.STEP)) { - fCommandCache.reset(); + fCommandCache.reset(e.getDMContext()); } } @@ -461,6 +468,6 @@ public class PDAStack extends AbstractDsfService implements IStack2 { public void eventDispatched(ISuspendedDMEvent e) { // Enable sending commands to target and clear the cache. fCommandCache.setContextAvailable(e.getDMContext(), true); - fCommandCache.reset(); + fCommandCache.reset(e.getDMContext()); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDABitField.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDABitField.java new file mode 100644 index 00000000000..9140ee6e543 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDABitField.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.commands; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.StringTokenizer; + +import org.eclipse.dd.dsf.concurrent.Immutable; + +/** + * Object representing a bit field in the stack command results. + * + * @see PDARegistersCommand + */ +@Immutable +public class PDABitField { + + final public String fName; + final public int fOffset; + final public int fCount; + final public Map fMnemonics; + + PDABitField(String bitFieldString) { + StringTokenizer st = new StringTokenizer(bitFieldString, " "); + + fName = st.nextToken(); + fOffset = Integer.parseInt(st.nextToken()); + fCount = Integer.parseInt(st.nextToken()); + + fMnemonics = new LinkedHashMap(0); + while (st.hasMoreTokens()) { + fMnemonics.put(st.nextToken(), st.nextToken()); + } + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAChildrenCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAChildrenCommand.java new file mode 100644 index 00000000000..45f3cb615cc --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAChildrenCommand.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.commands; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.examples.pda.service.PDAThreadDMContext; + +/** + * Retrieves data stack information + * + *
+ *    C: children {thread_id} {frame_id} {variable_name}
+ *    R: {child variable 1}|{child variable 2}|{child variable 3}|...|
+ *    
+ * Errors:
+ *    error: invalid thread
+ * 
+ */ +@Immutable +public class PDAChildrenCommand extends AbstractPDACommand { + + public PDAChildrenCommand(PDAThreadDMContext thread, int frameId, String name ) { + super(thread, "children " + thread.getID() + " " + frameId + " " + name); + } + + @Override + public PDAListResult createResult(String resultText) { + return new PDAListResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java index 37ff5c84deb..cca355cd843 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommand.java @@ -25,14 +25,14 @@ import org.eclipse.dd.examples.pda.service.PDAThreadDMContext; * */ @Immutable -public class PDADataCommand extends AbstractPDACommand { +public class PDADataCommand extends AbstractPDACommand { public PDADataCommand(PDAThreadDMContext thread) { super(thread, "data " + thread.getID()); } @Override - public PDADataCommandResult createResult(String resultText) { - return new PDADataCommandResult(resultText); + public PDAListResult createResult(String resultText) { + return new PDAListResult(resultText); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAGroupsCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAGroupsCommand.java new file mode 100644 index 00000000000..d34be6c75c9 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAGroupsCommand.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.commands; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.examples.pda.service.PDAVirtualMachineDMContext; + +/** + * Retrieves register groups information + * + *
+ *    C: groups
+ *    R: {group 1}|{group 2}|{group 3}|...|
+ * 
+ */ +@Immutable +public class PDAGroupsCommand extends AbstractPDACommand { + + public PDAGroupsCommand(PDAVirtualMachineDMContext context) { + super(context, "groups"); + } + + @Override + public PDAListResult createResult(String resultText) { + return new PDAListResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAListResult.java similarity index 89% rename from plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java rename to plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAListResult.java index aff431a7ec6..f24108a40b1 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDADataCommandResult.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDAListResult.java @@ -21,11 +21,11 @@ import org.eclipse.dd.dsf.concurrent.Immutable; * @see PDADataCommand */ @Immutable -public class PDADataCommandResult extends PDACommandResult { +public class PDAListResult extends PDACommandResult { final public String[] fValues; - PDADataCommandResult(String response) { + PDAListResult(String response) { super(response); StringTokenizer st = new StringTokenizer(response, "|"); List valuesList = new ArrayList(); @@ -33,7 +33,7 @@ public class PDADataCommandResult extends PDACommandResult { while (st.hasMoreTokens()) { String token = st.nextToken(); if (token.length() != 0) { - valuesList.add(st.nextToken()); + valuesList.add(token); } } diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDARegister.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDARegister.java new file mode 100644 index 00000000000..ebdbd1a723f --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDARegister.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.commands; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +import org.eclipse.dd.dsf.concurrent.Immutable; + +/** + * Object representing a register in the registers command results. + * + * @see PDARCommand + */ +@Immutable +public class PDARegister { + + final public String fName; + final public boolean fWritable; + final public PDABitField[] fBitFields; + + PDARegister(String regString) { + StringTokenizer st = new StringTokenizer(regString, "|"); + + String regInfo = st.nextToken(); + StringTokenizer regSt = new StringTokenizer(regInfo, " "); + fName = regSt.nextToken(); + fWritable = Boolean.parseBoolean(regSt.nextToken()); + + List bitFieldsList = new ArrayList(); + while (st.hasMoreTokens()) { + bitFieldsList.add(new PDABitField(st.nextToken())); + } + fBitFields = bitFieldsList.toArray(new PDABitField[bitFieldsList.size()]); + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDARegistersCommand.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDARegistersCommand.java new file mode 100644 index 00000000000..3b5297f46ba --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDARegistersCommand.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.commands; + +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.examples.pda.service.PDAThreadDMContext; + +/** + * Retrieves registers definition information + * + *
+ *    C: registers {group name}
+ *    R: {register name} {true|false}|{bit field name} {start bit} {bit count} {mnemonic 1} {mnemonic 2} ...#{register name} ...
+ * 
+ */ +@Immutable +public class PDARegistersCommand extends AbstractPDACommand { + + public PDARegistersCommand(PDAThreadDMContext context, String group) { + super(context, "registers " + group); + } + + @Override + public PDARegistersCommandResult createResult(String resultText) { + return new PDARegistersCommandResult(resultText); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDARegistersCommandResult.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDARegistersCommandResult.java new file mode 100644 index 00000000000..a259b36e9cd --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/service/commands/PDARegistersCommandResult.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pda.service.commands; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +import org.eclipse.dd.dsf.concurrent.Immutable; + + +/** + * @see PDARegistersCommand + */ +@Immutable +public class PDARegistersCommandResult extends PDACommandResult { + + /** + * Array of registers returned by the registers commands. + */ + final public PDARegister[] fRegisters; + + PDARegistersCommandResult(String response) { + super(response); + StringTokenizer st = new StringTokenizer(response, "#"); + List regList = new ArrayList(); + + while (st.hasMoreTokens()) { + regList.add(new PDARegister(st.nextToken())); + } + fRegisters = regList.toArray(new PDARegister[regList.size()]); + } +} diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test10.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test10.java new file mode 100644 index 00000000000..283341e70f4 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test10.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.tests.pda.service.command; + +import java.io.File; + +import org.eclipse.core.runtime.Path; +import org.eclipse.dd.examples.pda.PDAPlugin; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * + */ +public class Test10 extends CommandControlTestsBase { + + @BeforeClass + public static void setProgram() { + File programFile = PDAPlugin.getFileInPlugin(new Path("pdavm/tests/vmtest10.pda")); + + fProgram = programFile.getPath(); + } + + @Test + public void testRegisters() throws Throwable { + expectEvent("started 1"); + // run to the end of register definitions + sendCommand("set 10 1"); + sendCommand("vmresume"); + expectEvent("vmresumed client"); + expectEvent("registers"); + expectEvent("registers"); + expectEvent("registers"); + expectEvent("registers"); + expectEvent("registers"); + expectEvent("registers"); + expectEvent("registers"); + expectEvent("registers"); + expectEvent("registers"); + expectEvent("vmsuspended 1 breakpoint 10"); + + // Test the definitions commands + sendCommand("groups", "group1|group2|"); + sendCommand("registers group1", "reg1 true|field1 0 2 |field2 2 2 zero 0 one 1 two 2 three 3 #reg2 false#"); + sendCommand("registers group2", "reg3 true#"); + + // Run to the end of the program + sendCommand("set 37 1"); + sendCommand("vmresume"); + expectEvent("vmresumed client"); + expectOutput("1"); + expectOutput("2"); + expectOutput("0"); + expectOutput("4"); + expectOutput("0"); + expectOutput("0"); + expectOutput("2"); + expectOutput("8"); + expectEvent("vmsuspended 1 breakpoint 37"); + + // Test var get/set commands + sendCommand("var 1 1 $reg1", "8"); + sendCommand("var 1 1 $reg1.field1", "0"); + sendCommand("var 1 1 $reg1.field2", "2"); + sendCommand("setvar 1 1 $reg1.field2 3"); + sendCommand("var 1 1 $reg1.field2", "3"); + sendCommand("setvar 1 1 $reg1 1"); + sendCommand("var 1 1 $reg1", "1"); + + // exit + sendCommand("exit"); + expectEvent("terminated"); + } +}