GP-1585: Change TargetBreakpointLocation to range, not address,length

This commit is contained in:
Dan 2022-09-12 09:01:55 -04:00
parent 6a2cd80550
commit cb16d8dd9e
23 changed files with 1143 additions and 1161 deletions

View file

@ -16,12 +16,12 @@
package agent.dbgeng.model.iface2;
import ghidra.dbg.target.TargetBreakpointLocation;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressRange;
public interface DbgModelTargetBreakpointLocation
extends DbgModelTargetObject, TargetBreakpointLocation {
@Override
public Address getAddress();
public AddressRange getRange();
}

View file

@ -24,6 +24,7 @@ import agent.dbgeng.model.iface1.DbgModelTargetBptHelper;
import ghidra.dbg.target.*;
import ghidra.dbg.target.TargetBreakpointSpecContainer.TargetBreakpointKindSet;
import ghidra.program.model.address.*;
import ghidra.util.Msg;
public interface DbgModelTargetBreakpointSpec extends //
DbgModelTargetObject, //
@ -99,12 +100,13 @@ public interface DbgModelTargetBreakpointSpec extends //
setBreakpointId(idstr);
//String uidstr = unique.getCachedAttribute(VALUE_ATTRIBUTE_NAME).toString();
String enstr = enabled.getCachedAttribute(VALUE_ATTRIBUTE_NAME).toString();
Address address = null;
try {
Address address = space.getAddress(addstr);
map.put(ADDRESS_ATTRIBUTE_NAME, address);
address = space.getAddress(addstr);
//map.put(ADDRESS_ATTRIBUTE_NAME, address);
}
catch (AddressFormatException e) {
e.printStackTrace();
Msg.error(this, "Could not parse breakpoint address", e);
}
map.put(SPEC_ATTRIBUTE_NAME, this);
map.put(EXPRESSION_ATTRIBUTE_NAME, addstr);
@ -113,7 +115,15 @@ public interface DbgModelTargetBreakpointSpec extends //
map.put(ENABLED_ATTRIBUTE_NAME, enstr.equals("-1"));
setEnabled(enstr.equals("-1"), "Refreshed");
int size = getBreakpointInfo().getSize();
map.put(LENGTH_ATTRIBUTE_NAME, size);
//map.put(LENGTH_ATTRIBUTE_NAME, size);
if (address != null) {
try {
map.put(RANGE_ATTRIBUTE_NAME, new AddressRangeImpl(address, size));
}
catch (AddressOverflowException e) {
Msg.error(this, "Address overflow in breakpoint range", e);
}
}
String oldval = (String) getCachedAttribute(DISPLAY_ATTRIBUTE_NAME);
String display = "[" + idstr + "] " + addstr;
@ -125,9 +135,13 @@ public interface DbgModelTargetBreakpointSpec extends //
private long orZero(Long l) {
if (l == null) {
return 0;
Msg.warn(this, "Breakpoint had null offset. Defaulting to ram:00000000");
}
return l;
return l == null ? 0 : l;
}
private int orOne(Integer i) {
return i == null ? 1 : i;
}
public default Address doGetAddress() {
@ -135,6 +149,14 @@ public interface DbgModelTargetBreakpointSpec extends //
return getModel().getAddress("ram", orZero(info.getOffset()));
}
public default AddressRange doGetRange() {
DbgBreakpointInfo info = getBreakpointInfo();
AddressSpace ram = getModel().getAddressSpace("ram");
Address min = ram.getAddress(orZero(info.getOffset()));
Address max = min.add(orOne(info.getSize()) - 1);
return new AddressRangeImpl(min, max);
}
public default void updateInfo(DbgBreakpointInfo oldInfo, DbgBreakpointInfo newInfo,
String reason) {
synchronized (this) {
@ -147,6 +169,7 @@ public interface DbgModelTargetBreakpointSpec extends //
/**
* Update the enabled field
*
* <p>
* This does not actually toggle the breakpoint. It just updates the field and calls the proper
* listeners. To actually toggle the breakpoint, use {@link #toggle(boolean)} instead, which if
* effective, should eventually cause this method to be called.

View file

@ -67,20 +67,18 @@ public class DbgModelTargetBreakpointSpecImpl extends DbgModelTargetObjectImpl
protected boolean enabled;
public void changeAttributeSet(String reason) {
this.changeAttributes(List.of(), List.of(), Map.of( //
DISPLAY_ATTRIBUTE_NAME, "[" + info.getNumber() + "] " + info.getExpression(), //
ADDRESS_ATTRIBUTE_NAME, doGetAddress(), //
LENGTH_ATTRIBUTE_NAME, info.getSize(), //
SPEC_ATTRIBUTE_NAME, this, //
EXPRESSION_ATTRIBUTE_NAME, info.getExpression(), //
KINDS_ATTRIBUTE_NAME, getKinds() //
), reason);
this.changeAttributes(List.of(), List.of(), Map.of( //
BPT_TYPE_ATTRIBUTE_NAME, info.getType().name(), //
BPT_DISP_ATTRIBUTE_NAME, info.getDisp().name(), //
BPT_PENDING_ATTRIBUTE_NAME, info.getPending(), //
BPT_TIMES_ATTRIBUTE_NAME, info.getTimes() //
), reason);
this.changeAttributes(List.of(), List.of(), Map.of(
DISPLAY_ATTRIBUTE_NAME, "[" + info.getNumber() + "] " + info.getExpression(),
RANGE_ATTRIBUTE_NAME, doGetRange(),
SPEC_ATTRIBUTE_NAME, this,
EXPRESSION_ATTRIBUTE_NAME, info.getExpression(),
KINDS_ATTRIBUTE_NAME, getKinds(),
BPT_TYPE_ATTRIBUTE_NAME, info.getType().name(),
BPT_DISP_ATTRIBUTE_NAME, info.getDisp().name(),
BPT_PENDING_ATTRIBUTE_NAME, info.getPending(),
BPT_TIMES_ATTRIBUTE_NAME, info.getTimes()),
reason);
}
private final ListenerSet<TargetBreakpointAction> actions =

View file

@ -28,7 +28,7 @@ import ghidra.dbg.target.TargetBreakpointLocation;
import ghidra.dbg.target.TargetObject;
import ghidra.dbg.target.schema.*;
import ghidra.dbg.util.PathUtils;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.*;
import ghidra.util.Msg;
@TargetObjectSchemaInfo(
@ -55,8 +55,7 @@ public class GdbModelTargetBreakpointLocation
protected final GdbModelImpl impl;
protected final GdbBreakpointLocation loc;
protected Address address;
protected Integer length;
protected AddressRange range;
protected String display;
public GdbModelTargetBreakpointLocation(GdbModelTargetBreakpointSpec spec,
@ -67,8 +66,8 @@ public class GdbModelTargetBreakpointLocation
impl.addModelObject(loc, this);
if (!spec.info.getType().isWatchpoint()) {
this.address = doGetAddress();
this.length = 1;
Address addr = impl.space.getAddress(loc.addrAsLong());
this.range = new AddressRangeImpl(addr, addr);
doChangeAttributes("Initialized");
}
}
@ -76,8 +75,7 @@ public class GdbModelTargetBreakpointLocation
protected void doChangeAttributes(String reason) {
this.changeAttributes(List.of(), Map.of(
SPEC_ATTRIBUTE_NAME, parent,
ADDRESS_ATTRIBUTE_NAME, address,
LENGTH_ATTRIBUTE_NAME, length,
RANGE_ATTRIBUTE_NAME, range,
DISPLAY_ATTRIBUTE_NAME, display = computeDisplay()),
reason);
placeLocations();
@ -112,29 +110,26 @@ public class GdbModelTargetBreakpointLocation
throw new AssertionError("Unexpected result count: " + result);
}
address = impl.space.getAddress(vals.get(0));
length = vals.get(1).intValue();
range = makeRange(impl.space.getAddress(vals.get(0)), vals.get(1).intValue());
doChangeAttributes("Initialized");
}).exceptionally(ex -> {
Msg.warn(this, "Could not evaluated breakpoint location and/or size: " + ex);
address = impl.space.getAddress(0);
length = 1;
Address addr = impl.space.getAddress(0);
range = new AddressRangeImpl(addr, addr);
doChangeAttributes("Defaulted for eval/parse error");
return null;
});
}
protected String computeDisplay() {
return String.format("%d.%d %s", parent.info.getNumber(), loc.getSub(), address);
return String.format("%d.%d %s", parent.info.getNumber(), loc.getSub(),
range.getMinAddress());
}
protected Address doGetAddress() {
return impl.space.getAddress(loc.addrAsLong());
}
@Override
public Integer getLength() {
return length;
// Avoid the checked exception on new AddressRangeImpl(min, length)
protected static AddressRange makeRange(Address min, int length) {
Address max = min.add(length - 1);
return new AddressRangeImpl(min, max);
}
protected void placeLocations() {
@ -161,6 +156,11 @@ public class GdbModelTargetBreakpointLocation
}
}
@Override
public AddressRange getRange() {
return range;
}
@Override
public GdbModelTargetBreakpointSpec getSpecification() {
return parent;

View file

@ -16,13 +16,13 @@
package agent.lldb.model.iface2;
import ghidra.dbg.target.TargetBreakpointLocation;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressRange;
public interface LldbModelTargetBreakpointLocation
extends LldbModelTargetObject, TargetBreakpointLocation {
@Override
public Address getAddress();
AddressRange getRange();
public int getLocationId();
}

View file

@ -25,7 +25,7 @@ import ghidra.dbg.target.TargetObject;
import ghidra.dbg.target.schema.TargetAttributeType;
import ghidra.dbg.target.schema.TargetObjectSchemaInfo;
import ghidra.dbg.util.PathUtils;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.*;
@TargetObjectSchemaInfo(
name = "BreakpointLocation",
@ -46,11 +46,9 @@ public class LldbModelTargetBreakpointLocationImpl extends LldbModelTargetObject
protected LldbModelTargetAbstractXpointSpec spec;
protected SBBreakpointLocation loc;
protected Address address;
protected Integer length;
protected AddressRange range;
protected String display;
public LldbModelTargetBreakpointLocationImpl(LldbModelTargetAbstractXpointSpec spec,
SBBreakpointLocation loc) {
super(spec.getModel(), spec, keyLocation(loc), loc, "BreakpointLocation");
@ -60,21 +58,28 @@ public class LldbModelTargetBreakpointLocationImpl extends LldbModelTargetObject
doChangeAttributes("Initialization");
}
// TODO: A separate class for Impl wrapping SBWatchpoint?
public LldbModelTargetBreakpointLocationImpl(LldbModelTargetAbstractXpointSpec spec,
SBWatchpoint wpt) {
super(spec.getModel(), spec, keyLocation(wpt), wpt, "BreakpointLocation");
this.loc = null;
address = getModel().getAddress("ram", wpt.GetWatchAddress().longValue());
Address address = getModel().getAddress("ram", wpt.GetWatchAddress().longValue());
long length = wpt.GetWatchSize();
this.changeAttributes(List.of(), Map.of(
SPEC_ATTRIBUTE_NAME, parent,
ADDRESS_ATTRIBUTE_NAME, address,
LENGTH_ATTRIBUTE_NAME, length = (int) wpt.GetWatchSize(),
RANGE_ATTRIBUTE_NAME, range = makeRange(address, length),
DISPLAY_ATTRIBUTE_NAME, display = getDescription(1)),
"Initialization");
placeLocations();
}
protected static AddressRange makeRange(Address min, long length) {
Address max = min.add(length - 1);
return new AddressRangeImpl(min, max);
}
@Override
public String getDescription(int level) {
Object modelObject = getModelObject();
SBStream stream = new SBStream();
@ -91,12 +96,10 @@ public class LldbModelTargetBreakpointLocationImpl extends LldbModelTargetObject
}
protected void doChangeAttributes(String reason) {
address = getModel().getAddress("ram", loc.GetLoadAddress().longValue());
length = 1;
Address address = getModel().getAddress("ram", loc.GetLoadAddress().longValue());
this.changeAttributes(List.of(), Map.of(
SPEC_ATTRIBUTE_NAME, parent,
ADDRESS_ATTRIBUTE_NAME, address,
LENGTH_ATTRIBUTE_NAME, length,
RANGE_ATTRIBUTE_NAME, range = new AddressRangeImpl(address, address),
DISPLAY_ATTRIBUTE_NAME, display = getDescription(1)),
reason);
placeLocations();
@ -104,7 +107,8 @@ public class LldbModelTargetBreakpointLocationImpl extends LldbModelTargetObject
protected void placeLocations() {
LldbModelTargetSession parentSession = getParentSession();
Map<String, ? extends TargetObject> cachedElements = parentSession.getProcesses().getCachedElements();
Map<String, ? extends TargetObject> cachedElements =
parentSession.getProcesses().getCachedElements();
for (TargetObject obj : cachedElements.values()) {
if (obj instanceof LldbModelTargetProcess) {
LldbModelTargetProcessImpl process = (LldbModelTargetProcessImpl) obj;
@ -123,21 +127,18 @@ public class LldbModelTargetBreakpointLocationImpl extends LldbModelTargetObject
TargetObject modelObject = getModel().getModelObject(getManager().getCurrentProcess());
if (modelObject instanceof LldbModelTargetProcess) {
LldbModelTargetProcess targetProcess = (LldbModelTargetProcess) modelObject;
LldbModelTargetBreakpointLocationContainer locs = (LldbModelTargetBreakpointLocationContainer) targetProcess.getCachedAttribute("Breakpoints");
LldbModelTargetBreakpointLocationContainer locs =
(LldbModelTargetBreakpointLocationContainer) targetProcess
.getCachedAttribute("Breakpoints");
locs.removeBreakpointLocation(this);
}
}
@Override
public Integer getLength() {
return length;
}
@Override
public Address getAddress() {
return address;
public AddressRange getRange() {
return range;
}
@Override
public int getLocationId() {
return loc.GetID();

View file

@ -56,6 +56,7 @@ public class LldbModelTargetBreakpointSpecImpl extends LldbModelTargetAbstractXp
super(breakpoints, info, "BreakpointSpec");
}
@Override
public String getDescription(int level) {
SBStream stream = new SBStream();
SBBreakpoint bpt = (SBBreakpoint) getModelObject();
@ -63,16 +64,17 @@ public class LldbModelTargetBreakpointSpecImpl extends LldbModelTargetAbstractXp
return stream.GetData();
}
@Override
protected TargetBreakpointKindSet computeKinds(Object from) {
if (from instanceof SBBreakpoint) {
SBBreakpoint bpt = (SBBreakpoint) from;
return bpt.IsHardware() ?
TargetBreakpointKindSet.of(TargetBreakpointKind.HW_EXECUTE) :
TargetBreakpointKindSet.of(TargetBreakpointKind.SW_EXECUTE);
return bpt.IsHardware() ? TargetBreakpointKindSet.of(TargetBreakpointKind.HW_EXECUTE)
: TargetBreakpointKindSet.of(TargetBreakpointKind.SW_EXECUTE);
}
return TargetBreakpointKindSet.of();
}
@Override
public void updateInfo(Object info, String reason) {
setModelObject(info);
updateAttributesFromInfo(reason);
@ -91,13 +93,14 @@ public class LldbModelTargetBreakpointSpecImpl extends LldbModelTargetAbstractXp
});
}
@Override
public void updateAttributesFromInfo(String reason) {
SBBreakpoint bpt = (SBBreakpoint) getModelObject();
String description = getDescription(1);
String[] split = description.split(",");
if (split[1].contains("regex")) {
expression = split[1];
expression = expression.substring(expression.indexOf("'")+1);
expression = expression.substring(expression.indexOf("'") + 1);
expression = expression.substring(0, expression.indexOf("'"));
}
this.changeAttributes(List.of(), List.of(), Map.of( //
@ -118,15 +121,17 @@ public class LldbModelTargetBreakpointSpecImpl extends LldbModelTargetAbstractXp
LldbModelTargetBreakpointLocationImpl loc =
(LldbModelTargetBreakpointLocationImpl) elements[0];
this.changeAttributes(List.of(), List.of(), Map.of( //
TargetBreakpointLocation.ADDRESS_ATTRIBUTE_NAME, loc.address //
TargetBreakpointLocation.RANGE_ATTRIBUTE_NAME, loc.range //
), reason);
}
}
@Override
public ListenerSet<TargetBreakpointAction> getActions() {
return actions;
}
@Override
public LldbModelTargetBreakpointLocation findLocation(Object obj) {
if (!(obj instanceof BigInteger)) {
return null;

View file

@ -70,7 +70,8 @@ import ghidra.framework.options.annotation.*;
import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.annotation.AutoConfigStateField;
import ghidra.framework.plugintool.annotation.AutoServiceConsumed;
import ghidra.program.model.address.*;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressRange;
import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection;
@ -2097,9 +2098,9 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
if (listingService == null || listingService == null) {
return;
}
// TODO: Could probably inspect schema for any attribute of type Address[Range], or String
if (value == null) {
value =
object.getCachedAttribute(TargetBreakpointLocation.ADDRESS_ATTRIBUTE_NAME);
value = object.getCachedAttribute(TargetObject.PREFIX_INVISIBLE + "address");
}
if (value == null) {
value = object.getCachedAttribute(TargetObject.PREFIX_INVISIBLE + "range");
@ -2112,19 +2113,16 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
}
Address addr = null;
if (value instanceof Address) {
addr = (Address) value;
if (value instanceof Address a) {
addr = a;
}
else if (value instanceof AddressRangeImpl) {
AddressRangeImpl range = (AddressRangeImpl) value;
else if (value instanceof AddressRange range) {
addr = range.getMinAddress();
}
else if (value instanceof Long) {
Long lval = (Long) value;
else if (value instanceof Long lval) {
addr = object.getModel().getAddress("ram", lval);
}
else if (value instanceof String) {
String sval = (String) value;
else if (value instanceof String sval) {
addr = stringToAddress(object, addr, sval);
}
if (addr != null) {

View file

@ -23,8 +23,7 @@ import ghidra.app.services.LogicalBreakpoint;
import ghidra.app.services.TraceRecorder;
import ghidra.dbg.target.*;
import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointKind;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSet;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.*;
import ghidra.program.util.ProgramLocation;
import ghidra.trace.model.Trace;
@ -394,10 +393,11 @@ public interface LogicalBreakpointInternal extends LogicalBreakpoint {
Set<TargetBreakpointKind> tKinds = TraceRecorder.traceToTargetBreakpointKinds(kinds);
Address targetAddr = computeTargetAddress();
for (TargetBreakpointLocation loc : recorder.collectBreakpoints(null)) {
if (!targetAddr.equals(loc.getAddress())) {
AddressRange range = loc.getRange();
if (!targetAddr.equals(range.getMinAddress())) {
continue;
}
if (length != loc.getLength().longValue()) {
if (length != range.getLength()) {
continue;
}
TargetBreakpointSpec spec = loc.getSpecification();
@ -413,10 +413,11 @@ public interface LogicalBreakpointInternal extends LogicalBreakpoint {
Set<TargetBreakpointKind> tKinds = TraceRecorder.traceToTargetBreakpointKinds(kinds);
Address targetAddr = computeTargetAddress();
for (TargetBreakpointLocation loc : recorder.collectBreakpoints(null)) {
if (!targetAddr.equals(loc.getAddress())) {
AddressRange range = loc.getRange();
if (!targetAddr.equals(range.getMinAddress())) {
continue;
}
if (length != loc.getLength().longValue()) {
if (length != range.getLength()) {
continue;
}
TargetBreakpointSpec spec = loc.getSpecification();

View file

@ -31,18 +31,6 @@ import ghidra.util.exception.DuplicateNameException;
public class DefaultBreakpointRecorder implements ManagedBreakpointRecorder {
public static AddressRange range(Address min, Integer length) {
if (length == null) {
length = 1;
}
try {
return new AddressRangeImpl(min, length);
}
catch (AddressOverflowException e) {
throw new AssertionError(e);
}
}
protected static String nameBreakpoint(TargetBreakpointLocation bpt) {
if (bpt instanceof TargetBreakpointSpec) {
return bpt.getIndex();
@ -93,8 +81,7 @@ public class DefaultBreakpointRecorder implements ManagedBreakpointRecorder {
}
String path = PathUtils.toString(loc.getPath());
String name = nameBreakpoint(loc);
Address traceAddr = recorder.getMemoryMapper().targetToTrace(loc.getAddress());
AddressRange traceRange = range(traceAddr, loc.getLength());
AddressRange traceRange = recorder.getMemoryMapper().targetToTrace(loc.getRange());
try {
TargetBreakpointSpec spec = loc.getSpecification();
boolean enabled = spec.isEnabled();
@ -151,11 +138,9 @@ public class DefaultBreakpointRecorder implements ManagedBreakpointRecorder {
}, path);
}
protected void doBreakpointLocationChanged(long snap, int length, Address traceAddr,
String path) {
protected void doBreakpointLocationChanged(long snap, AddressRange traceRng, String path) {
for (TraceBreakpoint traceBpt : breakpointManager.getBreakpointsByPath(path)) {
AddressRange range = range(traceAddr, length);
if (traceBpt.getRange().equals(range)) {
if (traceBpt.getRange().equals(traceRng)) {
continue; // Nothing to change
}
// TODO: Verify all other attributes match?
@ -167,7 +152,7 @@ public class DefaultBreakpointRecorder implements ManagedBreakpointRecorder {
traceBpt.setClearedSnap(snap - 1);
}
TraceBreakpoint newtraceBpt =
breakpointManager.placeBreakpoint(path, snap, range,
breakpointManager.placeBreakpoint(path, snap, traceRng,
traceBpt.getThreads(), traceBpt.getKinds(), traceBpt.isEnabled(snap),
traceBpt.getComment());
// placeBreakpoint resets the name - maybe pass name in?
@ -182,11 +167,11 @@ public class DefaultBreakpointRecorder implements ManagedBreakpointRecorder {
}
@Override
public void breakpointLocationChanged(int length, Address traceAddr, String path)
public void breakpointLocationChanged(AddressRange traceRng, String path)
throws AssertionError {
long snap = recorder.getSnap();
recorder.parTx.execute("Breakpoint length changed", () -> {
doBreakpointLocationChanged(snap, length, traceAddr, path);
doBreakpointLocationChanged(snap, traceRng, path);
}, path);
}

View file

@ -30,7 +30,7 @@ import ghidra.async.AsyncLazyMap;
import ghidra.dbg.target.*;
import ghidra.dbg.util.PathUtils;
import ghidra.dbg.util.PathUtils.PathComparator;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressRange;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
import ghidra.trace.model.memory.TraceMemoryRegion;
@ -496,12 +496,10 @@ public class TraceObjectManager {
public void attributesChangedBreakpointLocation(TargetObject obj, Map<String, ?> added) {
TargetBreakpointLocation loc = (TargetBreakpointLocation) obj;
if (added.containsKey(TargetBreakpointLocation.LENGTH_ATTRIBUTE_NAME) ||
added.containsKey(TargetBreakpointLocation.ADDRESS_ATTRIBUTE_NAME)) {
Address traceAddr = recorder.getMemoryMapper().targetToTrace(loc.getAddress());
if (added.containsKey(TargetBreakpointLocation.RANGE_ATTRIBUTE_NAME)) {
AddressRange traceRng = recorder.getMemoryMapper().targetToTrace(loc.getRange());
String path = loc.getJoinedPath(".");
int length = loc.getLengthOrDefault(1);
recorder.breakpointRecorder.breakpointLocationChanged(length, traceAddr, path);
recorder.breakpointRecorder.breakpointLocationChanged(traceRng, path);
}
}

View file

@ -19,7 +19,7 @@ import java.util.Collection;
import java.util.Set;
import ghidra.dbg.target.*;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressRange;
import ghidra.trace.model.breakpoint.TraceBreakpoint;
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
import ghidra.trace.model.thread.TraceThread;
@ -41,11 +41,10 @@ public interface ManagedBreakpointRecorder {
/**
* The range of a breakpoint location has changed
*
* @param length the new length
* @param traceAddr the address of the location in the trace
* @param traceRng the address range of the location in the trace
* @param path the dot-separated path of the breakpoint location in the model
*/
void breakpointLocationChanged(int length, Address traceAddr, String path);
void breakpointLocationChanged(AddressRange traceRng, String path);
/**
* A breakpoint specification has changed (typically, toggled)

View file

@ -18,6 +18,7 @@ package ghidra.dbg.target;
import ghidra.dbg.DebuggerTargetObjectIface;
import ghidra.dbg.target.schema.TargetAttributeType;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressRange;
/**
* The location of a breakpoint
@ -31,20 +32,33 @@ import ghidra.program.model.address.Address;
@DebuggerTargetObjectIface("BreakpointLocation")
public interface TargetBreakpointLocation extends TargetObject {
String ADDRESS_ATTRIBUTE_NAME = PREFIX_INVISIBLE + "address";
// NOTE: address and length are treated separately (not using AddressRange)
// On GDB, e.g., the length may not be offered immediately.
String LENGTH_ATTRIBUTE_NAME = PREFIX_INVISIBLE + "length";
String RANGE_ATTRIBUTE_NAME = PREFIX_INVISIBLE + "range";
String SPEC_ATTRIBUTE_NAME = PREFIX_INVISIBLE + "spec";
/**
* The range covered by this location
*
* <p>
* Typically, watchpoints (or access breakpoints) have a length, so the range would cover all
* addresses in the variable being watched. Execution breakpoints likely have a "length" of 1,
* meaning they cover only the address of the trap.
*
* @return the address range of the location
*/
@TargetAttributeType(name = RANGE_ATTRIBUTE_NAME, hidden = true)
public default AddressRange getRange() {
return getTypedAttributeNowByName(RANGE_ATTRIBUTE_NAME, AddressRange.class, null);
}
/**
* The minimum address of this location
*
* @return the address
* @deprecated use {@link #getRange()} instead
*/
@TargetAttributeType(name = ADDRESS_ATTRIBUTE_NAME, required = true, hidden = true)
@Deprecated(forRemoval = true, since = "10.2")
public default Address getAddress() {
return getTypedAttributeNowByName(ADDRESS_ATTRIBUTE_NAME, Address.class, null);
return getRange().getMinAddress();
}
/**
@ -53,18 +67,26 @@ public interface TargetBreakpointLocation extends TargetObject {
* <p>
* In most cases, where the length is not available, a length of 1 should be presumed.
*
* <p>
* TODO: Should this be Long?
*
* @return the length, or {@code null} if not known
* @deprecated use {@link #getRange()} instead
*/
@TargetAttributeType(name = LENGTH_ATTRIBUTE_NAME, hidden = true)
@Deprecated(forRemoval = true, since = "10.2")
public default Integer getLength() {
return getTypedAttributeNowByName(LENGTH_ATTRIBUTE_NAME, Integer.class, null);
AddressRange range = getRange();
return range == null ? null : (int) range.getLength();
}
/**
* Get the length, defaulting to a given fallback, usually 1
*
* @param fallback the fallback value
* @return the length, or the fallback
* @deprecated use {@link #getRange()} instead
*/
@Deprecated(forRemoval = true, since = "10.2")
public default int getLengthOrDefault(int fallback) {
return getTypedAttributeNowByName(LENGTH_ATTRIBUTE_NAME, Integer.class, fallback);
Integer length = getLength();
return length == null ? 1 : length;
}
/**
@ -72,7 +94,8 @@ public interface TargetBreakpointLocation extends TargetObject {
*
* <p>
* If the debugger does not separate specifications from actual breakpoints, then the
* "specification" is this breakpoint. Otherwise, the specification is the parent.
* "specification" is this breakpoint. Otherwise, the specification is identified by an
* attribute, usually a link.
*
* @return the reference to the specification
*/

View file

@ -92,8 +92,8 @@ public class TestDebuggerObjectModel extends EmptyDebuggerObjectModel {
}
protected TestTargetBreakpoint newTestTargetBreakpoint(TestTargetBreakpointContainer container,
int num, Address address, int length, Set<TargetBreakpointKind> kinds) {
return new TestTargetBreakpoint(container, num, address, length, kinds);
int num, AddressRange range, Set<TargetBreakpointKind> kinds) {
return new TestTargetBreakpoint(container, num, range, kinds);
}
protected TestTargetMemory newTestTargetMemory(TestTargetProcess process, AddressSpace space) {

View file

@ -21,24 +21,23 @@ import java.util.concurrent.CompletableFuture;
import ghidra.dbg.target.*;
import ghidra.dbg.target.TargetBreakpointSpecContainer.TargetBreakpointKindSet;
import ghidra.dbg.util.PathUtils;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.*;
public class TestTargetBreakpoint
extends DefaultTestTargetObject<TestTargetBreakpoint, TestTargetBreakpointContainer>
implements TargetBreakpointSpec, TargetBreakpointLocation, TargetDeletable {
public TestTargetBreakpoint(TestTargetBreakpointContainer parent, int num, Address address,
int length, Set<TargetBreakpointKind> kinds) {
public TestTargetBreakpoint(TestTargetBreakpointContainer parent, int num, AddressRange range,
Set<TargetBreakpointKind> kinds) {
super(parent, PathUtils.makeKey(PathUtils.makeIndex(num)), "Breakpoint");
changeAttributes(List.of(), Map.of(
SPEC_ATTRIBUTE_NAME, this,
ADDRESS_ATTRIBUTE_NAME, address,
RANGE_ATTRIBUTE_NAME, range,
ENABLED_ATTRIBUTE_NAME, true,
EXPRESSION_ATTRIBUTE_NAME, address.toString(),
KINDS_ATTRIBUTE_NAME, TargetBreakpointKindSet.copyOf(kinds),
LENGTH_ATTRIBUTE_NAME, length //
), "Initialized");
EXPRESSION_ATTRIBUTE_NAME, range.getMinAddress().toString(),
KINDS_ATTRIBUTE_NAME, TargetBreakpointKindSet.copyOf(kinds)),
"Initialized");
}
@Override

View file

@ -57,8 +57,7 @@ public class TestTargetBreakpointContainer
public CompletableFuture<Void> placeBreakpoint(AddressRange range,
Set<TargetBreakpointKind> kinds) {
TestTargetBreakpoint bpt =
getModel().newTestTargetBreakpoint(this, counter.getAndIncrement(),
range.getMinAddress(), (int) range.getLength(), kinds);
getModel().newTestTargetBreakpoint(this, counter.getAndIncrement(), range, kinds);
changeElements(List.of(), List.of(bpt), "Breakpoint Added");
return getModel().future(null);
}

View file

@ -16,7 +16,8 @@
package ghidra.dbg.test;
import static org.junit.Assert.*;
import static org.junit.Assume.*;
import static org.junit.Assume.assumeNotNull;
import static org.junit.Assume.assumeTrue;
import java.util.*;
import java.util.Map.Entry;
@ -31,7 +32,6 @@ import ghidra.dbg.target.TargetBreakpointSpecContainer.TargetBreakpointKindSet;
import ghidra.dbg.target.schema.TargetObjectSchema;
import ghidra.dbg.util.DebuggerCallbackReorderer;
import ghidra.program.model.address.AddressRange;
import ghidra.program.model.address.AddressRangeImpl;
import ghidra.util.Msg;
/**
@ -141,10 +141,10 @@ public abstract class AbstractDebuggerModelBreakpointsTest extends AbstractDebug
if (spec == null) { // Mid construction?
continue;
}
if (l.getAddress() == null || l.getLength() == null) {
AddressRange actualRange = l.getRange();
if (actualRange == null) {
continue;
}
AddressRange actualRange = new AddressRangeImpl(l.getAddress(), l.getLength());
if (!actualRange.contains(range.getMinAddress()) ||
!actualRange.contains(range.getMaxAddress())) {
continue;

View file

@ -1,398 +1,397 @@
<?xml version="1.0" ?>
<?xml version="1.0"?>
<context>
<schema name="Test" elementResync="NEVER" attributeResync="ONCE">
<interface name="EventScope" />
<interface name="Launcher" />
<interface name="FocusScope" />
<interface name="Aggregate" />
<element schema="VOID" />
<!-- attribute name="_accessible" schema="BOOL" hidden="yes" /-->
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="_state" schema="EXECUTION_STATE" required="yes" hidden="yes" />
<attribute name="_prompt" schema="STRING" required="yes" hidden="yes" />
<attribute name="Environment" schema="Environment" />
<attribute name="Processes" schema="ProcessContainer" required="yes" fixed="yes" />
<attribute name="Interpreter" schema="Interpreter" />
<attribute name="JavaMimic" schema="Launcher" />
<attribute schema="ANY" />
</schema>
<schema name="Environment" elementResync="NEVER" attributeResync="NEVER">
<interface name="Environment" />
<element schema="VOID" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="Arch" schema="STRING" />
<attribute name="Debugger" schema="STRING" />
<attribute name="OS" schema="STRING" />
<attribute schema="ANY" />
</schema>
<schema name="ProcessContainer" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<element schema="Process" />
<attribute name="_event_process" schema="STRING" hidden="yes" />
<attribute name="_event_thread" schema="STRING" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="base" schema="INT" hidden="yes" />
<attribute schema="ANY" />
</schema>
<schema name="Interpreter" elementResync="NEVER" attributeResync="NEVER">
<interface name="Interpreter" />
<element schema="VOID" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="Arch" schema="STRING" />
<attribute name="Debugger" schema="STRING" />
<attribute name="OS" schema="STRING" />
<attribute schema="ANY" />
</schema>
<schema name="Launcher" elementResync="NEVER" attributeResync="NEVER">
<interface name="Launcher" />
<element schema="VOID" />
<attribute name="_parameters" schema="MAP_PARAMETERS" required="yes" fixed="yes" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="VOID" />
</schema>
<schema name="Process" elementResync="NEVER" attributeResync="ONCE">
<interface name="Aggregate" />
<interface name="Process" />
<element schema="VOID" />
<attribute name="_pid" schema="LONG" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="Breakpoints" schema="BreakpointContainer" required="yes" fixed="yes" />
<attribute name="Memory" schema="Memory" required="yes" fixed="yes" />
<attribute name="Modules" schema="ModuleContainer" required="yes" fixed="yes" />
<attribute name="Registers" schema="RegisterContainer" required="yes" fixed="yes" />
<attribute name="Threads" schema="ThreadContainer" required="yes" fixed="yes" />
<attribute name="Devices" schema="OBJECT" />
<attribute name="Environment" schema="OBJECT" />
<attribute name="Handle" schema="OBJECT" />
<attribute name="Id" schema="OBJECT" />
<attribute name="Io" schema="OBJECT" />
<attribute name="Name" schema="OBJECT" />
<attribute schema="ANY" />
</schema>
<schema name="Memory" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<interface name="Memory" />
<element schema="MemoryRegion" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" />
</schema>
<schema name="ModuleContainer" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<interface name="ModuleContainer" />
<element schema="Module" />
<attribute name="_supports_synthetic_modules" schema="BOOL" fixed="yes" hidden="yes" />
<attribute name="_event_process" schema="STRING" hidden="yes" />
<attribute name="_event_thread" schema="STRING" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" />
</schema>
<schema name="ThreadContainer" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<element schema="Thread" />
<attribute name="_event_process" schema="STRING" hidden="yes" />
<attribute name="_event_thread" schema="STRING" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" />
</schema>
<schema name="MemoryRegion" elementResync="NEVER" attributeResync="NEVER">
<interface name="MemoryRegion" />
<element schema="VOID" />
<attribute name="_memory" schema="Memory" />
<attribute name="_range" schema="RANGE" required="yes" hidden="yes" />
<attribute name="_readable" schema="BOOL" required="yes" hidden="yes" />
<attribute name="_writable" schema="BOOL" required="yes" hidden="yes" />
<attribute name="_executable" schema="BOOL" required="yes" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="BaseAddress" schema="ADDRESS" />
<attribute name="EndAddress" schema="ADDRESS" />
<attribute name="RegionSize" schema="STRING" />
<attribute name="AllocationBase" schema="ADDRESS" />
<attribute name="AllocationProtect" schema="STRING" />
<attribute name="Protect" schema="STRING" />
<attribute name="State" schema="STRING" />
<attribute name="Type" schema="STRING" />
<attribute schema="VOID" />
</schema>
<schema name="Thread" elementResync="NEVER" attributeResync="NEVER">
<interface name="Thread" />
<interface name="ExecutionStateful" />
<interface name="Steppable" />
<interface name="Resumable" />
<interface name="Interruptible" />
<interface name="Killable" />
<element schema="VOID" />
<attribute name="_tid" schema="INT" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="_accessible" schema="BOOL" required="yes" hidden="yes" />
<attribute name="_state" schema="EXECUTION_STATE" required="yes" hidden="yes" />
<attribute name="_supported_step_kinds" schema="SET_STEP_KIND" required="yes" fixed="yes" hidden="yes" />
<attribute name="Stack" schema="Stack" required="yes" fixed="yes" />
<attribute name="RegisterBank" schema="RegisterBank" fixed="yes" />
<attribute name="Environment" schema="OBJECT" />
<attribute name="Id" schema="OBJECT" />
<attribute name="Name" schema="OBJECT" />
<attribute name="_arch" schema="STRING" />
<attribute schema="ANY" />
</schema>
<schema name="Module" elementResync="NEVER" attributeResync="NEVER">
<interface name="Module" />
<element schema="VOID" />
<attribute name="_range" schema="RANGE" required="yes" hidden="yes" />
<attribute name="_module_name" schema="STRING" required="yes" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="BaseAddress" schema="OBJECT" />
<attribute name="ImageName" schema="OBJECT" />
<attribute name="TimeStamp" schema="OBJECT" />
<attribute name="Len" schema="OBJECT" />
<attribute name="Name" schema="OBJECT" />
<attribute name="Size" schema="OBJECT" />
<attribute name="Sections" schema="SectionContainer" />
<attribute schema="ANY" />
</schema>
<schema name="SectionContainer" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<interface name="SectionContainer" />
<element schema="Section" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" />
</schema>
<schema name="Section" elementResync="NEVER" attributeResync="NEVER">
<interface name="Section" />
<element schema="VOID" />
<attribute name="_module" schema="Module" hidden="yes" />
<attribute name="_range" schema="RANGE" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" />
</schema>
<schema name="BreakpointContainer" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<interface name="BreakpointSpecContainer" />
<interface name="BreakpointLocationContainer" />
<element schema="Breakpoint" />
<attribute name="_supported_breakpoint_kinds" schema="SET_BREAKPOINT_KIND" required="yes" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" />
</schema>
<schema name="SymbolContainer" canonical="yes" elementResync="ONCE" attributeResync="NEVER">
<interface name="SymbolNamespace" />
<element schema="Symbol" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" />
</schema>
<schema name="RegisterContainer" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<interface name="RegisterContainer" />
<element schema="RegisterDescriptor" />
<attribute name="_descriptions" schema="RegisterContainer" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" />
</schema>
<schema name="RegisterBank" elementResync="NEVER" attributeResync="NEVER">
<interface name="RegisterBank" />
<!-- NB: registers are attributes, not elements here -->
<element schema="RegisterDescriptor" />
<attribute name="_descriptions" schema="RegisterContainer" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="OBJECT" />
</schema>
<schema name="Stack" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<element schema="StackFrame" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" />
</schema>
<schema name="Breakpoint" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<interface name="BreakpointSpec" />
<interface name="BreakpointLocation" />
<interface name="Deletable" />
<element schema="OBJECT" />
<attribute name="_enabled" schema="BOOL" required="yes" hidden="yes" />
<attribute name="_expression" schema="STRING" required="yes" hidden="yes" />
<attribute name="_kinds" schema="SET_BREAKPOINT_KIND" required="yes" hidden="yes" />
<attribute name="_container" schema="BreakpointContainer" />
<attribute name="_affects" schema="LIST_OBJECT" hidden="yes" />
<attribute name="_spec" schema="Breakpoint" />
<attribute name="_length" schema="INT" hidden="yes" />
<attribute name="_address" schema="ADDRESS" required="yes" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="Type" schema="OBJECT" />
<attribute name="Disposition" schema="OBJECT" />
<attribute name="Pending" schema="OBJECT" />
<attribute name="Times" schema="OBJECT" />
<attribute schema="VOID" />
</schema>
<schema name="StackFrame" elementResync="NEVER" attributeResync="NEVER">
<interface name="StackFrame" />
<element schema="VOID" />
<attribute name="_pc" schema="ADDRESS" required="yes" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="Attributes" schema="StackFrameAttributes" />
<attribute schema="ANY" />
</schema>
<schema name="StackFrameAttributes" elementResync="NEVER" attributeResync="NEVER">
<element schema="VOID" />
<attribute name="_pc" schema="ADDRESS" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="FrameNumber" schema="OBJECT" />
<attribute name="FrameOffset" schema="OBJECT" />
<attribute name="FuncTableEntry" schema="OBJECT" />
<attribute name="InstructionOffset" schema="OBJECT" />
<attribute name="ReturnOffset" schema="OBJECT" />
<attribute name="StackOffset" schema="OBJECT" />
<attribute name="Virtual" schema="OBJECT" />
<attribute schema="ANY" />
</schema>
<schema name="Symbol" elementResync="NEVER" attributeResync="NEVER">
<interface name="Symbol" />
<element schema="VOID" />
<attribute name="_namespace" schema="SymbolContainer" />
<attribute name="_data_type" schema="DATA_TYPE" fixed="yes" hidden="yes" />
<attribute name="_size" schema="LONG" fixed="yes" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ADDRESS" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="VOID" />
</schema>
<schema name="RegisterDescriptor" elementResync="NEVER" attributeResync="NEVER">
<interface name="Register" />
<element schema="VOID" />
<attribute name="_length" schema="INT" fixed="yes" hidden="yes" />
<attribute name="_container" schema="RegisterContainer" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" required="yes" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="VOID" />
</schema>
<schema name="Test" elementResync="NEVER" attributeResync="ONCE">
<interface name="EventScope" />
<interface name="Launcher" />
<interface name="FocusScope" />
<interface name="Aggregate" />
<element schema="VOID" />
<!-- attribute name="_accessible" schema="BOOL" hidden="yes" /-->
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="_state" schema="EXECUTION_STATE" required="yes" hidden="yes" />
<attribute name="_prompt" schema="STRING" required="yes" hidden="yes" />
<attribute name="Environment" schema="Environment" />
<attribute name="Processes" schema="ProcessContainer" required="yes" fixed="yes" />
<attribute name="Interpreter" schema="Interpreter" />
<attribute name="JavaMimic" schema="Launcher" />
<attribute schema="ANY" />
</schema>
<schema name="Environment" elementResync="NEVER" attributeResync="NEVER">
<interface name="Environment" />
<element schema="VOID" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="Arch" schema="STRING" />
<attribute name="Debugger" schema="STRING" />
<attribute name="OS" schema="STRING" />
<attribute schema="ANY" />
</schema>
<schema name="ProcessContainer" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<element schema="Process" />
<attribute name="_event_process" schema="STRING" hidden="yes" />
<attribute name="_event_thread" schema="STRING" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="base" schema="INT" hidden="yes" />
<attribute schema="ANY" />
</schema>
<schema name="Interpreter" elementResync="NEVER" attributeResync="NEVER">
<interface name="Interpreter" />
<element schema="VOID" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="Arch" schema="STRING" />
<attribute name="Debugger" schema="STRING" />
<attribute name="OS" schema="STRING" />
<attribute schema="ANY" />
</schema>
<schema name="Launcher" elementResync="NEVER" attributeResync="NEVER">
<interface name="Launcher" />
<element schema="VOID" />
<attribute name="_parameters" schema="MAP_PARAMETERS" required="yes" fixed="yes" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="VOID" />
</schema>
<schema name="Process" elementResync="NEVER" attributeResync="ONCE">
<interface name="Aggregate" />
<interface name="Process" />
<element schema="VOID" />
<attribute name="_pid" schema="LONG" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="Breakpoints" schema="BreakpointContainer" required="yes" fixed="yes" />
<attribute name="Memory" schema="Memory" required="yes" fixed="yes" />
<attribute name="Modules" schema="ModuleContainer" required="yes" fixed="yes" />
<attribute name="Registers" schema="RegisterContainer" required="yes" fixed="yes" />
<attribute name="Threads" schema="ThreadContainer" required="yes" fixed="yes" />
<attribute name="Devices" schema="OBJECT" />
<attribute name="Environment" schema="OBJECT" />
<attribute name="Handle" schema="OBJECT" />
<attribute name="Id" schema="OBJECT" />
<attribute name="Io" schema="OBJECT" />
<attribute name="Name" schema="OBJECT" />
<attribute schema="ANY" />
</schema>
<schema name="Memory" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<interface name="Memory" />
<element schema="MemoryRegion" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" />
</schema>
<schema name="ModuleContainer" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<interface name="ModuleContainer" />
<element schema="Module" />
<attribute name="_supports_synthetic_modules" schema="BOOL" fixed="yes" hidden="yes" />
<attribute name="_event_process" schema="STRING" hidden="yes" />
<attribute name="_event_thread" schema="STRING" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" />
</schema>
<schema name="ThreadContainer" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<element schema="Thread" />
<attribute name="_event_process" schema="STRING" hidden="yes" />
<attribute name="_event_thread" schema="STRING" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" />
</schema>
<schema name="MemoryRegion" elementResync="NEVER" attributeResync="NEVER">
<interface name="MemoryRegion" />
<element schema="VOID" />
<attribute name="_memory" schema="Memory" />
<attribute name="_range" schema="RANGE" required="yes" hidden="yes" />
<attribute name="_readable" schema="BOOL" required="yes" hidden="yes" />
<attribute name="_writable" schema="BOOL" required="yes" hidden="yes" />
<attribute name="_executable" schema="BOOL" required="yes" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="BaseAddress" schema="ADDRESS" />
<attribute name="EndAddress" schema="ADDRESS" />
<attribute name="RegionSize" schema="STRING" />
<attribute name="AllocationBase" schema="ADDRESS" />
<attribute name="AllocationProtect" schema="STRING" />
<attribute name="Protect" schema="STRING" />
<attribute name="State" schema="STRING" />
<attribute name="Type" schema="STRING" />
<attribute schema="VOID" />
</schema>
<schema name="Thread" elementResync="NEVER" attributeResync="NEVER">
<interface name="Thread" />
<interface name="ExecutionStateful" />
<interface name="Steppable" />
<interface name="Resumable" />
<interface name="Interruptible" />
<interface name="Killable" />
<element schema="VOID" />
<attribute name="_tid" schema="INT" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="_accessible" schema="BOOL" required="yes" hidden="yes" />
<attribute name="_state" schema="EXECUTION_STATE" required="yes" hidden="yes" />
<attribute name="_supported_step_kinds" schema="SET_STEP_KIND" required="yes" fixed="yes" hidden="yes" />
<attribute name="Stack" schema="Stack" required="yes" fixed="yes" />
<attribute name="RegisterBank" schema="RegisterBank" fixed="yes" />
<attribute name="Environment" schema="OBJECT" />
<attribute name="Id" schema="OBJECT" />
<attribute name="Name" schema="OBJECT" />
<attribute name="_arch" schema="STRING" />
<attribute schema="ANY" />
</schema>
<schema name="Module" elementResync="NEVER" attributeResync="NEVER">
<interface name="Module" />
<element schema="VOID" />
<attribute name="_range" schema="RANGE" required="yes" hidden="yes" />
<attribute name="_module_name" schema="STRING" required="yes" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="BaseAddress" schema="OBJECT" />
<attribute name="ImageName" schema="OBJECT" />
<attribute name="TimeStamp" schema="OBJECT" />
<attribute name="Len" schema="OBJECT" />
<attribute name="Name" schema="OBJECT" />
<attribute name="Size" schema="OBJECT" />
<attribute name="Sections" schema="SectionContainer" />
<attribute schema="ANY" />
</schema>
<schema name="SectionContainer" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<interface name="SectionContainer" />
<element schema="Section" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" />
</schema>
<schema name="Section" elementResync="NEVER" attributeResync="NEVER">
<interface name="Section" />
<element schema="VOID" />
<attribute name="_module" schema="Module" hidden="yes" />
<attribute name="_range" schema="RANGE" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" />
</schema>
<schema name="BreakpointContainer" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<interface name="BreakpointSpecContainer" />
<interface name="BreakpointLocationContainer" />
<element schema="Breakpoint" />
<attribute name="_supported_breakpoint_kinds" schema="SET_BREAKPOINT_KIND" required="yes" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" />
</schema>
<schema name="SymbolContainer" canonical="yes" elementResync="ONCE" attributeResync="NEVER">
<interface name="SymbolNamespace" />
<element schema="Symbol" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" />
</schema>
<schema name="RegisterContainer" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<interface name="RegisterContainer" />
<element schema="RegisterDescriptor" />
<attribute name="_descriptions" schema="RegisterContainer" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" />
</schema>
<schema name="RegisterBank" elementResync="NEVER" attributeResync="NEVER">
<interface name="RegisterBank" />
<!-- NB: registers are attributes, not elements here -->
<element schema="RegisterDescriptor" />
<attribute name="_descriptions" schema="RegisterContainer" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="OBJECT" />
</schema>
<schema name="Stack" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<element schema="StackFrame" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="ANY" />
</schema>
<schema name="Breakpoint" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
<interface name="BreakpointSpec" />
<interface name="BreakpointLocation" />
<interface name="Deletable" />
<element schema="OBJECT" />
<attribute name="_enabled" schema="BOOL" required="yes" hidden="yes" />
<attribute name="_expression" schema="STRING" required="yes" hidden="yes" />
<attribute name="_kinds" schema="SET_BREAKPOINT_KIND" required="yes" hidden="yes" />
<attribute name="_container" schema="BreakpointContainer" />
<attribute name="_affects" schema="LIST_OBJECT" hidden="yes" />
<attribute name="_spec" schema="Breakpoint" />
<attribute name="_range" schema="RANGE" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="Type" schema="OBJECT" />
<attribute name="Disposition" schema="OBJECT" />
<attribute name="Pending" schema="OBJECT" />
<attribute name="Times" schema="OBJECT" />
<attribute schema="VOID" />
</schema>
<schema name="StackFrame" elementResync="NEVER" attributeResync="NEVER">
<interface name="StackFrame" />
<element schema="VOID" />
<attribute name="_pc" schema="ADDRESS" required="yes" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="Attributes" schema="StackFrameAttributes" />
<attribute schema="ANY" />
</schema>
<schema name="StackFrameAttributes" elementResync="NEVER" attributeResync="NEVER">
<element schema="VOID" />
<attribute name="_pc" schema="ADDRESS" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="FrameNumber" schema="OBJECT" />
<attribute name="FrameOffset" schema="OBJECT" />
<attribute name="FuncTableEntry" schema="OBJECT" />
<attribute name="InstructionOffset" schema="OBJECT" />
<attribute name="ReturnOffset" schema="OBJECT" />
<attribute name="StackOffset" schema="OBJECT" />
<attribute name="Virtual" schema="OBJECT" />
<attribute schema="ANY" />
</schema>
<schema name="Symbol" elementResync="NEVER" attributeResync="NEVER">
<interface name="Symbol" />
<element schema="VOID" />
<attribute name="_namespace" schema="SymbolContainer" />
<attribute name="_data_type" schema="DATA_TYPE" fixed="yes" hidden="yes" />
<attribute name="_size" schema="LONG" fixed="yes" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ADDRESS" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="VOID" />
</schema>
<schema name="RegisterDescriptor" elementResync="NEVER" attributeResync="NEVER">
<interface name="Register" />
<element schema="VOID" />
<attribute name="_length" schema="INT" fixed="yes" hidden="yes" />
<attribute name="_container" schema="RegisterContainer" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" required="yes" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="VOID" />
</schema>
</context>

View file

@ -24,6 +24,7 @@ import java.util.concurrent.locks.ReadWriteLock;
import com.google.common.collect.Range;
import db.DBHandle;
import ghidra.dbg.target.TargetBreakpointLocation;
import ghidra.program.model.address.*;
import ghidra.program.model.lang.Language;
import ghidra.trace.database.DBTrace;
@ -142,7 +143,8 @@ public class DBTraceBreakpointManager
public Collection<? extends TraceBreakpoint> getBreakpointsAt(long snap, Address address) {
if (trace.getObjectManager().hasSchema()) {
return trace.getObjectManager()
.getObjectsContaining(snap, address, TraceObjectBreakpointLocation.KEY_RANGE,
.getObjectsContaining(snap, address,
TargetBreakpointLocation.RANGE_ATTRIBUTE_NAME,
TraceObjectBreakpointLocation.class);
}
return delegateRead(address.getAddressSpace(), m -> m.getBreakpointsAt(snap, address),
@ -154,7 +156,8 @@ public class DBTraceBreakpointManager
AddressRange range) {
if (trace.getObjectManager().hasSchema()) {
return trace.getObjectManager()
.getObjectsIntersecting(span, range, TraceObjectBreakpointLocation.KEY_RANGE,
.getObjectsIntersecting(span, range,
TargetBreakpointLocation.RANGE_ATTRIBUTE_NAME,
TraceObjectBreakpointLocation.class);
}
return delegateRead(range.getAddressSpace(), m -> m.getBreakpointsIntersecting(span, range),

View file

@ -44,7 +44,7 @@ public class DBTraceObjectBreakpointLocation
protected class BreakpointChangeTranslator extends Translator<TraceBreakpoint> {
protected BreakpointChangeTranslator(DBTraceObject object, TraceBreakpoint iface) {
super(KEY_RANGE, object, iface);
super(TargetBreakpointLocation.RANGE_ATTRIBUTE_NAME, object, iface);
}
@Override
@ -64,7 +64,7 @@ public class DBTraceObjectBreakpointLocation
@Override
protected boolean appliesToKey(String key) {
return KEY_RANGE.equals(key) ||
return TargetBreakpointLocation.RANGE_ATTRIBUTE_NAME.equals(key) ||
TargetObject.DISPLAY_ATTRIBUTE_NAME.equals(key) ||
TargetBreakpointSpec.ENABLED_ATTRIBUTE_NAME.equals(key) ||
KEY_COMMENT.equals(key);
@ -122,7 +122,7 @@ public class DBTraceObjectBreakpointLocation
@Override
public void setRange(Range<Long> lifespan, AddressRange range) {
try (LockHold hold = object.getTrace().lockWrite()) {
object.setValue(lifespan, KEY_RANGE, range);
object.setValue(lifespan, TargetBreakpointLocation.RANGE_ATTRIBUTE_NAME, range);
this.range = range;
}
}
@ -133,8 +133,8 @@ public class DBTraceObjectBreakpointLocation
if (object.getLife().isEmpty()) {
return range;
}
return range = TraceObjectInterfaceUtils.getValue(object, getPlacedSnap(), KEY_RANGE,
AddressRange.class, range);
return range = TraceObjectInterfaceUtils.getValue(object, getPlacedSnap(),
TargetBreakpointLocation.RANGE_ATTRIBUTE_NAME, AddressRange.class, range);
}
}
@ -325,7 +325,7 @@ public class DBTraceObjectBreakpointLocation
}
public TraceAddressSpace getTraceAddressSpace() {
return spaceForValue(computeMinSnap(), KEY_RANGE);
return spaceForValue(computeMinSnap(), TargetBreakpointLocation.RANGE_ATTRIBUTE_NAME);
}
@Override

View file

@ -27,11 +27,10 @@ import com.google.common.collect.*;
import db.DBRecord;
import db.StringField;
import ghidra.dbg.target.TargetBreakpointLocation;
import ghidra.dbg.target.TargetObject;
import ghidra.dbg.target.schema.TargetObjectSchema;
import ghidra.dbg.util.*;
import ghidra.program.model.address.*;
import ghidra.program.model.address.AddressSpace;
import ghidra.trace.database.DBTrace;
import ghidra.trace.database.DBTraceUtils;
import ghidra.trace.database.breakpoint.DBTraceObjectBreakpointLocation;
@ -728,47 +727,6 @@ public class DBTraceObject extends DBAnnotatedObject implements TraceObject {
return manager.doCreateValue(lifespan, this, key, value);
}
// HACK: Because breakpoint uses address,length instead of range. FIXME!
protected void applyBreakpointRangeHack(Range<Long> lifespan, String key, Object value,
ConflictResolution resolution) {
/**
* NOTE: This should only be happening in Target/TraceBreakpointLocation, but I suppose
* anything using this scheme should be hacked.
*/
Address address;
int length;
if (key == TargetBreakpointLocation.ADDRESS_ATTRIBUTE_NAME &&
value instanceof Address) {
address = (Address) value;
InternalTraceObjectValue lengthObj = getValue(DBTraceUtils.lowerEndpoint(lifespan),
TargetBreakpointLocation.LENGTH_ATTRIBUTE_NAME);
if (lengthObj == null || !(lengthObj.getValue() instanceof Integer)) {
return;
}
length = (Integer) lengthObj.getValue();
}
else if (key == TargetBreakpointLocation.LENGTH_ATTRIBUTE_NAME &&
value instanceof Integer) {
length = (Integer) value;
InternalTraceObjectValue addressObj = getValue(DBTraceUtils.lowerEndpoint(lifespan),
TargetBreakpointLocation.ADDRESS_ATTRIBUTE_NAME);
if (addressObj == null || !(addressObj.getValue() instanceof Address)) {
return;
}
address = (Address) addressObj.getValue();
}
else {
return;
}
try {
setValue(lifespan, TraceObjectBreakpointLocation.KEY_RANGE,
new AddressRangeImpl(address, length), resolution);
}
catch (AddressOverflowException e) {
Msg.warn(this, "Could not set range: " + e);
}
}
@Override
public InternalTraceObjectValue setValue(Range<Long> lifespan, String key, Object value,
ConflictResolution resolution) {
@ -812,8 +770,6 @@ public class DBTraceObject extends DBAnnotatedObject implements TraceObject {
};
InternalTraceObjectValue result = setter.set(lifespan, value);
// NB. This hack will cause more value events. good.
applyBreakpointRangeHack(lifespan, key, value, resolution);
DBTraceObject child = setter.canonicalLifeChanged;
if (child != null) {
child.emitEvents(

View file

@ -31,14 +31,11 @@ import ghidra.util.exception.DuplicateNameException;
shortName = "breakpoint location",
fixedKeys = {
TargetObject.DISPLAY_ATTRIBUTE_NAME,
TargetBreakpointLocation.ADDRESS_ATTRIBUTE_NAME,
TargetBreakpointLocation.LENGTH_ATTRIBUTE_NAME,
TargetBreakpointLocation.RANGE_ATTRIBUTE_NAME,
TraceObjectBreakpointLocation.KEY_COMMENT,
TraceObjectBreakpointLocation.KEY_RANGE,
})
public interface TraceObjectBreakpointLocation extends TraceBreakpoint, TraceObjectInterface {
String KEY_COMMENT = "_comment";
String KEY_RANGE = "_range"; // Duplicates address,length
TraceObjectBreakpointSpec getSpecification();