mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 17:56:01 +02:00
Complete rewrite to not use the gdb/mi variable object
but rather the -data-list-register-xxx calls.
This commit is contained in:
parent
73a428b3f5
commit
e206d3b10f
2 changed files with 407 additions and 4 deletions
|
@ -5,14 +5,291 @@
|
|||
*/
|
||||
package org.eclipse.cdt.debug.mi.core.cdi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.eclipse.cdt.debug.core.cdi.CDIException;
|
||||
import org.eclipse.cdt.debug.core.cdi.ICDIRegisterObject;
|
||||
import org.eclipse.cdt.debug.core.cdi.model.ICDIRegister;
|
||||
import org.eclipse.cdt.debug.mi.core.output.MIVar;
|
||||
import org.eclipse.cdt.debug.core.cdi.model.ICDIValue;
|
||||
import org.eclipse.cdt.debug.core.cdi.model.ICDIVariable;
|
||||
import org.eclipse.cdt.debug.mi.core.MIException;
|
||||
import org.eclipse.cdt.debug.mi.core.MIFormat;
|
||||
import org.eclipse.cdt.debug.mi.core.MISession;
|
||||
import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
|
||||
import org.eclipse.cdt.debug.mi.core.command.MIDataListRegisterValues;
|
||||
import org.eclipse.cdt.debug.mi.core.output.MIDataListRegisterValuesInfo;
|
||||
import org.eclipse.cdt.debug.mi.core.output.MIRegisterValue;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class Register extends Variable implements ICDIRegister {
|
||||
public class Register extends CObject implements ICDIRegister, ICDIValue {
|
||||
|
||||
public Register(StackFrame frame, String name, MIVar var) {
|
||||
super(frame, name, var);
|
||||
RegisterObject regObject;
|
||||
int format = MIFormat.HEXADECIMAL;
|
||||
Register parent;
|
||||
String lastname;
|
||||
|
||||
/**
|
||||
* A container class to hold the values of the registers and sub values
|
||||
* for example on x86, xmm0 register is consider to be a struct
|
||||
* gdb/mi -data-list-register-values returns the value like this
|
||||
* value="{f = {0x0, 0x0, 0x0, 0x0}}"
|
||||
* we'll parse() it and change it to:
|
||||
* Argument[0] = { "xmm0", "{f = {0x0, 0x0, 0x0, 0x0}}"
|
||||
* Argument[1] = { "xmm0.f", "{0x0, 0x0, 0x0, 0x0}"}
|
||||
* Argument[2] = { "xmm0.f.0", "0x0"}
|
||||
* Argument[3] = { "xmm0.f.1", "0x0"}
|
||||
* Argument[4] = { "xmm0.f.2", "0x0"}
|
||||
* Argument[5] = { "xmm0.f.3", "0x0"}
|
||||
* see @parse()
|
||||
*/
|
||||
class Argument {
|
||||
String name;
|
||||
String val;
|
||||
Argument(String n, String v) {
|
||||
name = n;
|
||||
val = v;
|
||||
}
|
||||
String getKey() {
|
||||
return name;
|
||||
}
|
||||
String getValue() {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
public Register(CTarget target, ICDIRegisterObject r) {
|
||||
super(target);
|
||||
parent = null;
|
||||
lastname = r.getName();
|
||||
regObject = (RegisterObject)r;
|
||||
}
|
||||
|
||||
public Register(Register p, String n) {
|
||||
super(p.getCTarget());
|
||||
parent = p;
|
||||
lastname = n;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the MI regno.
|
||||
*/
|
||||
public int getId() {
|
||||
return regObject.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Unique name separated by '.' to describe the path
|
||||
* for example xmm0.f.0
|
||||
*/
|
||||
public String getUniqName() {
|
||||
String n = "";
|
||||
if (parent != null) {
|
||||
n = parent.getUniqName() + "." + getLastName();
|
||||
} else {
|
||||
n = getLastName();
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the register, for example xmm0.
|
||||
*/
|
||||
public String getBaseName() {
|
||||
String base = "";
|
||||
if (parent != null) {
|
||||
base = parent.getBaseName();
|
||||
} else {
|
||||
base = getLastName();
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current name for xmm0.f the last name is "f".
|
||||
*/
|
||||
public String getLastName() {
|
||||
return lastname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIVariable#getName()
|
||||
*/
|
||||
public String getName() throws CDIException {
|
||||
return getLastName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIVariable#getTypeName()
|
||||
*/
|
||||
public String getTypeName() throws CDIException {
|
||||
String v = getValueString();
|
||||
if (v.startsWith("{")) {
|
||||
// Use ptype?
|
||||
return "struct ";
|
||||
}
|
||||
return "int";
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIVariable#getValue()
|
||||
*/
|
||||
public ICDIValue getValue() throws CDIException {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIValue#getValueString()
|
||||
*/
|
||||
public String getValueString() throws CDIException {
|
||||
if (parent == null) {
|
||||
MISession mi = getCTarget().getCSession().getMISession();
|
||||
CommandFactory factory = mi.getCommandFactory();
|
||||
int[] regno = new int[]{((RegisterObject)regObject).getId()};
|
||||
MIDataListRegisterValues registers =
|
||||
factory.createMIDataListRegisterValues(format, regno);
|
||||
try {
|
||||
mi.postCommand(registers);
|
||||
MIDataListRegisterValuesInfo info =
|
||||
registers.getMIDataListRegisterValuesInfo();
|
||||
if (info == null) {
|
||||
throw new CDIException("No answer");
|
||||
}
|
||||
MIRegisterValue[] regValues = info.getMIRegisterValues();
|
||||
// We only ask for one. But do the right thing
|
||||
for (int i = 0; i < regValues.length; i++) {
|
||||
if (regValues[i].getNumber() == regno[i]) {
|
||||
return regValues[i].getValue();
|
||||
}
|
||||
}
|
||||
} catch (MIException e) {
|
||||
throw new CDIException(e.getMessage());
|
||||
}
|
||||
} else {
|
||||
String u = getUniqName();
|
||||
String v = parent.getValueString();
|
||||
Argument[] args = parse(parent.getUniqName(), v);
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (u.equals(args[i].getKey())) {
|
||||
return args[i].getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIVariable#isEditable()
|
||||
*/
|
||||
public boolean isEditable() throws CDIException {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIVariable#setValue(ICDIValue)
|
||||
*/
|
||||
public void setValue(ICDIValue val) throws CDIException {
|
||||
setValue(val.getValueString());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIVariable#setValue(String)
|
||||
*/
|
||||
public void setValue(String expression) throws CDIException {
|
||||
throw new CDIException("Register setting is not supported");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIVariable#setFormat()
|
||||
*/
|
||||
public void setFormat(int format) throws CDIException {
|
||||
format = Format.toMIFormat(format);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIValue#getChildrenNumber()
|
||||
*/
|
||||
public int getChildrenNumber() throws CDIException {
|
||||
return getVariables().length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIValue#getVariables()
|
||||
*/
|
||||
public ICDIVariable[] getVariables() throws CDIException {
|
||||
List aList = new ArrayList(1);
|
||||
String v = getValueString();
|
||||
Argument[] args = parse(getUniqName(), v);
|
||||
/* The idea here s to get the first level
|
||||
*
|
||||
* Argument[0] = { "xmm0", "{f = {0x0, 0x0, 0x0, 0x0}}"
|
||||
* Argument[1] = { "xmm0.f", "{0x0, 0x0, 0x0, 0x0}"}
|
||||
* Argument[2] = { "xmm0.f.0", "0x0"}
|
||||
* Argument[3] = { "xmm0.f.1", "0x0"}
|
||||
* Argument[4] = { "xmm0.f.2", "0x0"}
|
||||
* Argument[5] = { "xmm0.f.3", "0x0"}
|
||||
*
|
||||
* For example the children or xmm0.f are xmm0.f.{0,1,2,3,}
|
||||
*
|
||||
*/
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
String n = args[i].getKey();
|
||||
String u = getUniqName();
|
||||
if (n.startsWith(u) && n.length() > u.length()) {
|
||||
String p = n.substring(u.length());
|
||||
StringTokenizer st = new StringTokenizer(p, ".");
|
||||
if (st.countTokens() == 1) {
|
||||
aList.add(new Register(this, (String)st.nextElement()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return (ICDIVariable[])aList.toArray(new ICDIVariable[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIValue#hasChildren()
|
||||
*/
|
||||
public boolean hasChildren() throws CDIException {
|
||||
return getChildrenNumber() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* We are parsing this:
|
||||
* "{f = {0x0, 0x0, 0x0, 0x0}}"
|
||||
* into:
|
||||
* Argument[0] = { "xmm0", "{f = {0x0, 0x0, 0x0, 0x0}}"
|
||||
* Argument[1] = { "xmm0.f", "{0x0, 0x0, 0x0, 0x0}"}
|
||||
* Argument[2] = { "xmm0.f.0", "0x0"}
|
||||
* Argument[3] = { "xmm0.f.1", "0x0"}
|
||||
* Argument[4] = { "xmm0.f.2", "0x0"}
|
||||
* Argument[5] = { "xmm0.f.3", "0x0"}
|
||||
*/
|
||||
Argument[] parse(String base, String v) throws CDIException {
|
||||
List aList = new ArrayList(1);
|
||||
StringBuffer sb = new StringBuffer(base);
|
||||
aList.add(new Argument(sb.toString(), v.trim()));
|
||||
while (v.startsWith("{")) {
|
||||
int idx;
|
||||
v = v.substring(1);
|
||||
if (v.endsWith("}")) {
|
||||
idx = v.lastIndexOf('}');
|
||||
v = v.substring(0, idx);
|
||||
}
|
||||
idx = v.indexOf('=');
|
||||
if (idx != -1) {
|
||||
String n = v.substring(0, idx).trim();
|
||||
sb.append('.').append(n);
|
||||
v = v.substring(idx + 1).trim();
|
||||
aList.add(new Argument(sb.toString(), v));
|
||||
} else {
|
||||
StringTokenizer st = new StringTokenizer(v, ",");
|
||||
for (int i = 0; st.hasMoreElements(); i++) {
|
||||
aList.add(new Argument(sb.toString() + "." + Integer.toString(i), ((String)st.nextElement()).trim()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return (Argument[])aList.toArray(new Argument[0]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
*(c) Copyright QNX Software Systems Ltd. 2002.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
*/
|
||||
package org.eclipse.cdt.debug.mi.core.cdi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.debug.core.cdi.CDIException;
|
||||
import org.eclipse.cdt.debug.core.cdi.ICDIRegisterObject;
|
||||
import org.eclipse.cdt.debug.mi.core.MIException;
|
||||
import org.eclipse.cdt.debug.mi.core.MISession;
|
||||
import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
|
||||
import org.eclipse.cdt.debug.mi.core.command.MIDataListChangedRegisters;
|
||||
import org.eclipse.cdt.debug.mi.core.command.MIDataListRegisterNames;
|
||||
import org.eclipse.cdt.debug.mi.core.event.MIEvent;
|
||||
import org.eclipse.cdt.debug.mi.core.event.MIRegisterChangedEvent;
|
||||
import org.eclipse.cdt.debug.mi.core.output.MIDataListChangedRegistersInfo;
|
||||
import org.eclipse.cdt.debug.mi.core.output.MIDataListRegisterNamesInfo;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class RegisterManager extends SessionObject {
|
||||
|
||||
List regList;
|
||||
|
||||
public RegisterManager(CSession session) {
|
||||
super(session);
|
||||
regList = new ArrayList();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#getRegisterObjects()
|
||||
*/
|
||||
public ICDIRegisterObject[] getRegisterObjects() throws CDIException {
|
||||
MISession mi = getCSession().getMISession();
|
||||
CommandFactory factory = mi.getCommandFactory();
|
||||
MIDataListRegisterNames registers = factory.createMIDataListRegisterNames();
|
||||
try {
|
||||
mi.postCommand(registers);
|
||||
MIDataListRegisterNamesInfo info =
|
||||
registers.getMIDataListRegisterNamesInfo();
|
||||
if (info == null) {
|
||||
throw new CDIException("No answer");
|
||||
}
|
||||
String[] names = info.getRegisterNames();
|
||||
RegisterObject[] regs = new RegisterObject[names.length];
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
regs[i] = new RegisterObject(names[i], i);
|
||||
}
|
||||
return regs;
|
||||
} catch (MIException e) {
|
||||
throw new CDIException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
Register[] getRegisters() {
|
||||
return (Register[])regList.toArray(new Register[0]);
|
||||
}
|
||||
|
||||
Register getRegister(int regno) throws CDIException {
|
||||
Register[] regs = getRegisters();
|
||||
for (int i = 0; i < regs.length; i++) {
|
||||
if (regs[i].getId() == regno) {
|
||||
return regs[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Register getRegister(ICDIRegisterObject regObject) throws CDIException {
|
||||
Register[] regs = getRegisters();
|
||||
for (int i = 0; i < regs.length; i++) {
|
||||
if (regObject.getName().equals(regs[i].getName())) {
|
||||
return regs[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Register createRegister(ICDIRegisterObject regObject) throws CDIException {
|
||||
Register reg = getRegister(regObject);
|
||||
if (reg == null) {
|
||||
reg = new Register(getCSession().getCTarget(), regObject);
|
||||
regList.add(reg);
|
||||
}
|
||||
return reg;
|
||||
}
|
||||
|
||||
Register[] createRegisters(ICDIRegisterObject[] regObjects) throws CDIException {
|
||||
Register[] regs = new Register[regObjects.length];
|
||||
for (int i = 0; i < regs.length; i++) {
|
||||
regs[i] = createRegister(regObjects[i]);
|
||||
}
|
||||
return regs;
|
||||
}
|
||||
|
||||
void update() throws CDIException {
|
||||
MISession mi = getCSession().getMISession();
|
||||
CommandFactory factory = mi.getCommandFactory();
|
||||
MIDataListChangedRegisters changed = factory.createMIDataListChangedRegisters();
|
||||
try {
|
||||
mi.postCommand(changed);
|
||||
MIDataListChangedRegistersInfo info =
|
||||
changed.getMIDataListChangedRegistersInfo();
|
||||
if (info == null) {
|
||||
throw new CDIException("No answer");
|
||||
}
|
||||
int[] regnos = info.getRegisterNumbers();
|
||||
List eventList = new ArrayList(regnos.length);
|
||||
for (int i = 0 ; i < regnos.length; i++) {
|
||||
Register reg = getRegister(regnos[i]);
|
||||
if (reg != null) {
|
||||
eventList.add(new MIRegisterChangedEvent(reg.getName(), regnos[i]));
|
||||
}
|
||||
}
|
||||
MIEvent[] events = (MIEvent[])eventList.toArray(new MIEvent[0]);
|
||||
mi.fireEvents(events);
|
||||
} catch (MIException e) {
|
||||
throw new CDIException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue