mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-30 04:15:35 +02:00
[244435] - Added registers to the PDA debugger exmple.
This commit is contained in:
parent
938067e4ce
commit
eeba5abcba
17 changed files with 1344 additions and 993 deletions
|
@ -19,12 +19,14 @@ import java.io.PrintStream;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
import java.util.TreeSet;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -34,16 +36,41 @@ import java.util.regex.Pattern;
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class PDAVirtualMachine {
|
public class PDAVirtualMachine {
|
||||||
|
|
||||||
class Stack extends LinkedList<Object> {
|
static class Stack extends LinkedList<Object> {
|
||||||
|
@Override
|
||||||
public Object pop() {
|
public Object pop() {
|
||||||
return isEmpty() ? 0 : remove(size() - 1);
|
return isEmpty() ? 0 : remove(size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void push(Object value) {
|
public void push(Object value) {
|
||||||
add(value);
|
add(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class Register {
|
||||||
|
Register(String name) {
|
||||||
|
fName = name;
|
||||||
|
}
|
||||||
|
String fName;
|
||||||
|
String fGroup = "<no_group>";
|
||||||
|
boolean fIsWriteable = true;
|
||||||
|
Map<String, BitField> fBitFields = new LinkedHashMap<String, BitField>(0);
|
||||||
|
int fValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class BitField {
|
||||||
|
BitField(String name) {
|
||||||
|
fName = name;
|
||||||
|
}
|
||||||
|
String fName;
|
||||||
|
int fBitOffset;
|
||||||
|
int fBitCount;
|
||||||
|
Map<String, Integer> fMnemonics = new LinkedHashMap<String, Integer>(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String,Register> fRegisters = new LinkedHashMap<String,Register>(0);
|
||||||
|
|
||||||
class Args {
|
class Args {
|
||||||
final String[] fArgs;
|
final String[] fArgs;
|
||||||
|
|
||||||
|
@ -69,6 +96,15 @@ public class PDAVirtualMachine {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean getNextBooleanArg() {
|
||||||
|
String arg = getNextStringArg();
|
||||||
|
try {
|
||||||
|
return Boolean.parseBoolean(arg);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Object getNextIntOrStringArg() {
|
Object getNextIntOrStringArg() {
|
||||||
String arg = getNextStringArg();
|
String arg = getNextStringArg();
|
||||||
try {
|
try {
|
||||||
|
@ -133,7 +169,7 @@ public class PDAVirtualMachine {
|
||||||
|
|
||||||
int fNextThreadId = 1;
|
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
|
* The code is stored as an array of strings, each line of the source file
|
||||||
* being one entry in the array.
|
* being one entry in the array.
|
||||||
|
@ -144,7 +180,9 @@ public class PDAVirtualMachine {
|
||||||
final Map<String, Integer> fLabels;
|
final Map<String, Integer> fLabels;
|
||||||
|
|
||||||
/** Each stack frame is a mapping of variable names to values. */
|
/** Each stack frame is a mapping of variable names to values. */
|
||||||
class Frame extends LinkedHashMap<String, Object> {
|
class Frame {
|
||||||
|
final Map<String, Object> fLocalVariables = new LinkedHashMap<String, Object>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the function in this frame
|
* The name of the function in this frame
|
||||||
*/
|
*/
|
||||||
|
@ -160,8 +198,63 @@ public class PDAVirtualMachine {
|
||||||
fFunction = function;
|
fFunction = function;
|
||||||
fPC = pc;
|
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
|
* Breakpoints are stored per each each line of code. The boolean indicates
|
||||||
* whether the whole VM should suspend or just the triggering thread.
|
* 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];
|
String instruction = thread.fThreadCode[thread.fCurrentFrame.fPC];
|
||||||
thread.fCurrentFrame.fPC++;
|
thread.fCurrentFrame.fPC++;
|
||||||
doOneInstruction(thread, instruction);
|
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 reached end of code, exit from the thread.
|
||||||
thread.fRun = false;
|
thread.fRun = false;
|
||||||
} else if (thread.fStepReturn) {
|
} 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("branch_not_zero")) iBranchNotZero(thread, args);
|
||||||
else if (op.equals("call")) iCall(thread, args);
|
else if (op.equals("call")) iCall(thread, args);
|
||||||
else if (op.equals("dec")) iDec(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("dup")) iDup(thread, args);
|
||||||
else if (op.equals("exec")) iExec(thread, args);
|
else if (op.equals("exec")) iExec(thread, args);
|
||||||
else if (op.equals("halt")) iHalt(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()]));
|
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 ("data".equals(command)) debugData(args);
|
||||||
else if ("drop".equals(command)) debugDropFrame(args);
|
else if ("drop".equals(command)) debugDropFrame(args);
|
||||||
else if ("eval".equals(command)) debugEval(args);
|
else if ("eval".equals(command)) debugEval(args);
|
||||||
else if ("eventstop".equals(command)) debugEventStop(args);
|
else if ("eventstop".equals(command)) debugEventStop(args);
|
||||||
else if ("exit".equals(command)) debugExit();
|
else if ("exit".equals(command)) debugExit();
|
||||||
else if ("frame".equals(command)) debugFrame(args);
|
else if ("frame".equals(command)) debugFrame(args);
|
||||||
|
else if ("groups".equals(command)) debugGroups(args);
|
||||||
else if ("popdata".equals(command)) debugPop(args);
|
else if ("popdata".equals(command)) debugPop(args);
|
||||||
else if ("pushdata".equals(command)) debugPush(args);
|
else if ("pushdata".equals(command)) debugPush(args);
|
||||||
|
else if ("registers".equals(command)) debugRegisters(args);
|
||||||
else if ("resume".equals(command)) debugResume(args);
|
else if ("resume".equals(command)) debugResume(args);
|
||||||
else if ("set".equals(command)) debugSetBreakpoint(args);
|
else if ("set".equals(command)) debugSetBreakpoint(args);
|
||||||
else if ("setdata".equals(command)) debugSetData(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<String> children = new ArrayList<String>();
|
||||||
|
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) {
|
void debugClearBreakpoint(Args args) {
|
||||||
int line = args.getNextIntArg();
|
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])");
|
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) {
|
void debugEval(Args args) {
|
||||||
if (fSuspendVM != null) {
|
if (fSuspendVM != null) {
|
||||||
sendCommandResponse("error: cannot evaluate while vm is suspended\n");
|
sendCommandResponse("error: cannot evaluate while vm is suspended\n");
|
||||||
|
@ -665,43 +830,6 @@ public class PDAVirtualMachine {
|
||||||
sendDebugEvent("resumed " + thread.fID + " eval", false);
|
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) {
|
void debugEventStop(Args args) {
|
||||||
String event = args.getNextStringArg();
|
String event = args.getNextStringArg();
|
||||||
int stop = args.getNextIntArg();
|
int stop = args.getNextIntArg();
|
||||||
|
@ -732,6 +860,20 @@ public class PDAVirtualMachine {
|
||||||
sendCommandResponse(printFrame(frame) + "\n");
|
sendCommandResponse(printFrame(frame) + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void debugGroups(Args args) {
|
||||||
|
TreeSet<String> groups = new TreeSet<String>();
|
||||||
|
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) {
|
void debugPop(Args args) {
|
||||||
PDAThread thread = args.getThreadArg();
|
PDAThread thread = args.getThreadArg();
|
||||||
if (thread == null) {
|
if (thread == null) {
|
||||||
|
@ -755,6 +897,38 @@ public class PDAVirtualMachine {
|
||||||
sendCommandResponse("ok\n");
|
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<String, Integer> 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) {
|
void debugResume(Args args) {
|
||||||
PDAThread thread = args.getThreadArg();
|
PDAThread thread = args.getThreadArg();
|
||||||
if (thread == null) {
|
if (thread == null) {
|
||||||
|
@ -814,9 +988,9 @@ public class PDAVirtualMachine {
|
||||||
Object val = args.getNextIntOrStringArg();
|
Object val = args.getNextIntOrStringArg();
|
||||||
|
|
||||||
if (sfnumber >= thread.fFrames.size()) {
|
if (sfnumber >= thread.fFrames.size()) {
|
||||||
thread.fCurrentFrame.put(var, val);
|
thread.fCurrentFrame.set(var, val);
|
||||||
} else {
|
} else {
|
||||||
thread.fFrames.get(sfnumber).put(var, val);
|
thread.fFrames.get(sfnumber).set(var, val);
|
||||||
}
|
}
|
||||||
sendCommandResponse("ok\n");
|
sendCommandResponse("ok\n");
|
||||||
}
|
}
|
||||||
|
@ -859,9 +1033,11 @@ public class PDAVirtualMachine {
|
||||||
buf.append(frame.fPC);
|
buf.append(frame.fPC);
|
||||||
buf.append('|');
|
buf.append('|');
|
||||||
buf.append(frame.fFunction);
|
buf.append(frame.fFunction);
|
||||||
for (String var : frame.keySet()) {
|
for (String var : frame.fLocalVariables.keySet()) {
|
||||||
buf.append('|');
|
if (var.indexOf('.') == -1) {
|
||||||
buf.append(var);
|
buf.append('|');
|
||||||
|
buf.append(var);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
@ -1062,6 +1238,52 @@ public class PDAVirtualMachine {
|
||||||
thread.fStack.push(val);
|
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) {
|
void iDup(PDAThread thread, Args args) {
|
||||||
Object val = thread.fStack.pop();
|
Object val = thread.fStack.pop();
|
||||||
thread.fStack.push(val);
|
thread.fStack.push(val);
|
||||||
|
@ -1095,7 +1317,7 @@ public class PDAVirtualMachine {
|
||||||
String arg = args.getNextStringArg();
|
String arg = args.getNextStringArg();
|
||||||
if (arg.startsWith("$")) {
|
if (arg.startsWith("$")) {
|
||||||
String var = arg.substring(1);
|
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;
|
String key = thread.fCurrentFrame.fFunction + "::" + var;
|
||||||
if (fWatchpoints.containsKey(key) && (fWatchpoints.get(key) & 2) != 0) {
|
if (fWatchpoints.containsKey(key) && (fWatchpoints.get(key) & 2) != 0) {
|
||||||
fSuspendVM = thread.fID + " watch write " + key;
|
fSuspendVM = thread.fID + " watch write " + key;
|
||||||
|
@ -1107,21 +1329,26 @@ public class PDAVirtualMachine {
|
||||||
|
|
||||||
void iPush(PDAThread thread, Args args) {
|
void iPush(PDAThread thread, Args args) {
|
||||||
String arg = args.getNextStringArg();
|
String arg = args.getNextStringArg();
|
||||||
if (arg.startsWith("$")) {
|
while (arg.length() != 0) {
|
||||||
String var = arg.substring(1);
|
if (arg.startsWith("$")) {
|
||||||
Object val = thread.fCurrentFrame.containsKey(var) ? thread.fCurrentFrame.get(var) : "<undefined>";
|
String var = arg.substring(1);
|
||||||
thread.fStack.push(val);
|
Object val = thread.fCurrentFrame.get(var);
|
||||||
String key = thread.fCurrentFrame.fFunction + "::" + var;
|
if (val == null) val = "<undefined>";
|
||||||
if (fWatchpoints.containsKey(key) && (fWatchpoints.get(key) & 1) != 0) {
|
thread.fStack.push(val);
|
||||||
fSuspendVM = thread.fID + " watch read " + key;
|
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;
|
arg = args.getNextStringArg();
|
||||||
try {
|
|
||||||
val = Integer.parseInt(arg);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
}
|
|
||||||
thread.fStack.push(val);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1137,7 +1364,7 @@ public class PDAVirtualMachine {
|
||||||
|
|
||||||
void iVar(PDAThread thread, Args args) {
|
void iVar(PDAThread thread, Args args) {
|
||||||
String var = args.getNextStringArg();
|
String var = args.getNextStringArg();
|
||||||
thread.fCurrentFrame.put(var, 0);
|
thread.fCurrentFrame.set(var, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iInternalEndEval(PDAThread thread, Args args) {
|
void iInternalEndEval(PDAThread thread, Args args) {
|
||||||
|
|
38
plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest10.pda
Normal file
38
plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtest10.pda
Normal file
|
@ -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
|
|
@ -0,0 +1,8 @@
|
||||||
|
var a
|
||||||
|
var a.b
|
||||||
|
var a.c
|
||||||
|
push 1
|
||||||
|
pop $a.b
|
||||||
|
push $a.b
|
||||||
|
output
|
||||||
|
halt
|
72
plugins/org.eclipse.dd.examples.pda/samples/registers.pda
Normal file
72
plugins/org.eclipse.dd.examples.pda/samples/registers.pda
Normal file
|
@ -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
|
|
@ -1,8 +1,23 @@
|
||||||
push one two three
|
push one two three
|
||||||
push 1 2 3
|
push 1 2 3
|
||||||
|
push I II III
|
||||||
var x
|
var x
|
||||||
|
var x.a
|
||||||
|
var x.b
|
||||||
var y
|
var y
|
||||||
|
var y.c
|
||||||
|
var y.d
|
||||||
|
var y.d.1
|
||||||
|
var y.d.2
|
||||||
|
var y.d.3
|
||||||
pop $x
|
pop $x
|
||||||
|
pop $x.a
|
||||||
|
pop $x.b
|
||||||
pop $y
|
pop $y
|
||||||
|
pop $y.c
|
||||||
|
pop $y.d
|
||||||
|
pop $y.d.1
|
||||||
|
pop $y.d.2
|
||||||
|
pop $y.d.3
|
||||||
push Done
|
push Done
|
||||||
output
|
output
|
|
@ -21,7 +21,6 @@ import org.eclipse.dd.dsf.datamodel.AbstractDMEvent;
|
||||||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||||
import org.eclipse.dd.dsf.debug.service.IExpressions;
|
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.IRegisters.IRegisterDMContext;
|
||||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent;
|
import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent;
|
||||||
import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
|
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.DsfServiceEventHandler;
|
||||||
import org.eclipse.dd.dsf.service.DsfSession;
|
import org.eclipse.dd.dsf.service.DsfSession;
|
||||||
import org.eclipse.dd.examples.pda.PDAPlugin;
|
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.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.PDASetVarCommand;
|
||||||
import org.eclipse.dd.examples.pda.service.commands.PDAVarCommand;
|
import org.eclipse.dd.examples.pda.service.commands.PDAVarCommand;
|
||||||
import org.osgi.framework.BundleContext;
|
import org.osgi.framework.BundleContext;
|
||||||
|
@ -163,7 +164,7 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions {
|
||||||
|
|
||||||
|
|
||||||
private PDACommandControl fCommandControl;
|
private PDACommandControl fCommandControl;
|
||||||
private IStack fStack;
|
private PDAStack fStack;
|
||||||
|
|
||||||
private CommandCache fCommandCache;
|
private CommandCache fCommandCache;
|
||||||
|
|
||||||
|
@ -188,7 +189,7 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions {
|
||||||
|
|
||||||
private void doInitialize(final RequestMonitor rm) {
|
private void doInitialize(final RequestMonitor rm) {
|
||||||
fCommandControl = getServicesTracker().getService(PDACommandControl.class);
|
fCommandControl = getServicesTracker().getService(PDACommandControl.class);
|
||||||
fStack = getServicesTracker().getService(IStack.class);
|
fStack = getServicesTracker().getService(PDAStack.class);
|
||||||
fCommandCache = new CommandCache(getSession(), fCommandControl);
|
fCommandCache = new CommandCache(getSession(), fCommandControl);
|
||||||
|
|
||||||
getSession().addServiceEventListener(this, null);
|
getSession().addServiceEventListener(this, null);
|
||||||
|
@ -212,19 +213,23 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions {
|
||||||
|
|
||||||
public IExpressionDMContext createExpression(IDMContext ctx, String expression) {
|
public IExpressionDMContext createExpression(IDMContext ctx, String expression) {
|
||||||
// Create an expression based on the given context and 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);
|
PDAThreadDMContext threadCtx = DMContexts.getAncestorOfType(ctx, PDAThreadDMContext.class);
|
||||||
IFrameDMContext frameCtx = DMContexts.getAncestorOfType(ctx, IFrameDMContext.class);
|
if (threadCtx != null) {
|
||||||
if (threadCtx != null && frameCtx != 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);
|
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.
|
// If the thread cannot be found in context, return an "invalid"
|
||||||
// Evaluating an invalid expression context will always yield an
|
// expression context, because a null return value is not allowed.
|
||||||
// error.
|
// Evaluating an invalid expression context will always yield an
|
||||||
return new InvalidExpressionDMContext(getSession().getId(), ctx, expression);
|
// error.
|
||||||
}
|
return new InvalidExpressionDMContext(getSession().getId(), ctx, expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getBaseExpressions(IExpressionDMContext exprContext, DataRequestMonitor<IExpressionDMContext[]> rm) {
|
public void getBaseExpressions(IExpressionDMContext exprContext, DataRequestMonitor<IExpressionDMContext[]> rm) {
|
||||||
|
@ -246,25 +251,99 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getSubExpressionCount(IExpressionDMContext exprCtx, DataRequestMonitor<Integer> rm) {
|
public void getSubExpressionCount(final IExpressionDMContext exprCtx, final DataRequestMonitor<Integer> 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<Integer>(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<PDAListResult>(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<IExpressionDMContext[]> rm) {
|
public void getSubExpressions(IExpressionDMContext exprCtx, DataRequestMonitor<IExpressionDMContext[]> rm) {
|
||||||
PDAPlugin.failRequest(rm, NOT_SUPPORTED, "Not supported");
|
getSubExpressions(exprCtx, -1, -1, rm);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getSubExpressions(IExpressionDMContext exprCtx, int startIndex, int length,
|
public void getSubExpressions(final IExpressionDMContext exprCtx, final int startIndexArg, final int lengthArg,
|
||||||
DataRequestMonitor<IExpressionDMContext[]> rm)
|
final DataRequestMonitor<IExpressionDMContext[]> 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<Integer>(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<PDAListResult>(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<String[]> rm) {
|
public void getAvailableFormats(IFormattedDataDMContext dmc, final DataRequestMonitor<String[]> rm) {
|
||||||
// PDA debugger doesn't support formatting the expression. Natural
|
getFormattedExpressionValue(
|
||||||
// formatting is the only available option.
|
new FormattedValueDMContext(this, dmc, NATURAL_FORMAT),
|
||||||
rm.setData(new String[] { NATURAL_FORMAT });
|
new DataRequestMonitor<FormattedValueDMData>(getExecutor(), rm) {
|
||||||
rm.done();
|
@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) {
|
public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext exprCtx, String formatId) {
|
||||||
|
@ -275,6 +354,7 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions {
|
||||||
public void getFormattedExpressionValue(FormattedValueDMContext formattedCtx,
|
public void getFormattedExpressionValue(FormattedValueDMContext formattedCtx,
|
||||||
final DataRequestMonitor<FormattedValueDMData> rm)
|
final DataRequestMonitor<FormattedValueDMData> rm)
|
||||||
{
|
{
|
||||||
|
final String formatId = formattedCtx.getFormatID();
|
||||||
final ExpressionDMContext exprCtx = DMContexts.getAncestorOfType(formattedCtx, ExpressionDMContext.class);
|
final ExpressionDMContext exprCtx = DMContexts.getAncestorOfType(formattedCtx, ExpressionDMContext.class);
|
||||||
if (exprCtx != null) {
|
if (exprCtx != null) {
|
||||||
final PDAThreadDMContext threadCtx = DMContexts.getAncestorOfType(exprCtx, PDAThreadDMContext.class);
|
final PDAThreadDMContext threadCtx = DMContexts.getAncestorOfType(exprCtx, PDAThreadDMContext.class);
|
||||||
|
@ -296,21 +376,95 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions {
|
||||||
new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
|
new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
|
||||||
@Override
|
@Override
|
||||||
protected void handleSuccess() {
|
protected void handleSuccess() {
|
||||||
rm.setData(new FormattedValueDMData(getData().fResponseText));
|
if (NATURAL_FORMAT.equals(formatId) || STRING_FORMAT.equals(formatId)) {
|
||||||
rm.done();
|
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 {
|
} else {
|
||||||
PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid expression context " + formattedCtx);
|
PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid expression context " + formattedCtx);
|
||||||
rm.done();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeExpression(final IExpressionDMContext exprCtx, final String exprValue, String formatId,
|
public void writeExpression(final IExpressionDMContext exprCtx, final String exprValue, String formatId,
|
||||||
final RequestMonitor rm)
|
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) {
|
if (exprCtx instanceof ExpressionDMContext) {
|
||||||
final PDAThreadDMContext threadCtx = DMContexts.getAncestorOfType(exprCtx, PDAThreadDMContext.class);
|
final PDAThreadDMContext threadCtx = DMContexts.getAncestorOfType(exprCtx, PDAThreadDMContext.class);
|
||||||
final IFrameDMContext frameCtx = DMContexts.getAncestorOfType(exprCtx, IFrameDMContext.class);
|
final IFrameDMContext frameCtx = DMContexts.getAncestorOfType(exprCtx, IFrameDMContext.class);
|
||||||
|
@ -331,7 +485,13 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions {
|
||||||
new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
|
new DataRequestMonitor<PDACommandResult>(getExecutor(), rm) {
|
||||||
@Override
|
@Override
|
||||||
protected void handleSuccess() {
|
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();
|
rm.done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -339,7 +499,6 @@ public class PDAExpressions extends AbstractDsfService implements IExpressions {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
PDAPlugin.failRequest(rm, INVALID_HANDLE, "Invalid expression context " + exprCtx);
|
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<FormattedValueDMData>) rm);
|
getFormattedExpressionValue((FormattedValueDMContext) dmc, (DataRequestMonitor<FormattedValueDMData>) rm);
|
||||||
} else {
|
} else {
|
||||||
PDAPlugin.failRequest(rm, INVALID_HANDLE, "Unknown DMC type");
|
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.
|
// will fail. Also reset the cache unless it was a step command.
|
||||||
fCommandCache.setContextAvailable(e.getDMContext(), false);
|
fCommandCache.setContextAvailable(e.getDMContext(), false);
|
||||||
if (!e.getReason().equals(StateChangeReason.STEP)) {
|
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) {
|
public void eventDispatched(ISuspendedDMEvent e) {
|
||||||
// Enable sending commands to target and clear the cache.
|
// Enable sending commands to target and clear the cache.
|
||||||
fCommandCache.setContextAvailable(e.getDMContext(), true);
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -445,6 +445,13 @@ public class PDAStack extends AbstractDsfService implements IStack2 {
|
||||||
PDAPlugin.failRequest(rm, IDsfStatusConstants.INVALID_HANDLE, "Unknown context type");
|
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
|
@DsfServiceEventHandler
|
||||||
public void eventDispatched(IResumedDMEvent e) {
|
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.
|
// fail. Also reset the cache unless it was a step command.
|
||||||
fCommandCache.setContextAvailable(e.getDMContext(), false);
|
fCommandCache.setContextAvailable(e.getDMContext(), false);
|
||||||
if (!e.getReason().equals(StateChangeReason.STEP)) {
|
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) {
|
public void eventDispatched(ISuspendedDMEvent e) {
|
||||||
// Enable sending commands to target and clear the cache.
|
// Enable sending commands to target and clear the cache.
|
||||||
fCommandCache.setContextAvailable(e.getDMContext(), true);
|
fCommandCache.setContextAvailable(e.getDMContext(), true);
|
||||||
fCommandCache.reset();
|
fCommandCache.reset(e.getDMContext());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<String, String> 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<String, String>(0);
|
||||||
|
while (st.hasMoreTokens()) {
|
||||||
|
fMnemonics.put(st.nextToken(), st.nextToken());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* C: children {thread_id} {frame_id} {variable_name}
|
||||||
|
* R: {child variable 1}|{child variable 2}|{child variable 3}|...|
|
||||||
|
*
|
||||||
|
* Errors:
|
||||||
|
* error: invalid thread
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
@Immutable
|
||||||
|
public class PDAChildrenCommand extends AbstractPDACommand<PDAListResult> {
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,14 +25,14 @@ import org.eclipse.dd.examples.pda.service.PDAThreadDMContext;
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
@Immutable
|
@Immutable
|
||||||
public class PDADataCommand extends AbstractPDACommand<PDADataCommandResult> {
|
public class PDADataCommand extends AbstractPDACommand<PDAListResult> {
|
||||||
|
|
||||||
public PDADataCommand(PDAThreadDMContext thread) {
|
public PDADataCommand(PDAThreadDMContext thread) {
|
||||||
super(thread, "data " + thread.getID());
|
super(thread, "data " + thread.getID());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PDADataCommandResult createResult(String resultText) {
|
public PDAListResult createResult(String resultText) {
|
||||||
return new PDADataCommandResult(resultText);
|
return new PDAListResult(resultText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* C: groups
|
||||||
|
* R: {group 1}|{group 2}|{group 3}|...|
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
@Immutable
|
||||||
|
public class PDAGroupsCommand extends AbstractPDACommand<PDAListResult> {
|
||||||
|
|
||||||
|
public PDAGroupsCommand(PDAVirtualMachineDMContext context) {
|
||||||
|
super(context, "groups");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PDAListResult createResult(String resultText) {
|
||||||
|
return new PDAListResult(resultText);
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,11 +21,11 @@ import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||||
* @see PDADataCommand
|
* @see PDADataCommand
|
||||||
*/
|
*/
|
||||||
@Immutable
|
@Immutable
|
||||||
public class PDADataCommandResult extends PDACommandResult {
|
public class PDAListResult extends PDACommandResult {
|
||||||
|
|
||||||
final public String[] fValues;
|
final public String[] fValues;
|
||||||
|
|
||||||
PDADataCommandResult(String response) {
|
PDAListResult(String response) {
|
||||||
super(response);
|
super(response);
|
||||||
StringTokenizer st = new StringTokenizer(response, "|");
|
StringTokenizer st = new StringTokenizer(response, "|");
|
||||||
List<String> valuesList = new ArrayList<String>();
|
List<String> valuesList = new ArrayList<String>();
|
||||||
|
@ -33,7 +33,7 @@ public class PDADataCommandResult extends PDACommandResult {
|
||||||
while (st.hasMoreTokens()) {
|
while (st.hasMoreTokens()) {
|
||||||
String token = st.nextToken();
|
String token = st.nextToken();
|
||||||
if (token.length() != 0) {
|
if (token.length() != 0) {
|
||||||
valuesList.add(st.nextToken());
|
valuesList.add(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<PDABitField> bitFieldsList = new ArrayList<PDABitField>();
|
||||||
|
while (st.hasMoreTokens()) {
|
||||||
|
bitFieldsList.add(new PDABitField(st.nextToken()));
|
||||||
|
}
|
||||||
|
fBitFields = bitFieldsList.toArray(new PDABitField[bitFieldsList.size()]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* C: registers {group name}
|
||||||
|
* R: {register name} {true|false}|{bit field name} {start bit} {bit count} {mnemonic 1} {mnemonic 2} ...#{register name} ...
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
@Immutable
|
||||||
|
public class PDARegistersCommand extends AbstractPDACommand<PDARegistersCommandResult> {
|
||||||
|
|
||||||
|
public PDARegistersCommand(PDAThreadDMContext context, String group) {
|
||||||
|
super(context, "registers " + group);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PDARegistersCommandResult createResult(String resultText) {
|
||||||
|
return new PDARegistersCommandResult(resultText);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<PDARegister> regList = new ArrayList<PDARegister>();
|
||||||
|
|
||||||
|
while (st.hasMoreTokens()) {
|
||||||
|
regList.add(new PDARegister(st.nextToken()));
|
||||||
|
}
|
||||||
|
fRegisters = regList.toArray(new PDARegister[regList.size()]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue