mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
Merge remote-tracking branch 'origin/GP-5926_Dan_refsToRange--SQUASHED'
This commit is contained in:
commit
dc1c70e2bf
12 changed files with 539 additions and 163 deletions
|
@ -24,7 +24,6 @@ import ghidra.program.model.data.TypeDefSettingsDefinition;
|
||||||
import ghidra.program.model.symbol.RefType;
|
import ghidra.program.model.symbol.RefType;
|
||||||
import ghidra.program.model.symbol.SourceType;
|
import ghidra.program.model.symbol.SourceType;
|
||||||
import ghidra.trace.database.data.DBTraceDataSettingsOperations;
|
import ghidra.trace.database.data.DBTraceDataSettingsOperations;
|
||||||
import ghidra.trace.database.symbol.DBTraceReference;
|
|
||||||
import ghidra.trace.model.listing.TraceData;
|
import ghidra.trace.model.listing.TraceData;
|
||||||
import ghidra.trace.model.symbol.TraceReference;
|
import ghidra.trace.model.symbol.TraceReference;
|
||||||
import ghidra.trace.util.*;
|
import ghidra.trace.util.*;
|
||||||
|
@ -63,7 +62,7 @@ public interface DBTraceDataAdapter extends DBTraceCodeUnitAdapter, DataAdapterM
|
||||||
@Override
|
@Override
|
||||||
default void removeValueReference(Address refAddr) {
|
default void removeValueReference(Address refAddr) {
|
||||||
try (LockHold hold = getTrace().lockWrite()) {
|
try (LockHold hold = getTrace().lockWrite()) {
|
||||||
DBTraceReference ref = getTrace().getReferenceManager()
|
TraceReference ref = getTrace().getReferenceManager()
|
||||||
.getReference(getStartSnap(),
|
.getReference(getStartSnap(),
|
||||||
getAddress(), refAddr, DATA_OP_INDEX);
|
getAddress(), refAddr, DATA_OP_INDEX);
|
||||||
if (ref == null) {
|
if (ref == null) {
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -36,8 +36,8 @@ public class DBTraceOffsetReference extends DBTraceReference implements TraceOff
|
||||||
@Override
|
@Override
|
||||||
public Address getBaseAddress() {
|
public Address getBaseAddress() {
|
||||||
if (isExternalBlockReference) {
|
if (isExternalBlockReference) {
|
||||||
return ent.toAddress;
|
return ent.toAddrMin;
|
||||||
}
|
}
|
||||||
return ent.toAddress.subtractWrap(ent.ext);
|
return ent.toAddrMin.subtractWrap(ent.ext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import java.util.Collection;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
|
import ghidra.program.model.address.AddressRange;
|
||||||
import ghidra.program.model.symbol.*;
|
import ghidra.program.model.symbol.*;
|
||||||
import ghidra.trace.database.DBTrace;
|
import ghidra.trace.database.DBTrace;
|
||||||
import ghidra.trace.database.symbol.DBTraceReferenceSpace.DBTraceReferenceEntry;
|
import ghidra.trace.database.symbol.DBTraceReferenceSpace.DBTraceReferenceEntry;
|
||||||
|
@ -76,8 +77,8 @@ public class DBTraceReference implements TraceReference {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Address getToAddress() {
|
public AddressRange getToRange() {
|
||||||
return ent.toAddress;
|
return ent.toRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -39,6 +39,7 @@ import ghidra.trace.model.symbol.TraceReference;
|
||||||
import ghidra.trace.model.symbol.TraceReferenceManager;
|
import ghidra.trace.model.symbol.TraceReferenceManager;
|
||||||
import ghidra.trace.model.thread.TraceThread;
|
import ghidra.trace.model.thread.TraceThread;
|
||||||
import ghidra.util.UnionAddressSetView;
|
import ghidra.util.UnionAddressSetView;
|
||||||
|
import ghidra.util.database.spatial.rect.Rectangle2DDirection;
|
||||||
import ghidra.util.exception.VersionException;
|
import ghidra.util.exception.VersionException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
|
@ -96,27 +97,27 @@ public class DBTraceReferenceManager extends AbstractDBTraceSpaceBasedManager<DB
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doAddXRef(DBTraceReferenceEntry entry) {
|
protected void doAddXRef(DBTraceReferenceEntry entry) {
|
||||||
if (!entry.toAddress.isMemoryAddress()) {
|
if (!entry.toAddrMin.isMemoryAddress()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DBTraceReferenceSpace space = getReferenceSpace(entry.toAddress.getAddressSpace(), true);
|
DBTraceReferenceSpace space = getReferenceSpace(entry.toAddrMin.getAddressSpace(), true);
|
||||||
space.doAddXRef(entry);
|
space.doAddXRef(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doDelXRef(DBTraceReferenceEntry entry) {
|
protected void doDelXRef(DBTraceReferenceEntry entry) {
|
||||||
if (!entry.toAddress.isMemoryAddress()) {
|
if (!entry.toAddrMin.isMemoryAddress()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DBTraceReferenceSpace space = getReferenceSpace(entry.toAddress.getAddressSpace(), false);
|
DBTraceReferenceSpace space = getReferenceSpace(entry.toAddrMin.getAddressSpace(), false);
|
||||||
assert space != null;
|
assert space != null;
|
||||||
space.doDelXRef(entry);
|
space.doDelXRef(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doSetXRefLifespan(DBTraceReferenceEntry entry) {
|
protected void doSetXRefLifespan(DBTraceReferenceEntry entry) {
|
||||||
if (!entry.toAddress.isMemoryAddress()) {
|
if (!entry.toAddrMin.isMemoryAddress()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DBTraceReferenceSpace space = getReferenceSpace(entry.toAddress.getAddressSpace(), false);
|
DBTraceReferenceSpace space = getReferenceSpace(entry.toAddrMin.getAddressSpace(), false);
|
||||||
assert space != null;
|
assert space != null;
|
||||||
space.doSetXRefLifespan(entry);
|
space.doSetXRefLifespan(entry);
|
||||||
}
|
}
|
||||||
|
@ -164,9 +165,9 @@ public class DBTraceReferenceManager extends AbstractDBTraceSpaceBasedManager<DB
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DBTraceReference addMemoryReference(Lifespan lifespan, Address fromAddress,
|
public DBTraceReference addMemoryReference(Lifespan lifespan, Address fromAddress,
|
||||||
Address toAddress, RefType refType, SourceType source, int operandIndex) {
|
AddressRange toRange, RefType refType, SourceType source, int operandIndex) {
|
||||||
return delegateWrite(fromAddress.getAddressSpace(), s -> s.addMemoryReference(lifespan,
|
return delegateWrite(fromAddress.getAddressSpace(), s -> s.addMemoryReference(lifespan,
|
||||||
fromAddress, toAddress, refType, source, operandIndex));
|
fromAddress, toRange, refType, source, operandIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -199,10 +200,10 @@ public class DBTraceReferenceManager extends AbstractDBTraceSpaceBasedManager<DB
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DBTraceReference getReference(long snap, Address fromAddress, Address toAddress,
|
public DBTraceReference getReference(long snap, Address fromAddress, AddressRange toRange,
|
||||||
int operandIndex) {
|
int operandIndex) {
|
||||||
return delegateRead(fromAddress.getAddressSpace(),
|
return delegateRead(fromAddress.getAddressSpace(),
|
||||||
s -> s.getReference(snap, fromAddress, toAddress, operandIndex));
|
s -> s.getReference(snap, fromAddress, toRange, operandIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -253,9 +254,9 @@ public class DBTraceReferenceManager extends AbstractDBTraceSpaceBasedManager<DB
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<? extends DBTraceReference> getReferencesToRange(Lifespan span,
|
public Collection<? extends DBTraceReference> getReferencesToRange(Lifespan span,
|
||||||
AddressRange range) {
|
AddressRange range, Rectangle2DDirection order) {
|
||||||
return delegateRead(range.getAddressSpace(), s -> s.getReferencesToRange(span, range),
|
return delegateRead(range.getAddressSpace(),
|
||||||
Collections.emptyList());
|
s -> s.getReferencesToRange(span, range, order), Collections.emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -42,11 +42,11 @@ import ghidra.trace.model.Lifespan;
|
||||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||||
import ghidra.trace.model.symbol.TraceReference;
|
import ghidra.trace.model.symbol.TraceReference;
|
||||||
import ghidra.trace.model.symbol.TraceReferenceSpace;
|
import ghidra.trace.model.symbol.TraceReferenceSpace;
|
||||||
import ghidra.trace.util.TraceChangeRecord;
|
import ghidra.trace.util.*;
|
||||||
import ghidra.trace.util.TraceEvents;
|
|
||||||
import ghidra.util.*;
|
import ghidra.util.*;
|
||||||
import ghidra.util.database.*;
|
import ghidra.util.database.*;
|
||||||
import ghidra.util.database.annot.*;
|
import ghidra.util.database.annot.*;
|
||||||
|
import ghidra.util.database.spatial.rect.Rectangle2DDirection;
|
||||||
import ghidra.util.exception.VersionException;
|
import ghidra.util.exception.VersionException;
|
||||||
|
|
||||||
public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceSpace {
|
public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceSpace {
|
||||||
|
@ -59,7 +59,7 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected DBTraceReference construct(DBTraceReferenceEntry ent) {
|
protected DBTraceReference construct(DBTraceReferenceEntry ent) {
|
||||||
if (ent.toAddress.isStackAddress()) {
|
if (ent.toAddrMin.isStackAddress()) {
|
||||||
return new DBTraceStackReference(ent);
|
return new DBTraceStackReference(ent);
|
||||||
}
|
}
|
||||||
return new DBTraceReference(ent);
|
return new DBTraceReference(ent);
|
||||||
|
@ -97,7 +97,7 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
* <li>0: Initial version and previous unversioned implementation</li>
|
* <li>0: Initial version and previous unversioned implementation</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
@DBAnnotatedObjectInfo(version = 1)
|
@DBAnnotatedObjectInfo(version = 2)
|
||||||
protected static class DBTraceReferenceEntry
|
protected static class DBTraceReferenceEntry
|
||||||
extends AbstractDBTraceAddressSnapRangePropertyMapData<DBTraceReferenceEntry>
|
extends AbstractDBTraceAddressSnapRangePropertyMapData<DBTraceReferenceEntry>
|
||||||
implements DecodesAddresses {
|
implements DecodesAddresses {
|
||||||
|
@ -114,7 +114,8 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
private static final byte TYPE_SHIFT = 5;
|
private static final byte TYPE_SHIFT = 5;
|
||||||
//private static final byte TYPE_CLEAR = ~(TYPE_MASK << TYPE_SHIFT);
|
//private static final byte TYPE_CLEAR = ~(TYPE_MASK << TYPE_SHIFT);
|
||||||
|
|
||||||
static final String TO_ADDR_COLUMN_NAME = "ToAddr";
|
static final String TO_ADDR_MIN_COLUMN_NAME = "ToAddrMin";
|
||||||
|
static final String TO_ADDR_MAX_COLUMN_NAME = "ToAddrMax";
|
||||||
static final String SYMBOL_ID_COLUMN_NAME = "SymbolId";
|
static final String SYMBOL_ID_COLUMN_NAME = "SymbolId";
|
||||||
static final String REF_TYPE_COLUMN_NAME = "RefType";
|
static final String REF_TYPE_COLUMN_NAME = "RefType";
|
||||||
static final String OP_INDEX_COLUMN_NAME = "OpIndex";
|
static final String OP_INDEX_COLUMN_NAME = "OpIndex";
|
||||||
|
@ -122,8 +123,10 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
// bit-packed sourceType, isPrimary, type
|
// bit-packed sourceType, isPrimary, type
|
||||||
static final String FLAGS_COLUMN_NAME = "Flags";
|
static final String FLAGS_COLUMN_NAME = "Flags";
|
||||||
|
|
||||||
@DBAnnotatedColumn(TO_ADDR_COLUMN_NAME)
|
@DBAnnotatedColumn(TO_ADDR_MIN_COLUMN_NAME)
|
||||||
static DBObjectColumn TO_ADDR_COLUMN;
|
static DBObjectColumn TO_ADDR_MIN_COLUMN;
|
||||||
|
@DBAnnotatedColumn(TO_ADDR_MAX_COLUMN_NAME)
|
||||||
|
static DBObjectColumn TO_ADDR_MAX_COLUMN;
|
||||||
@DBAnnotatedColumn(SYMBOL_ID_COLUMN_NAME)
|
@DBAnnotatedColumn(SYMBOL_ID_COLUMN_NAME)
|
||||||
static DBObjectColumn SYMBOL_ID_COLUMN;
|
static DBObjectColumn SYMBOL_ID_COLUMN;
|
||||||
@DBAnnotatedColumn(REF_TYPE_COLUMN_NAME)
|
@DBAnnotatedColumn(REF_TYPE_COLUMN_NAME)
|
||||||
|
@ -140,10 +143,15 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
}
|
}
|
||||||
|
|
||||||
@DBAnnotatedField(
|
@DBAnnotatedField(
|
||||||
column = TO_ADDR_COLUMN_NAME,
|
column = TO_ADDR_MIN_COLUMN_NAME,
|
||||||
indexed = true,
|
indexed = true,
|
||||||
codec = AddressDBFieldCodec.class)
|
codec = AddressDBFieldCodec.class)
|
||||||
protected Address toAddress = Address.NO_ADDRESS;
|
protected Address toAddrMin = Address.NO_ADDRESS;
|
||||||
|
@DBAnnotatedField(
|
||||||
|
column = TO_ADDR_MAX_COLUMN_NAME,
|
||||||
|
indexed = true,
|
||||||
|
codec = AddressDBFieldCodec.class)
|
||||||
|
protected Address toAddrMax = Address.NO_ADDRESS;
|
||||||
@DBAnnotatedField(column = SYMBOL_ID_COLUMN_NAME, indexed = true)
|
@DBAnnotatedField(column = SYMBOL_ID_COLUMN_NAME, indexed = true)
|
||||||
protected long symbolId; // TODO: Is this at the from or to address? I think TO...
|
protected long symbolId; // TODO: Is this at the from or to address? I think TO...
|
||||||
@DBAnnotatedField(column = REF_TYPE_COLUMN_NAME, codec = RefTypeDBFieldCodec.class)
|
@DBAnnotatedField(column = REF_TYPE_COLUMN_NAME, codec = RefTypeDBFieldCodec.class)
|
||||||
|
@ -157,6 +165,7 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
|
|
||||||
protected final DBTraceReferenceSpace space;
|
protected final DBTraceReferenceSpace space;
|
||||||
|
|
||||||
|
protected AddressRange toRange;
|
||||||
protected DBTraceReference ref;
|
protected DBTraceReference ref;
|
||||||
|
|
||||||
public DBTraceReferenceEntry(DBTraceReferenceSpace space,
|
public DBTraceReferenceEntry(DBTraceReferenceSpace space,
|
||||||
|
@ -177,6 +186,7 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
if (created) {
|
if (created) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
toRange = new AddressRangeImpl(toAddrMin, toAddrMax);
|
||||||
TypeEnum type = TypeEnum.values()[(flags >> TYPE_SHIFT) & TYPE_MASK];
|
TypeEnum type = TypeEnum.values()[(flags >> TYPE_SHIFT) & TYPE_MASK];
|
||||||
ref = type.construct(this);
|
ref = type.construct(this);
|
||||||
}
|
}
|
||||||
|
@ -191,17 +201,20 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void set(Address toAddress, long symbolId, RefType refType, int opIndex, long ext,
|
protected void set(AddressRange toRange, long symbolId, RefType refType,
|
||||||
boolean isPrimary, TypeEnum type, SourceType sourceType) {
|
int opIndex, long ext, boolean isPrimary, TypeEnum type, SourceType sourceType) {
|
||||||
this.toAddress = toAddress;
|
this.toAddrMin = toRange.getMinAddress();
|
||||||
|
this.toAddrMax = toRange.getMaxAddress();
|
||||||
this.symbolId = symbolId;
|
this.symbolId = symbolId;
|
||||||
this.refType = refType;
|
this.refType = refType;
|
||||||
this.opIndex = (byte) opIndex;
|
this.opIndex = (byte) opIndex;
|
||||||
this.ext = ext;
|
this.ext = ext;
|
||||||
this.flags = (byte) ((isPrimary ? PRIMARY_MASK : 0) |
|
this.flags = (byte) ((isPrimary ? PRIMARY_MASK : 0) |
|
||||||
(sourceType.ordinal() << SOURCE_SHIFT) | type.ordinal() << TYPE_SHIFT);
|
(sourceType.ordinal() << SOURCE_SHIFT) | type.ordinal() << TYPE_SHIFT);
|
||||||
update(TO_ADDR_COLUMN, SYMBOL_ID_COLUMN, REF_TYPE_COLUMN, OP_INDEX_COLUMN, EXT_COLUMN,
|
update(TO_ADDR_MIN_COLUMN, TO_ADDR_MAX_COLUMN, SYMBOL_ID_COLUMN, REF_TYPE_COLUMN,
|
||||||
FLAGS_COLUMN);
|
OP_INDEX_COLUMN, EXT_COLUMN, FLAGS_COLUMN);
|
||||||
|
|
||||||
|
this.toRange = toRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setLifespan(Lifespan lifespan) {
|
protected void setLifespan(Lifespan lifespan) {
|
||||||
|
@ -369,7 +382,7 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
|
|
||||||
protected void doAddXRef(DBTraceReferenceEntry refEnt) {
|
protected void doAddXRef(DBTraceReferenceEntry refEnt) {
|
||||||
// Note: called from manager on relevant space
|
// Note: called from manager on relevant space
|
||||||
DBTraceXRefEntry xrefEnt = xrefMapSpace.put(refEnt.toAddress, refEnt.getLifespan(), null);
|
DBTraceXRefEntry xrefEnt = xrefMapSpace.put(refEnt.toRange, refEnt.getLifespan(), null);
|
||||||
xrefEnt.set((short) refEnt.getRange().getAddressSpace().getSpaceID(),
|
xrefEnt.set((short) refEnt.getRange().getAddressSpace().getSpaceID(),
|
||||||
refEnt.getKey());
|
refEnt.getKey());
|
||||||
}
|
}
|
||||||
|
@ -428,40 +441,40 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
return addShiftedReference(lifespan, sRef.getFromAddress(), sRef.getToAddress(),
|
return addShiftedReference(lifespan, sRef.getFromAddress(), sRef.getToAddress(),
|
||||||
sRef.getShift(), sRef.getReferenceType(), sRef.getSource(), sRef.getOperandIndex());
|
sRef.getShift(), sRef.getReferenceType(), sRef.getSource(), sRef.getOperandIndex());
|
||||||
}
|
}
|
||||||
return addMemoryReference(lifespan, reference.getFromAddress(), reference.getToAddress(),
|
AddressRange toRange = (reference instanceof TraceReference tref) ? tref.getToRange()
|
||||||
|
: new AddressRangeImpl(reference.getToAddress(), reference.getToAddress());
|
||||||
|
return addMemoryReference(lifespan, reference.getFromAddress(), toRange,
|
||||||
reference.getReferenceType(), reference.getSource(), reference.getOperandIndex());
|
reference.getReferenceType(), reference.getSource(), reference.getOperandIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void makeWay(Lifespan span, Address fromAddress, Address toAddress,
|
protected void makeWay(Lifespan span, Address fromAddress, AddressRange toRange,
|
||||||
int operandIndex) {
|
int operandIndex) {
|
||||||
// TODO: Do I consider "compatibility?" as in ReferenceDBManager?
|
// Do I consider "compatibility?" as in ReferenceDBManager?
|
||||||
// NOTE: Always call with the write lock
|
// NOTE: Always call with the write lock
|
||||||
for (DBTraceReferenceEntry ent : referenceMapSpace.reduce(
|
for (DBTraceReferenceEntry ent : referenceMapSpace.reduce(
|
||||||
TraceAddressSnapRangeQuery.intersecting(new AddressRangeImpl(fromAddress, fromAddress),
|
TraceAddressSnapRangeQuery.intersecting(new AddressRangeImpl(fromAddress, fromAddress),
|
||||||
span)).values()) {
|
span)).values()) {
|
||||||
if (!ent.toAddress.equals(toAddress)) {
|
if (!ent.toRange.equals(toRange) ||
|
||||||
continue;
|
ent.opIndex != operandIndex) {
|
||||||
}
|
|
||||||
if (ent.opIndex != operandIndex) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This sends events and updates primary. Do I want that here?
|
// This sends events and updates primary. Do I want that here?
|
||||||
DBTraceUtils.makeWay(ent, span, (e, s) -> e.setLifespan(s), e -> e.ref.delete());
|
DBTraceUtils.makeWay(ent, span, (e, s) -> e.setLifespan(s), e -> e.ref.delete());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DBTraceReference addMemoryReference(Lifespan lifespan, Address fromAddress,
|
public DBTraceReference addMemoryReference(Lifespan lifespan, Address fromAddress,
|
||||||
Address toAddress, RefType refType, SourceType source, int operandIndex) {
|
AddressRange toRange, RefType refType, SourceType source, int operandIndex) {
|
||||||
if (operandIndex < -1) {
|
if (operandIndex < -1) {
|
||||||
throw new IllegalArgumentException("operandIndex");
|
throw new IllegalArgumentException("operandIndex");
|
||||||
}
|
}
|
||||||
try (LockHold hold = LockHold.lock(lock.writeLock())) {
|
try (LockHold hold = LockHold.lock(lock.writeLock())) {
|
||||||
makeWay(lifespan, fromAddress, toAddress, operandIndex);
|
makeWay(lifespan, fromAddress, toRange, operandIndex);
|
||||||
|
|
||||||
DBTraceReferenceEntry entry = referenceMapSpace.put(fromAddress, lifespan, null);
|
DBTraceReferenceEntry entry = referenceMapSpace.put(fromAddress, lifespan, null);
|
||||||
entry.set(toAddress, -1, refType, operandIndex, 0, false, TypeEnum.MEMORY, source);
|
entry.set(toRange, -1, refType, operandIndex, 0, false, TypeEnum.MEMORY, source);
|
||||||
DBTraceReference ref = TypeEnum.MEMORY.construct(entry);
|
DBTraceReference ref = TypeEnum.MEMORY.construct(entry);
|
||||||
entry.ref = ref;
|
entry.ref = ref;
|
||||||
manager.doAddXRef(entry);
|
manager.doAddXRef(entry);
|
||||||
|
@ -520,10 +533,11 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
" produces bad Xref into EXTERNAL block");
|
" produces bad Xref into EXTERNAL block");
|
||||||
}
|
}
|
||||||
|
|
||||||
makeWay(lifespan, fromAddress, toAddress, operandIndex);
|
AddressRange toRange = new AddressRangeImpl(toAddress, toAddress);
|
||||||
|
makeWay(lifespan, fromAddress, toRange, operandIndex);
|
||||||
|
|
||||||
DBTraceReferenceEntry entry = referenceMapSpace.put(fromAddress, lifespan, null);
|
DBTraceReferenceEntry entry = referenceMapSpace.put(fromAddress, lifespan, null);
|
||||||
entry.set(toAddress, -1, refType, operandIndex, offset, false, type, source);
|
entry.set(toRange, -1, refType, operandIndex, offset, false, type, source);
|
||||||
DBTraceOffsetReference ref = new DBTraceOffsetReference(entry, isExternalBlockRef);
|
DBTraceOffsetReference ref = new DBTraceOffsetReference(entry, isExternalBlockRef);
|
||||||
entry.ref = ref;
|
entry.ref = ref;
|
||||||
manager.doAddXRef(entry);
|
manager.doAddXRef(entry);
|
||||||
|
@ -538,10 +552,11 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
throw new IllegalArgumentException("operandIndex");
|
throw new IllegalArgumentException("operandIndex");
|
||||||
}
|
}
|
||||||
try (LockHold hold = LockHold.lock(lock.writeLock())) {
|
try (LockHold hold = LockHold.lock(lock.writeLock())) {
|
||||||
makeWay(lifespan, fromAddress, toAddress, operandIndex);
|
AddressRange toRange = new AddressRangeImpl(toAddress, toAddress);
|
||||||
|
makeWay(lifespan, fromAddress, toRange, operandIndex);
|
||||||
|
|
||||||
DBTraceReferenceEntry entry = referenceMapSpace.put(fromAddress, lifespan, null);
|
DBTraceReferenceEntry entry = referenceMapSpace.put(fromAddress, lifespan, null);
|
||||||
entry.set(toAddress, -1, refType, operandIndex, shift, false, TypeEnum.SHIFT, source);
|
entry.set(toRange, -1, refType, operandIndex, shift, false, TypeEnum.SHIFT, source);
|
||||||
DBTraceShiftedReference ref = new DBTraceShiftedReference(entry);
|
DBTraceShiftedReference ref = new DBTraceShiftedReference(entry);
|
||||||
entry.ref = ref;
|
entry.ref = ref;
|
||||||
manager.doAddXRef(entry);
|
manager.doAddXRef(entry);
|
||||||
|
@ -552,8 +567,8 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
@Override
|
@Override
|
||||||
public DBTraceReference addRegisterReference(Lifespan lifespan, Address fromAddress,
|
public DBTraceReference addRegisterReference(Lifespan lifespan, Address fromAddress,
|
||||||
Register toRegister, RefType refType, SourceType source, int operandIndex) {
|
Register toRegister, RefType refType, SourceType source, int operandIndex) {
|
||||||
return addMemoryReference(lifespan, fromAddress, toRegister.getAddress(), refType, source,
|
return addMemoryReference(lifespan, fromAddress,
|
||||||
operandIndex);
|
TraceRegisterUtils.rangeForRegister(toRegister), refType, source, operandIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -561,20 +576,19 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
int toStackOffset, RefType refType, SourceType source, int operandIndex) {
|
int toStackOffset, RefType refType, SourceType source, int operandIndex) {
|
||||||
// TODO: base and guest compiler specs, too?
|
// TODO: base and guest compiler specs, too?
|
||||||
AddressSpace stack = baseLanguage.getDefaultCompilerSpec().getStackSpace();
|
AddressSpace stack = baseLanguage.getDefaultCompilerSpec().getStackSpace();
|
||||||
return addMemoryReference(lifespan, fromAddress, stack.getAddress(toStackOffset), refType,
|
Address toAddress = stack.getAddress(toStackOffset);
|
||||||
source, operandIndex);
|
AddressRange toRange = new AddressRangeImpl(toAddress, toAddress);
|
||||||
|
return addMemoryReference(lifespan, fromAddress, toRange, refType, source, operandIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DBTraceReference getReference(long snap, Address fromAddress, Address toAddress,
|
public DBTraceReference getReference(long snap, Address fromAddress, AddressRange toRange,
|
||||||
int operandIndex) {
|
int operandIndex) {
|
||||||
try (LockHold hold = LockHold.lock(lock.readLock())) {
|
try (LockHold hold = LockHold.lock(lock.readLock())) {
|
||||||
for (DBTraceReferenceEntry entry : referenceMapSpace.reduce(
|
for (DBTraceReferenceEntry entry : referenceMapSpace.reduce(
|
||||||
TraceAddressSnapRangeQuery.at(fromAddress, snap)).values()) {
|
TraceAddressSnapRangeQuery.at(fromAddress, snap)).values()) {
|
||||||
if (!toAddress.equals(entry.toAddress)) {
|
if (!entry.toRange.equals(toRange) ||
|
||||||
continue;
|
entry.opIndex != operandIndex) {
|
||||||
}
|
|
||||||
if (entry.opIndex != operandIndex) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return entry.ref;
|
return entry.ref;
|
||||||
|
@ -667,9 +681,10 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<? extends DBTraceReference> getReferencesToRange(Lifespan span,
|
public Collection<? extends DBTraceReference> getReferencesToRange(Lifespan span,
|
||||||
AddressRange range) {
|
AddressRange range, Rectangle2DDirection order) {
|
||||||
return new LazyCollection<>(
|
return new LazyCollection<>(
|
||||||
() -> xrefMapSpace.reduce(TraceAddressSnapRangeQuery.intersecting(range, span))
|
() -> xrefMapSpace
|
||||||
|
.reduce(TraceAddressSnapRangeQuery.intersecting(range, span).starting(order))
|
||||||
.values()
|
.values()
|
||||||
.stream()
|
.stream()
|
||||||
.map(this::getRefForXRefEntry));
|
.map(this::getRefForXRefEntry));
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -30,6 +30,6 @@ public class DBTraceShiftedReference extends DBTraceReference implements TraceSh
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getValue() {
|
public long getValue() {
|
||||||
return ent.toAddress.getOffset() >> ent.ext;
|
return ent.toAddrMin.getOffset() >> ent.ext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.trace.model.symbol;
|
package ghidra.trace.model.symbol;
|
||||||
|
|
||||||
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.symbol.OffsetReference;
|
import ghidra.program.model.symbol.OffsetReference;
|
||||||
|
|
||||||
public interface TraceOffsetReference extends TraceReference, OffsetReference {
|
public interface TraceOffsetReference extends TraceReference, OffsetReference {
|
||||||
|
@ -22,4 +23,9 @@ public interface TraceOffsetReference extends TraceReference, OffsetReference {
|
||||||
default boolean isOffsetReference() {
|
default boolean isOffsetReference() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default Address getToAddress() {
|
||||||
|
return TraceReference.super.getToAddress();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -15,17 +15,69 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.trace.model.symbol;
|
package ghidra.trace.model.symbol;
|
||||||
|
|
||||||
|
import ghidra.program.model.address.Address;
|
||||||
|
import ghidra.program.model.address.AddressRange;
|
||||||
import ghidra.program.model.symbol.*;
|
import ghidra.program.model.symbol.*;
|
||||||
import ghidra.trace.model.Lifespan;
|
import ghidra.trace.model.Lifespan;
|
||||||
import ghidra.trace.model.Trace;
|
import ghidra.trace.model.Trace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link Reference} within a {@link Trace}
|
||||||
|
*/
|
||||||
public interface TraceReference extends Reference {
|
public interface TraceReference extends Reference {
|
||||||
|
/**
|
||||||
|
* Get the trace containing this reference
|
||||||
|
*
|
||||||
|
* @return the trace
|
||||||
|
*/
|
||||||
Trace getTrace();
|
Trace getTrace();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the lifespan for which this reference is effective
|
||||||
|
*
|
||||||
|
* @return the lifespan
|
||||||
|
*/
|
||||||
Lifespan getLifespan();
|
Lifespan getLifespan();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the starting snapshot key of this reference's lifespan
|
||||||
|
*
|
||||||
|
* @return the starting snapshot
|
||||||
|
* @see #getLifespan()
|
||||||
|
*/
|
||||||
long getStartSnap();
|
long getStartSnap();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the "to" range of this reference.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Because references are often used in traces to indicate <em>actual</em> run-time writes, it
|
||||||
|
* is not sufficient to examine the code unit at a single "to" address and assume the reference
|
||||||
|
* is to the entire unit. For one, the read might be of a specific field in a structure data
|
||||||
|
* unit. For two, a read of a large unit may be implemented as a loop of several smaller reads.
|
||||||
|
* The trace could (and probably should) record each atomic read. In theory, one could examine
|
||||||
|
* the "from" instruction and operand index to derive the length, but that is onerous and not
|
||||||
|
* indexed. So instead, we record the exact "to" range in each reference and index it. This
|
||||||
|
* allows for easy implementation of, e.g., access breakpoints.
|
||||||
|
*
|
||||||
|
* @return the to range
|
||||||
|
*/
|
||||||
|
AddressRange getToRange();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* For a trace reference, the "to" part is actually a range. This returns the minimum address of
|
||||||
|
* that range.
|
||||||
|
*
|
||||||
|
* @see #getToRange()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default Address getToAddress() {
|
||||||
|
return getToRange().getMinAddress();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make this reference primary.
|
* Make this reference primary.
|
||||||
*
|
*
|
||||||
|
@ -43,10 +95,27 @@ public interface TraceReference extends Reference {
|
||||||
*/
|
*/
|
||||||
void setReferenceType(RefType refType);
|
void setReferenceType(RefType refType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the symbol associated with this reference
|
||||||
|
*
|
||||||
|
* @param symbol the symbol
|
||||||
|
* @see #getSymbolID()
|
||||||
|
*/
|
||||||
void setAssociatedSymbol(Symbol symbol);
|
void setAssociatedSymbol(Symbol symbol);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the associated symbol
|
||||||
|
*
|
||||||
|
* @see #getSymbolID()
|
||||||
|
*/
|
||||||
void clearAssociatedSymbol();
|
void clearAssociatedSymbol();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the symbol associated with this reference
|
||||||
|
*
|
||||||
|
* @return the symbol
|
||||||
|
* @see #getSymbolID()
|
||||||
|
*/
|
||||||
default Symbol getAssociatedSymbol() {
|
default Symbol getAssociatedSymbol() {
|
||||||
long id = getSymbolID();
|
long id = getSymbolID();
|
||||||
return id == -1 ? null : getTrace().getSymbolManager().getSymbolByID(id);
|
return id == -1 ? null : getTrace().getSymbolManager().getSymbolByID(id);
|
||||||
|
@ -115,5 +184,8 @@ public interface TraceReference extends Reference {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete this reference
|
||||||
|
*/
|
||||||
void delete();
|
void delete();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -21,93 +21,355 @@ import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.lang.Register;
|
import ghidra.program.model.lang.Register;
|
||||||
import ghidra.program.model.symbol.*;
|
import ghidra.program.model.symbol.*;
|
||||||
import ghidra.trace.model.Lifespan;
|
import ghidra.trace.model.Lifespan;
|
||||||
|
import ghidra.util.database.spatial.rect.Rectangle2DDirection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The operations for adding and retrieving references
|
||||||
|
*/
|
||||||
public interface TraceReferenceOperations {
|
public interface TraceReferenceOperations {
|
||||||
|
/**
|
||||||
|
* A (a copy of) the given reference to this manager
|
||||||
|
*
|
||||||
|
* @param reference the reference to add
|
||||||
|
* @return the resulting reference
|
||||||
|
*/
|
||||||
TraceReference addReference(TraceReference reference);
|
TraceReference addReference(TraceReference reference);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A (a copy of) the given reference to this manager
|
||||||
|
*
|
||||||
|
* @param lifespan the span of time where this reference applies
|
||||||
|
* @param reference the reference
|
||||||
|
* @return the resulting reference
|
||||||
|
*/
|
||||||
TraceReference addReference(Lifespan lifespan, Reference reference);
|
TraceReference addReference(Lifespan lifespan, Reference reference);
|
||||||
|
|
||||||
TraceReference addMemoryReference(Lifespan lifespan, Address fromAddress, Address toAddress,
|
/**
|
||||||
|
* Add a memory reference
|
||||||
|
*
|
||||||
|
* @param lifespan the span of time where this reference applies
|
||||||
|
* @param fromAddress the from address of the reference
|
||||||
|
* @param toRange the to addresses of the reference
|
||||||
|
* @param refType the type of reference
|
||||||
|
* @param source how this reference was derived
|
||||||
|
* @param operandIndex the operand index for the "from" end, or -1
|
||||||
|
* @return the resulting reference
|
||||||
|
*/
|
||||||
|
TraceReference addMemoryReference(Lifespan lifespan, Address fromAddress, AddressRange toRange,
|
||||||
RefType refType, SourceType source, int operandIndex);
|
RefType refType, SourceType source, int operandIndex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a memory reference
|
||||||
|
*
|
||||||
|
* @param lifespan the span of time where this reference applies
|
||||||
|
* @param fromAddress the from address of the reference
|
||||||
|
* @param toAddress the to address of the reference
|
||||||
|
* @param refType the type of reference
|
||||||
|
* @param source how this reference was derived
|
||||||
|
* @param operandIndex the operand index for the "from" end, or -1
|
||||||
|
* @return the resulting reference
|
||||||
|
*/
|
||||||
|
default TraceReference addMemoryReference(Lifespan lifespan, Address fromAddress,
|
||||||
|
Address toAddress, RefType refType, SourceType source, int operandIndex) {
|
||||||
|
return addMemoryReference(lifespan, fromAddress, new AddressRangeImpl(toAddress, toAddress),
|
||||||
|
refType, source, operandIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an offset memory reference
|
||||||
|
*
|
||||||
|
* @param lifespan the span of time where this reference applies
|
||||||
|
* @param fromAddress the from address of the reference
|
||||||
|
* @param toAddress the to address of the reference
|
||||||
|
* @param toAddrIsBase indicate whether or not toAddress incorporates the offset. False means
|
||||||
|
* toAddress=base+offset. True means toAddress=base.
|
||||||
|
* @param offset value added to the base address
|
||||||
|
* @param refType the type of reference
|
||||||
|
* @param source how this reference was derived
|
||||||
|
* @param operandIndex the operand index for the "from" end, or -1
|
||||||
|
* @return the resulting reference
|
||||||
|
*/
|
||||||
TraceOffsetReference addOffsetReference(Lifespan lifespan, Address fromAddress,
|
TraceOffsetReference addOffsetReference(Lifespan lifespan, Address fromAddress,
|
||||||
Address toAddress, boolean toAddrIsBase, long offset, RefType refType,
|
Address toAddress, boolean toAddrIsBase, long offset, RefType refType,
|
||||||
SourceType source, int operandIndex);
|
SourceType source, int operandIndex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a shifted memory reference
|
||||||
|
*
|
||||||
|
* @param lifespan the span of time where this reference applies
|
||||||
|
* @param fromAddress the from address of the reference
|
||||||
|
* @param toAddress the to address of the reference
|
||||||
|
* @param shift the number of bits to shift left
|
||||||
|
* @param refType the type of reference
|
||||||
|
* @param source how this reference was derived
|
||||||
|
* @param operandIndex the operand index for the "from" end, or -1
|
||||||
|
* @return the resulting reference
|
||||||
|
*/
|
||||||
TraceShiftedReference addShiftedReference(Lifespan lifespan, Address fromAddress,
|
TraceShiftedReference addShiftedReference(Lifespan lifespan, Address fromAddress,
|
||||||
Address toAddress, int shift, RefType refType, SourceType source, int operandIndex);
|
Address toAddress, int shift, RefType refType, SourceType source, int operandIndex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a register reference
|
||||||
|
*
|
||||||
|
* @param lifespan the span of time where this reference applies
|
||||||
|
* @param fromAddress the from address of the reference
|
||||||
|
* @param toRegister the to register of the reference
|
||||||
|
* @param refType the type of reference
|
||||||
|
* @param source how this reference was derived
|
||||||
|
* @param operandIndex the operand index for the "from" end, or -1
|
||||||
|
* @return the resulting reference
|
||||||
|
*/
|
||||||
TraceReference addRegisterReference(Lifespan lifespan, Address fromAddress,
|
TraceReference addRegisterReference(Lifespan lifespan, Address fromAddress,
|
||||||
Register toRegister, RefType refType, SourceType source, int operandIndex);
|
Register toRegister, RefType refType, SourceType source, int operandIndex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a (static) stack reference
|
||||||
|
*
|
||||||
|
* @param lifespan the span of time where this reference applies
|
||||||
|
* @param fromAddress the from address of the reference
|
||||||
|
* @param toStackOffset the to offset of the reference
|
||||||
|
* @param refType the type of reference
|
||||||
|
* @param source how this reference was derived
|
||||||
|
* @param operandIndex the operand index for the "from" end, or -1
|
||||||
|
* @return the resulting reference
|
||||||
|
*/
|
||||||
TraceReference addStackReference(Lifespan lifespan, Address fromAddress, int toStackOffset,
|
TraceReference addStackReference(Lifespan lifespan, Address fromAddress, int toStackOffset,
|
||||||
RefType refType, SourceType source, int operandIndex);
|
RefType refType, SourceType source, int operandIndex);
|
||||||
|
|
||||||
TraceReference getReference(long snap, Address fromAddress, Address toAddress,
|
/**
|
||||||
|
* Find the reference that matches the given parameters
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* <b>NOTE:</b> It is not sufficient to <em>intersect</em> the to range. It must exactly match
|
||||||
|
* that given.
|
||||||
|
*
|
||||||
|
* @param snap the snapshot key
|
||||||
|
* @param fromAddress the from address
|
||||||
|
* @param toRange the to address range
|
||||||
|
* @param operandIndex the operand index for the "from" end, or -1
|
||||||
|
* @return the found reference or null
|
||||||
|
*/
|
||||||
|
TraceReference getReference(long snap, Address fromAddress, AddressRange toRange,
|
||||||
int operandIndex);
|
int operandIndex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the reference that matches the given parameters
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* <b>NOTE:</b> It is not sufficient to <em>contain</em> the to address. To to range must be a
|
||||||
|
* singleton and exactly match that given. To match a range, see
|
||||||
|
* {@link #getReference(long, Address, AddressRange, int)}
|
||||||
|
*
|
||||||
|
* @param snap the snapshot key
|
||||||
|
* @param fromAddress the from address
|
||||||
|
* @param toAddress the to address
|
||||||
|
* @param operandIndex the operand index for the "from" end, or -1
|
||||||
|
* @return the found reference or null
|
||||||
|
*/
|
||||||
|
default TraceReference getReference(long snap, Address fromAddress, Address toAddress,
|
||||||
|
int operandIndex) {
|
||||||
|
return getReference(snap, fromAddress, new AddressRangeImpl(toAddress, toAddress),
|
||||||
|
operandIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all references from the given snapshot and address
|
||||||
|
*
|
||||||
|
* @param snap the snapshot key
|
||||||
|
* @param fromAddress the from address
|
||||||
|
* @return the collection of results
|
||||||
|
*/
|
||||||
Collection<? extends TraceReference> getReferencesFrom(long snap, Address fromAddress);
|
Collection<? extends TraceReference> getReferencesFrom(long snap, Address fromAddress);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all references from the given snapshot, address, and operand index
|
||||||
|
*
|
||||||
|
* @param snap the snapshot key
|
||||||
|
* @param fromAddress the from address
|
||||||
|
* @param operandIndex the operand index for the "from" end, or -1
|
||||||
|
* @return the collection of results
|
||||||
|
*/
|
||||||
Collection<? extends TraceReference> getReferencesFrom(long snap, Address fromAddress,
|
Collection<? extends TraceReference> getReferencesFrom(long snap, Address fromAddress,
|
||||||
int operandIndex);
|
int operandIndex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Document me
|
* Find all references with from addresses contained in the given lifespan and address range
|
||||||
*
|
*
|
||||||
* This returns all references from addresses within the given range, regardless of operand
|
* @param span the lifespan to examine
|
||||||
* index.
|
* @param range the range to examine
|
||||||
*
|
* @return the collection of results
|
||||||
* @param span
|
|
||||||
* @param range
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
Collection<? extends TraceReference> getReferencesFromRange(Lifespan span,
|
Collection<? extends TraceReference> getReferencesFromRange(Lifespan span,
|
||||||
AddressRange range);
|
AddressRange range);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the primary reference matching from the given snapshot, address, and operand index
|
||||||
|
*
|
||||||
|
* @param snap the snapshot key
|
||||||
|
* @param fromAddress the from address
|
||||||
|
* @param operandIndex the operand index for the "from" end, or -1
|
||||||
|
* @return the found reference or null
|
||||||
|
*/
|
||||||
TraceReference getPrimaryReferenceFrom(long snap, Address fromAddress, int operandIndex);
|
TraceReference getPrimaryReferenceFrom(long snap, Address fromAddress, int operandIndex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all flow references from the given snapshot and address
|
||||||
|
*
|
||||||
|
* @param snap the snapshot key
|
||||||
|
* @param fromAddress the from address
|
||||||
|
* @return the collection of results
|
||||||
|
*/
|
||||||
Collection<? extends TraceReference> getFlowReferencesFrom(long snap, Address fromAddress);
|
Collection<? extends TraceReference> getFlowReferencesFrom(long snap, Address fromAddress);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all references from the given lifespan and address range
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Any reference intersecting the given "from" parameters will have its lifespan truncated to
|
||||||
|
* the start of the given lifespan.
|
||||||
|
*
|
||||||
|
* @param span the lifespan to remove
|
||||||
|
* @param range the range to clear
|
||||||
|
*/
|
||||||
void clearReferencesFrom(Lifespan span, AddressRange range);
|
void clearReferencesFrom(Lifespan span, AddressRange range);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all references whose to address (or range) contains the given snapshot and address
|
||||||
|
*
|
||||||
|
* @param snap the snapshot key
|
||||||
|
* @param toAddress the to address
|
||||||
|
* @return the collection of results
|
||||||
|
*/
|
||||||
Collection<? extends TraceReference> getReferencesTo(long snap, Address toAddress);
|
Collection<? extends TraceReference> getReferencesTo(long snap, Address toAddress);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all references to the given lifespan and address range
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Any reference intersecting the given "to" parameters will have its lifespan truncated to the
|
||||||
|
* start of the given lifespan.
|
||||||
|
*
|
||||||
|
* @param span the lifespan to remove
|
||||||
|
* @param range the range of clear
|
||||||
|
*/
|
||||||
void clearReferencesTo(Lifespan span, AddressRange range);
|
void clearReferencesTo(Lifespan span, AddressRange range);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Document me
|
* Get all references whose to address range intersects the given lifespan and address range
|
||||||
*
|
*
|
||||||
* This returns all references to addresses within the given range, regardless of operand index.
|
* <p>
|
||||||
|
* The following iteration orders may be specified for the resulting (lazy) collection:
|
||||||
*
|
*
|
||||||
* @param span
|
* <ul>
|
||||||
* @param range
|
* <li>{@code null} - no particular order. This spares the cost of sorting.</li>
|
||||||
* @return
|
* <li>{@link Rectangle2DDirection#TOPMOST} - most-recent (latest snapshot) first.</li>
|
||||||
|
* <li>{@link Rectangle2DDirection#BOTTOMMOST} - least-recent (earliest including scratch
|
||||||
|
* snapshot first).</li>
|
||||||
|
* <li>{@link Rectangle2DDirection#LEFTMOST} - smallest address first.</li>
|
||||||
|
* <li>{@link Rectangle2DDirection#RIGHTMOST} - largest address first.</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* "Secondary" sorting is not supported.
|
||||||
|
*
|
||||||
|
* @param span the lifespan to examine
|
||||||
|
* @param range the range to examine
|
||||||
|
* @param order the order of items in the collection.
|
||||||
|
* @return the collection of results
|
||||||
*/
|
*/
|
||||||
Collection<? extends TraceReference> getReferencesToRange(Lifespan span, AddressRange range);
|
Collection<? extends TraceReference> getReferencesToRange(Lifespan span, AddressRange range,
|
||||||
|
Rectangle2DDirection order);
|
||||||
|
|
||||||
// TODO: Support Variable references
|
/**
|
||||||
|
* Get all references whose to address range intersects the given lifespan and address range
|
||||||
|
*
|
||||||
|
* @param span the lifespan to examine
|
||||||
|
* @param range the range to examine
|
||||||
|
* @return the collection of results
|
||||||
|
*/
|
||||||
|
default Collection<? extends TraceReference> getReferencesToRange(Lifespan span,
|
||||||
|
AddressRange range) {
|
||||||
|
return getReferencesToRange(span, range, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Variable references are not (yet?) supported
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if there exists a reference from the given snapshot and address
|
||||||
|
*
|
||||||
|
* @param snap the snapshot key
|
||||||
|
* @param fromAddress the from address
|
||||||
|
* @return true if one or more references exist
|
||||||
|
*/
|
||||||
default boolean hasReferencesFrom(long snap, Address fromAddress) {
|
default boolean hasReferencesFrom(long snap, Address fromAddress) {
|
||||||
return !getReferencesFrom(snap, fromAddress).isEmpty();
|
return !getReferencesFrom(snap, fromAddress).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if there exists a reference from the given snapshot, address, and operand
|
||||||
|
*
|
||||||
|
* @param snap the snapshot key
|
||||||
|
* @param fromAddress the from address
|
||||||
|
* @param operandIndex the operand index, or -1
|
||||||
|
* @return true if one or more references exist
|
||||||
|
*/
|
||||||
default boolean hasReferencesFrom(long snap, Address fromAddress, int operandIndex) {
|
default boolean hasReferencesFrom(long snap, Address fromAddress, int operandIndex) {
|
||||||
return !getReferencesFrom(snap, fromAddress, operandIndex).isEmpty();
|
return !getReferencesFrom(snap, fromAddress, operandIndex).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if there exists a flow reference from the given snapshot and address
|
||||||
|
*
|
||||||
|
* @param snap the snapshot key
|
||||||
|
* @param fromAddress the from address
|
||||||
|
* @return true if one or more flow references exist
|
||||||
|
*/
|
||||||
default boolean hasFlowReferencesFrom(long snap, Address fromAddress) {
|
default boolean hasFlowReferencesFrom(long snap, Address fromAddress) {
|
||||||
return !getFlowReferencesFrom(snap, fromAddress).isEmpty();
|
return !getFlowReferencesFrom(snap, fromAddress).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if there exists a reference to the given snapshot and address
|
||||||
|
*
|
||||||
|
* @param snap the snapshot key
|
||||||
|
* @param toAddress the to address
|
||||||
|
* @return true if one or more references exists
|
||||||
|
*/
|
||||||
default boolean hasReferencesTo(long snap, Address toAddress) {
|
default boolean hasReferencesTo(long snap, Address toAddress) {
|
||||||
return !getReferencesTo(snap, toAddress).isEmpty();
|
return !getReferencesTo(snap, toAddress).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an address set of all "from" addresses in any reference intersecting the given lifespan
|
||||||
|
*
|
||||||
|
* @param span the lifespan to examine
|
||||||
|
* @return a (lazily-computed) address set view of all "from" addresses
|
||||||
|
*/
|
||||||
AddressSetView getReferenceSources(Lifespan span);
|
AddressSetView getReferenceSources(Lifespan span);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an address set of all "to" addresses in any reference intersecting the given lifespan
|
||||||
|
*
|
||||||
|
* @param span the lifespan to examine
|
||||||
|
* @return a (lazily-computed) address set view of all "to" addresses
|
||||||
|
*/
|
||||||
AddressSetView getReferenceDestinations(Lifespan span);
|
AddressSetView getReferenceDestinations(Lifespan span);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count the number of references from the given snapshot and address
|
||||||
|
*
|
||||||
|
* @param snap the snapshot key
|
||||||
|
* @param fromAddress the from address
|
||||||
|
* @return the number of references
|
||||||
|
*/
|
||||||
int getReferenceCountFrom(long snap, Address fromAddress);
|
int getReferenceCountFrom(long snap, Address fromAddress);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Count the number of references to the given snapshot and address
|
||||||
|
*
|
||||||
|
* @param snap the snapshot key
|
||||||
|
* @param toAddress the to address
|
||||||
|
* @return the number of references
|
||||||
|
*/
|
||||||
int getReferenceCountTo(long snap, Address toAddress);
|
int getReferenceCountTo(long snap, Address toAddress);
|
||||||
}
|
}
|
||||||
|
|
|
@ -837,7 +837,7 @@ public class ToyDBTraceBuilder implements AutoCloseable {
|
||||||
* @param to the to address
|
* @param to the to address
|
||||||
* @return the reference
|
* @return the reference
|
||||||
*/
|
*/
|
||||||
public DBTraceReference addMemoryReference(long creationSnap, Address from, Address to) {
|
public DBTraceReference addMemoryReference(long creationSnap, Address from, AddressRange to) {
|
||||||
return addMemoryReference(creationSnap, from, to, -1);
|
return addMemoryReference(creationSnap, from, to, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -850,7 +850,7 @@ public class ToyDBTraceBuilder implements AutoCloseable {
|
||||||
* @param operandIndex the operand index, or -1 for mnemonic
|
* @param operandIndex the operand index, or -1 for mnemonic
|
||||||
* @return the reference
|
* @return the reference
|
||||||
*/
|
*/
|
||||||
public DBTraceReference addMemoryReference(long creationSnap, Address from, Address to,
|
public DBTraceReference addMemoryReference(long creationSnap, Address from, AddressRange to,
|
||||||
int operandIndex) {
|
int operandIndex) {
|
||||||
return trace.getReferenceManager()
|
return trace.getReferenceManager()
|
||||||
.addMemoryReference(Lifespan.nowOn(creationSnap), from, to, RefType.DATA,
|
.addMemoryReference(Lifespan.nowOn(creationSnap), from, to, RefType.DATA,
|
||||||
|
|
|
@ -38,7 +38,6 @@ import ghidra.trace.database.ToyDBTraceBuilder;
|
||||||
import ghidra.trace.database.listing.DBTraceCommentAdapter.DBTraceCommentEntry;
|
import ghidra.trace.database.listing.DBTraceCommentAdapter.DBTraceCommentEntry;
|
||||||
import ghidra.trace.database.map.DBTraceAddressSnapRangePropertyMapTree.TraceAddressSnapRangeQuery;
|
import ghidra.trace.database.map.DBTraceAddressSnapRangePropertyMapTree.TraceAddressSnapRangeQuery;
|
||||||
import ghidra.trace.database.memory.DBTraceMemorySpace;
|
import ghidra.trace.database.memory.DBTraceMemorySpace;
|
||||||
import ghidra.trace.database.symbol.DBTraceReference;
|
|
||||||
import ghidra.trace.model.Lifespan;
|
import ghidra.trace.model.Lifespan;
|
||||||
import ghidra.trace.model.guest.TraceGuestPlatform;
|
import ghidra.trace.model.guest.TraceGuestPlatform;
|
||||||
import ghidra.trace.model.listing.TraceData;
|
import ghidra.trace.model.listing.TraceData;
|
||||||
|
@ -52,7 +51,6 @@ import ghidra.trace.model.target.schema.XmlSchemaContext;
|
||||||
import ghidra.trace.model.thread.TraceThread;
|
import ghidra.trace.model.thread.TraceThread;
|
||||||
import ghidra.trace.util.TraceRegisterUtils;
|
import ghidra.trace.util.TraceRegisterUtils;
|
||||||
import ghidra.util.*;
|
import ghidra.util.*;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
|
||||||
import ghidra.util.exception.NoValueException;
|
import ghidra.util.exception.NoValueException;
|
||||||
import ghidra.util.map.TypeMismatchException;
|
import ghidra.util.map.TypeMismatchException;
|
||||||
|
|
||||||
|
@ -620,7 +618,7 @@ public class DBTraceCodeUnitTest extends AbstractGhidraHeadlessIntegrationTest {
|
||||||
|
|
||||||
assertEquals(Set.of(mnemRef, opRef, stackRef, regRef), set(i4004.getReferencesFrom()));
|
assertEquals(Set.of(mnemRef, opRef, stackRef, regRef), set(i4004.getReferencesFrom()));
|
||||||
|
|
||||||
DBTraceReference refTo;
|
TraceReference refTo;
|
||||||
try (Transaction tx = b.startTransaction()) {
|
try (Transaction tx = b.startTransaction()) {
|
||||||
refTo = b.trace.getReferenceManager()
|
refTo = b.trace.getReferenceManager()
|
||||||
.addMemoryReference(Lifespan.ALL, b.addr(0x3000), b.addr(0x4004),
|
.addMemoryReference(Lifespan.ALL, b.addr(0x3000), b.addr(0x4004),
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -19,19 +19,20 @@ import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.Collection;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
|
|
||||||
import db.Transaction;
|
import db.Transaction;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.address.AddressSpace;
|
|
||||||
import ghidra.program.model.symbol.*;
|
import ghidra.program.model.symbol.*;
|
||||||
import ghidra.test.AbstractGhidraHeadlessIntegrationTest;
|
import ghidra.test.AbstractGhidraHeadlessIntegrationTest;
|
||||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||||
import ghidra.trace.model.Lifespan;
|
import ghidra.trace.model.Lifespan;
|
||||||
import ghidra.trace.model.Trace;
|
import ghidra.trace.model.Trace;
|
||||||
import ghidra.trace.model.symbol.*;
|
import ghidra.trace.model.symbol.*;
|
||||||
|
import ghidra.trace.util.TraceRegisterUtils;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.exception.VersionException;
|
import ghidra.util.exception.VersionException;
|
||||||
|
|
||||||
|
@ -39,12 +40,12 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
protected static class DummyTraceReference implements TraceReference {
|
protected static class DummyTraceReference implements TraceReference {
|
||||||
protected final Lifespan lifespan;
|
protected final Lifespan lifespan;
|
||||||
protected final Address fromAddress;
|
protected final Address fromAddress;
|
||||||
protected final Address toAddress;
|
protected final AddressRange toRange;
|
||||||
|
|
||||||
public DummyTraceReference(long startSnap, Address fromAddress, Address toAddress) {
|
public DummyTraceReference(long startSnap, Address fromAddress, AddressRange toRange) {
|
||||||
this.lifespan = Lifespan.nowOn(startSnap);
|
this.lifespan = Lifespan.nowOn(startSnap);
|
||||||
this.fromAddress = fromAddress;
|
this.fromAddress = fromAddress;
|
||||||
this.toAddress = toAddress;
|
this.toRange = toRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -53,8 +54,8 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Address getToAddress() {
|
public AddressRange getToRange() {
|
||||||
return toAddress;
|
return toRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -130,7 +131,7 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
|
|
||||||
public DummyTraceOffsetReference(long startSnap, Address fromAddress, Address toAddress,
|
public DummyTraceOffsetReference(long startSnap, Address fromAddress, Address toAddress,
|
||||||
long offset) {
|
long offset) {
|
||||||
super(startSnap, fromAddress, toAddress);
|
super(startSnap, fromAddress, new AddressRangeImpl(toAddress, toAddress));
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
// NOTE: intended for test use in the absence of any EXTERNAL memory block concern
|
// NOTE: intended for test use in the absence of any EXTERNAL memory block concern
|
||||||
this.baseAddress = toAddress.subtract(offset);
|
this.baseAddress = toAddress.subtract(offset);
|
||||||
|
@ -154,7 +155,7 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
|
|
||||||
public DummyTraceShiftedReference(long startSnap, Address fromAddress, Address toAddress,
|
public DummyTraceShiftedReference(long startSnap, Address fromAddress, Address toAddress,
|
||||||
int shift) {
|
int shift) {
|
||||||
super(startSnap, fromAddress, toAddress);
|
super(startSnap, fromAddress, new AddressRangeImpl(toAddress, toAddress));
|
||||||
this.shift = shift;
|
this.shift = shift;
|
||||||
this.value = toAddress.getOffset() >>> shift;
|
this.value = toAddress.getOffset() >>> shift;
|
||||||
}
|
}
|
||||||
|
@ -190,8 +191,8 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
DBTraceReference offRef;
|
DBTraceReference offRef;
|
||||||
DBTraceReference sftRef;
|
DBTraceReference sftRef;
|
||||||
try (Transaction tx = b.startTransaction()) {
|
try (Transaction tx = b.startTransaction()) {
|
||||||
memRef =
|
memRef = manager.addReference(
|
||||||
manager.addReference(new DummyTraceReference(0, b.addr(0x4000), b.addr(0x5000)));
|
new DummyTraceReference(0, b.addr(0x4000), b.range(0x5000, 0x5003)));
|
||||||
offRef = manager.addReference(
|
offRef = manager.addReference(
|
||||||
new DummyTraceOffsetReference(0, b.addr(0x4001), b.addr(0x5001), 20));
|
new DummyTraceOffsetReference(0, b.addr(0x4001), b.addr(0x5001), 20));
|
||||||
sftRef = manager.addReference(
|
sftRef = manager.addReference(
|
||||||
|
@ -203,6 +204,7 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
assertTrue(sftRef instanceof DBTraceShiftedReference);
|
assertTrue(sftRef instanceof DBTraceShiftedReference);
|
||||||
|
|
||||||
assertEquals(b.addr(0x4000), memRef.getFromAddress());
|
assertEquals(b.addr(0x4000), memRef.getFromAddress());
|
||||||
|
assertEquals(b.range(0x5000, 0x5003), memRef.getToRange());
|
||||||
assertEquals(b.addr(0x5000), memRef.getToAddress());
|
assertEquals(b.addr(0x5000), memRef.getToAddress());
|
||||||
|
|
||||||
assertEquals(b.addr(0x4001), offRef.getFromAddress());
|
assertEquals(b.addr(0x4001), offRef.getFromAddress());
|
||||||
|
@ -219,7 +221,7 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
@Test
|
@Test
|
||||||
public void testAddMemoryReference() {
|
public void testAddMemoryReference() {
|
||||||
try (Transaction tx = b.startTransaction()) {
|
try (Transaction tx = b.startTransaction()) {
|
||||||
b.addMemoryReference(0, b.addr(0x4000), b.addr(0x5000));
|
b.addMemoryReference(0, b.addr(0x4000), b.range(0x5000, 0x5003));
|
||||||
}
|
}
|
||||||
DBTraceReferenceSpace space =
|
DBTraceReferenceSpace space =
|
||||||
manager.getReferenceSpace(b.language.getDefaultDataSpace(), false);
|
manager.getReferenceSpace(b.language.getDefaultDataSpace(), false);
|
||||||
|
@ -284,7 +286,7 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
DBTraceReference regRef;
|
DBTraceReference regRef;
|
||||||
DBTraceReference stkRef;
|
DBTraceReference stkRef;
|
||||||
try (Transaction tx = b.startTransaction()) {
|
try (Transaction tx = b.startTransaction()) {
|
||||||
memRef = b.addMemoryReference(0, b.addr(0x4000), b.addr(0x5000));
|
memRef = b.addMemoryReference(0, b.addr(0x4000), b.range(0x5000, 0x5003));
|
||||||
offRef = b.addOffsetReference(0, b.addr(0x4001), b.addr(0x5001), false, 20);
|
offRef = b.addOffsetReference(0, b.addr(0x4001), b.addr(0x5001), false, 20);
|
||||||
sftRef = b.addShiftedReference(0, b.addr(0x4002), b.addr(0x5002), 1);
|
sftRef = b.addShiftedReference(0, b.addr(0x4002), b.addr(0x5002), 1);
|
||||||
regRef = b.addRegisterReference(0, b.addr(0x4003), "r5");
|
regRef = b.addRegisterReference(0, b.addr(0x4003), "r5");
|
||||||
|
@ -292,20 +294,21 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
}
|
}
|
||||||
|
|
||||||
assertNull(manager.getReference(0, b.addr(0x4000), b.addr(0x5000), 0));
|
assertNull(manager.getReference(0, b.addr(0x4000), b.addr(0x5000), 0));
|
||||||
|
assertNull(manager.getReference(0, b.addr(0x4000), b.range(0x5000, 0x5003), 0));
|
||||||
assertNull(manager.getReference(0, b.addr(0x4000), b.addr(0x5001), -1));
|
assertNull(manager.getReference(0, b.addr(0x4000), b.addr(0x5001), -1));
|
||||||
assertNull(manager.getReference(0, b.addr(0x4001), b.addr(0x5000), -1));
|
assertNull(manager.getReference(0, b.addr(0x4001), b.addr(0x5000), -1));
|
||||||
assertNull(manager.getReference(-1, b.addr(0x4000), b.addr(0x5000), -1));
|
assertNull(manager.getReference(-1, b.addr(0x4000), b.addr(0x5000), -1));
|
||||||
assertEquals(memRef, manager.getReference(0, b.addr(0x4000), b.addr(0x5000), -1));
|
assertEquals(memRef, manager.getReference(0, b.addr(0x4000), b.range(0x5000, 0x5003), -1));
|
||||||
assertEquals(memRef, manager.getReference(10, b.addr(0x4000), b.addr(0x5000), -1));
|
assertEquals(memRef, manager.getReference(10, b.addr(0x4000), b.range(0x5000, 0x5003), -1));
|
||||||
|
|
||||||
assertEquals(offRef, manager.getReference(0, b.addr(0x4001), b.addr(0x5001), -1));
|
assertEquals(offRef, manager.getReference(0, b.addr(0x4001), b.addr(0x5001), -1));
|
||||||
|
|
||||||
assertEquals(sftRef, manager.getReference(0, b.addr(0x4002), b.addr(0x5002), -1));
|
assertEquals(sftRef, manager.getReference(0, b.addr(0x4002), b.addr(0x5002), -1));
|
||||||
|
|
||||||
assertEquals(regRef,
|
assertEquals(regRef, manager.getReference(0, b.addr(0x4003),
|
||||||
manager.getReference(0, b.addr(0x4003), b.language.getRegister("r5").getAddress(), -1));
|
TraceRegisterUtils.rangeForRegister(b.language.getRegister("r5")), -1));
|
||||||
assertNull(
|
assertNull(manager.getReference(0, b.addr(0x4003),
|
||||||
manager.getReference(0, b.addr(0x4003), b.language.getRegister("r6").getAddress(), -1));
|
TraceRegisterUtils.rangeForRegister(b.language.getRegister("r6")), -1));
|
||||||
|
|
||||||
// TODO: A better way to manage the compiler spec
|
// TODO: A better way to manage the compiler spec
|
||||||
assertEquals(stkRef, manager.getReference(0, b.addr(0x4004),
|
assertEquals(stkRef, manager.getReference(0, b.addr(0x4004),
|
||||||
|
@ -322,21 +325,21 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
DBTraceReference regRef;
|
DBTraceReference regRef;
|
||||||
DBTraceReference stkRef;
|
DBTraceReference stkRef;
|
||||||
try (Transaction tx = b.startTransaction()) {
|
try (Transaction tx = b.startTransaction()) {
|
||||||
memRef = b.addMemoryReference(0, b.addr(0x4000), b.addr(0x5000), 3);
|
memRef = b.addMemoryReference(0, b.addr(0x4000), b.range(0x5000, 0x5003), 3);
|
||||||
offRef = b.addOffsetReference(0, b.addr(0x4000), b.addr(0x5001), false, 20);
|
offRef = b.addOffsetReference(0, b.addr(0x4000), b.addr(0x5001), false, 20);
|
||||||
sftRef = b.addShiftedReference(0, b.addr(0x4000), b.addr(0x5002), 1);
|
sftRef = b.addShiftedReference(0, b.addr(0x4000), b.addr(0x5002), 1);
|
||||||
regRef = b.addRegisterReference(0, b.addr(0x4000), "r5");
|
regRef = b.addRegisterReference(0, b.addr(0x4000), "r5");
|
||||||
stkRef = b.addStackReference(0, b.addr(0x4000), 0x20);
|
stkRef = b.addStackReference(0, b.addr(0x4000), 0x20);
|
||||||
|
|
||||||
b.addMemoryReference(0, b.addr(0x4001), b.addr(0x8000));
|
b.addMemoryReference(0, b.addr(0x4001), b.range(0x8000, 0x8003));
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(Set.of(memRef, offRef, sftRef, regRef, stkRef),
|
assertEquals(Set.of(memRef, offRef, sftRef, regRef, stkRef),
|
||||||
new HashSet<>(manager.getReferencesFrom(0, b.addr(0x4000))));
|
Set.copyOf(manager.getReferencesFrom(0, b.addr(0x4000))));
|
||||||
assertEquals(Set.of(memRef),
|
assertEquals(Set.of(memRef),
|
||||||
new HashSet<>(manager.getReferencesFrom(0, b.addr(0x4000), 3)));
|
Set.copyOf(manager.getReferencesFrom(0, b.addr(0x4000), 3)));
|
||||||
assertEquals(Set.of(offRef, sftRef, regRef, stkRef),
|
assertEquals(Set.of(offRef, sftRef, regRef, stkRef),
|
||||||
new HashSet<>(manager.getReferencesFrom(0, b.addr(0x4000), -1)));
|
Set.copyOf(manager.getReferencesFrom(0, b.addr(0x4000), -1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -347,23 +350,23 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
DBTraceReference diffTo;
|
DBTraceReference diffTo;
|
||||||
DBTraceReference diffOpIndex;
|
DBTraceReference diffOpIndex;
|
||||||
try (Transaction tx = b.startTransaction()) {
|
try (Transaction tx = b.startTransaction()) {
|
||||||
at0 = b.addMemoryReference(0, b.addr(0x4000), b.addr(0x5000), 0);
|
at0 = b.addMemoryReference(0, b.addr(0x4000), b.range(0x5000, 0x5003), 0);
|
||||||
b.addMemoryReference(15, b.addr(0x4000), b.addr(0x5000), 0); // Lost
|
b.addMemoryReference(15, b.addr(0x4000), b.range(0x5000, 0x5003), 0); // Lost
|
||||||
at10 = b.addMemoryReference(10, b.addr(0x4000), b.addr(0x5000), 0);
|
at10 = b.addMemoryReference(10, b.addr(0x4000), b.range(0x5000, 0x5003), 0);
|
||||||
|
|
||||||
diffFrom = b.addMemoryReference(0, b.addr(0x4001), b.addr(0x5000), 0);
|
diffFrom = b.addMemoryReference(0, b.addr(0x4001), b.range(0x5000, 0x5003), 0);
|
||||||
diffTo = b.addMemoryReference(0, b.addr(0x4000), b.addr(0x5001), 0);
|
diffTo = b.addMemoryReference(0, b.addr(0x4000), b.range(0x5004, 0x5007), 0);
|
||||||
diffOpIndex = b.addMemoryReference(0, b.addr(0x4000), b.addr(0x5000), 1);
|
diffOpIndex = b.addMemoryReference(0, b.addr(0x4000), b.range(0x5000, 0x5003), 1);
|
||||||
|
|
||||||
assertEquals(Set.of(at0, diffTo, diffOpIndex),
|
assertEquals(Set.of(at0, diffTo, diffOpIndex),
|
||||||
new HashSet<>(manager.getReferencesFrom(0, b.addr(0x4000))));
|
Set.copyOf(manager.getReferencesFrom(0, b.addr(0x4000))));
|
||||||
assertEquals(Set.of(at10, diffTo, diffOpIndex),
|
assertEquals(Set.of(at10, diffTo, diffOpIndex),
|
||||||
new HashSet<>(manager.getReferencesFrom(15, b.addr(0x4000))));
|
Set.copyOf(manager.getReferencesFrom(15, b.addr(0x4000))));
|
||||||
|
|
||||||
assertEquals(Set.of(diffFrom),
|
assertEquals(Set.of(diffFrom),
|
||||||
new HashSet<>(manager.getReferencesFrom(0, b.addr(0x4001))));
|
Set.copyOf(manager.getReferencesFrom(0, b.addr(0x4001))));
|
||||||
assertEquals(Set.of(diffFrom),
|
assertEquals(Set.of(diffFrom),
|
||||||
new HashSet<>(manager.getReferencesFrom(15, b.addr(0x4001))));
|
Set.copyOf(manager.getReferencesFrom(15, b.addr(0x4001))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,7 +378,7 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
DBTraceReference memRef;
|
DBTraceReference memRef;
|
||||||
DBTraceReference offRef;
|
DBTraceReference offRef;
|
||||||
try (Transaction tx = b.startTransaction()) {
|
try (Transaction tx = b.startTransaction()) {
|
||||||
memRef = b.addMemoryReference(0, b.addr(0x4000), b.addr(0x5000));
|
memRef = b.addMemoryReference(0, b.addr(0x4000), b.range(0x5000, 0x5003));
|
||||||
offRef = b.addOffsetReference(0, b.addr(0x4000), b.addr(0x5001), false, 20);
|
offRef = b.addOffsetReference(0, b.addr(0x4000), b.addr(0x5001), false, 20);
|
||||||
|
|
||||||
assertNull(manager.getPrimaryReferenceFrom(0, b.addr(0x4000), -1));
|
assertNull(manager.getPrimaryReferenceFrom(0, b.addr(0x4000), -1));
|
||||||
|
@ -395,28 +398,28 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetFlowReferencesFrom() {
|
public void testGetFlowReferencesFrom() {
|
||||||
DBTraceReference flowRef;
|
TraceReference flowRef;
|
||||||
try (Transaction tx = b.startTransaction()) {
|
try (Transaction tx = b.startTransaction()) {
|
||||||
flowRef = manager.addMemoryReference(Lifespan.nowOn(0), b.addr(0x4000), b.addr(0x4001),
|
flowRef = manager.addMemoryReference(Lifespan.nowOn(0), b.addr(0x4000), b.addr(0x4001),
|
||||||
RefType.FLOW, SourceType.DEFAULT, -1);
|
RefType.FLOW, SourceType.DEFAULT, -1);
|
||||||
b.addMemoryReference(0, b.addr(0x4000), b.addr(0x5000));
|
b.addMemoryReference(0, b.addr(0x4000), b.range(0x5000, 0x5003));
|
||||||
b.addOffsetReference(0, b.addr(0x4000), b.addr(0x5001), false, 20);
|
b.addOffsetReference(0, b.addr(0x4000), b.addr(0x5001), false, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(Set.of(flowRef),
|
assertEquals(Set.of(flowRef),
|
||||||
new HashSet<>(manager.getFlowReferencesFrom(0, b.addr(0x4000))));
|
Set.copyOf(manager.getFlowReferencesFrom(0, b.addr(0x4000))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testClearReferencesFrom() {
|
public void testClearReferencesFrom() {
|
||||||
DBTraceReference keptRef;
|
DBTraceReference keptRef;
|
||||||
try (Transaction tx = b.startTransaction()) {
|
try (Transaction tx = b.startTransaction()) {
|
||||||
b.addMemoryReference(0, b.addr(0x4000), b.addr(0x5000), 3);
|
b.addMemoryReference(0, b.addr(0x4000), b.range(0x5000, 0x5003), 3);
|
||||||
b.addOffsetReference(0, b.addr(0x4000), b.addr(0x5001), false, 20);
|
b.addOffsetReference(0, b.addr(0x4000), b.addr(0x5001), false, 20);
|
||||||
b.addShiftedReference(0, b.addr(0x4000), b.addr(0x5002), 1);
|
b.addShiftedReference(0, b.addr(0x4000), b.addr(0x5002), 1);
|
||||||
b.addRegisterReference(0, b.addr(0x4000), "r5");
|
b.addRegisterReference(0, b.addr(0x4000), "r5");
|
||||||
b.addStackReference(0, b.addr(0x4000), 0x20);
|
b.addStackReference(0, b.addr(0x4000), 0x20);
|
||||||
keptRef = b.addMemoryReference(0, b.addr(0x4001), b.addr(0x8000));
|
keptRef = b.addMemoryReference(0, b.addr(0x4001), b.range(0x8000, 0x8003));
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(5, manager.getReferencesFrom(0, b.addr(0x4000)).size());
|
assertEquals(5, manager.getReferencesFrom(0, b.addr(0x4000)).size());
|
||||||
|
@ -448,27 +451,46 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
DBTraceReference offRef;
|
DBTraceReference offRef;
|
||||||
DBTraceReference sftRef;
|
DBTraceReference sftRef;
|
||||||
try (Transaction tx = b.startTransaction()) {
|
try (Transaction tx = b.startTransaction()) {
|
||||||
memRef = b.addMemoryReference(0, b.addr(0x4000), b.addr(0x5000));
|
memRef = b.addMemoryReference(0, b.addr(0x4000), b.range(0x5000, 0x5003));
|
||||||
offRef = b.addOffsetReference(0, b.addr(0x4001), b.addr(0x5000), false, 20);
|
offRef = b.addOffsetReference(0, b.addr(0x4001), b.addr(0x5000), false, 20);
|
||||||
sftRef = b.addShiftedReference(0, b.addr(0x4002), b.addr(0x5000), 1);
|
sftRef = b.addShiftedReference(0, b.addr(0x4002), b.addr(0x5000), 1);
|
||||||
b.addRegisterReference(0, b.addr(0x4003), "r5");
|
b.addRegisterReference(0, b.addr(0x4003), "r5");
|
||||||
b.addStackReference(0, b.addr(0x4004), 0x20);
|
b.addStackReference(0, b.addr(0x4004), 0x20);
|
||||||
|
|
||||||
b.addMemoryReference(0, b.addr(0x4005), b.addr(0x8000));
|
b.addMemoryReference(0, b.addr(0x4005), b.range(0x8000, 0x8003));
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(Set.of(memRef, offRef, sftRef),
|
assertEquals(Set.of(memRef, offRef, sftRef),
|
||||||
new HashSet<>(manager.getReferencesTo(0, b.addr(0x5000))));
|
Set.copyOf(manager.getReferencesTo(0, b.addr(0x5000))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void tesGetReferencesToRange() {
|
||||||
|
DBTraceReference memRef1;
|
||||||
|
DBTraceReference memRef2;
|
||||||
|
DBTraceReference memRef3;
|
||||||
|
try (Transaction tx = b.startTransaction()) {
|
||||||
|
memRef1 = b.addMemoryReference(0, b.addr(0x4000), b.range(0x5000, 0x5003));
|
||||||
|
memRef2 = b.addMemoryReference(5, b.addr(0x4000), b.range(0x5002, 0x5005));
|
||||||
|
memRef3 = b.addMemoryReference(0, b.addr(0x4000), b.range(0x5004, 0x5007));
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(Set.of(memRef1, memRef2, memRef3),
|
||||||
|
Set.copyOf(manager.getReferencesToRange(Lifespan.nowOn(0), b.range(0x5000, 0x5007))));
|
||||||
|
assertEquals(Set.of(memRef1),
|
||||||
|
Set.copyOf(manager.getReferencesToRange(Lifespan.nowOn(0), b.range(0x5000, 0x5000))));
|
||||||
|
assertEquals(Set.of(memRef1, memRef3),
|
||||||
|
Set.copyOf(manager.getReferencesToRange(Lifespan.at(0), b.range(0x5000, 0x5007))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testClearReferencesTo() {
|
public void testClearReferencesTo() {
|
||||||
DBTraceReference keptRef;
|
DBTraceReference keptRef;
|
||||||
try (Transaction tx = b.startTransaction()) {
|
try (Transaction tx = b.startTransaction()) {
|
||||||
b.addMemoryReference(0, b.addr(0x4000), b.addr(0x5000), 3);
|
b.addMemoryReference(0, b.addr(0x4000), b.range(0x5000, 0x5003), 3);
|
||||||
b.addOffsetReference(0, b.addr(0x4001), b.addr(0x5000), false, 20);
|
b.addOffsetReference(0, b.addr(0x4001), b.addr(0x5000), false, 20);
|
||||||
b.addShiftedReference(0, b.addr(0x4002), b.addr(0x5000), 1);
|
b.addShiftedReference(0, b.addr(0x4002), b.addr(0x5000), 1);
|
||||||
keptRef = b.addMemoryReference(0, b.addr(0x8000), b.addr(0x5001));
|
keptRef = b.addMemoryReference(0, b.addr(0x8000), b.range(0x5004, 0x5007));
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(3, manager.getReferencesTo(0, b.addr(0x5000)).size());
|
assertEquals(3, manager.getReferencesTo(0, b.addr(0x5000)).size());
|
||||||
|
@ -489,26 +511,26 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
|
|
||||||
assertEquals(0, manager.getReferencesTo(0, b.addr(0x5000)).size());
|
assertEquals(0, manager.getReferencesTo(0, b.addr(0x5000)).size());
|
||||||
assertEquals(0, manager.getReferencesTo(-1, b.addr(0x5000)).size());
|
assertEquals(0, manager.getReferencesTo(-1, b.addr(0x5000)).size());
|
||||||
assertEquals(1, manager.getReferencesTo(0, b.addr(0x5001)).size());
|
assertEquals(1, manager.getReferencesTo(0, b.addr(0x5004)).size());
|
||||||
assertEquals(keptRef, manager.getReferencesTo(0, b.addr(0x5001)).iterator().next());
|
assertEquals(keptRef, manager.getReferencesTo(0, b.addr(0x5004)).iterator().next());
|
||||||
assertEquals(Lifespan.nowOn(0), keptRef.getLifespan());
|
assertEquals(Lifespan.nowOn(0), keptRef.getLifespan());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetReferenceSourcesAndDestinations() {
|
public void testGetReferenceSourcesAndDestinations() {
|
||||||
try (Transaction tx = b.startTransaction()) {
|
try (Transaction tx = b.startTransaction()) {
|
||||||
b.addMemoryReference(0, b.addr(0x4000), b.addr(0x5000));
|
b.addMemoryReference(0, b.addr(0x4000), b.range(0x5000, 0x5000));
|
||||||
b.addOffsetReference(0, b.addr(0x4001), b.addr(0x5001), false, 20);
|
b.addOffsetReference(0, b.addr(0x4001), b.addr(0x5001), false, 20);
|
||||||
b.addShiftedReference(0, b.addr(0x4002), b.addr(0x5002), 1);
|
b.addShiftedReference(0, b.addr(0x4002), b.addr(0x5002), 1);
|
||||||
b.addRegisterReference(0, b.addr(0x4003), "r5");
|
b.addRegisterReference(0, b.addr(0x4003), "r5");
|
||||||
b.addStackReference(0, b.addr(0x4004), 0x20);
|
b.addStackReference(0, b.addr(0x4004), 0x20);
|
||||||
b.addMemoryReference(0, b.addr(0x4005), b.addr(0x8000));
|
b.addMemoryReference(0, b.addr(0x4005), b.range(0x8000, 0x8003));
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(b.set(b.range(0x4000, 0x4005)),
|
assertEquals(b.set(b.range(0x4000, 0x4005)),
|
||||||
manager.getReferenceSources(Lifespan.span(0, 0)));
|
manager.getReferenceSources(Lifespan.span(0, 0)));
|
||||||
assertEquals(b.set(), manager.getReferenceSources(Lifespan.span(-1, -1)));
|
assertEquals(b.set(), manager.getReferenceSources(Lifespan.span(-1, -1)));
|
||||||
assertEquals(b.set(b.range(0x5000, 0x5002), b.range(0x8000, 0x8000)),
|
assertEquals(b.set(b.range(0x5000, 0x5002), b.range(0x8000, 0x8003)),
|
||||||
manager.getReferenceDestinations(Lifespan.span(0, 0)));
|
manager.getReferenceDestinations(Lifespan.span(0, 0)));
|
||||||
assertEquals(b.set(), manager.getReferenceDestinations(Lifespan.span(-1, -1)));
|
assertEquals(b.set(), manager.getReferenceDestinations(Lifespan.span(-1, -1)));
|
||||||
}
|
}
|
||||||
|
@ -519,13 +541,13 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
assertEquals(0, manager.getReferenceCountTo(0, b.addr(0x5000)));
|
assertEquals(0, manager.getReferenceCountTo(0, b.addr(0x5000)));
|
||||||
|
|
||||||
try (Transaction tx = b.startTransaction()) {
|
try (Transaction tx = b.startTransaction()) {
|
||||||
b.addMemoryReference(0, b.addr(0x4000), b.addr(0x5000));
|
b.addMemoryReference(0, b.addr(0x4000), b.range(0x5000, 0x5003));
|
||||||
b.addOffsetReference(0, b.addr(0x4000), b.addr(0x5001), false, 20);
|
b.addOffsetReference(0, b.addr(0x4000), b.addr(0x5001), false, 20);
|
||||||
b.addShiftedReference(0, b.addr(0x4000), b.addr(0x5002), 1);
|
b.addShiftedReference(0, b.addr(0x4000), b.addr(0x5002), 1);
|
||||||
b.addRegisterReference(0, b.addr(0x4000), "r5");
|
b.addRegisterReference(0, b.addr(0x4000), "r5");
|
||||||
b.addStackReference(0, b.addr(0x4000), 0x20);
|
b.addStackReference(0, b.addr(0x4000), 0x20);
|
||||||
b.addMemoryReference(0, b.addr(0x4001), b.addr(0x5000));
|
b.addMemoryReference(0, b.addr(0x4001), b.range(0x5000, 0x5003));
|
||||||
b.addMemoryReference(0, b.addr(0x4002), b.addr(0x5000));
|
b.addMemoryReference(0, b.addr(0x4002), b.range(0x5000, 0x5003));
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(5, manager.getReferenceCountFrom(0, b.addr(0x4000)));
|
assertEquals(5, manager.getReferenceCountFrom(0, b.addr(0x4000)));
|
||||||
|
@ -537,7 +559,7 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
@Test
|
@Test
|
||||||
public void testSaveAndLoad() throws CancelledException, IOException, VersionException {
|
public void testSaveAndLoad() throws CancelledException, IOException, VersionException {
|
||||||
try (Transaction tx = b.startTransaction()) {
|
try (Transaction tx = b.startTransaction()) {
|
||||||
b.addMemoryReference(0, b.addr(0x4000), b.addr(0x5000));
|
b.addMemoryReference(0, b.addr(0x4000), b.range(0x5000, 0x5003));
|
||||||
b.addOffsetReference(0, b.addr(0x4000), b.addr(0x5001), false, 20);
|
b.addOffsetReference(0, b.addr(0x4000), b.addr(0x5001), false, 20);
|
||||||
b.addShiftedReference(0, b.addr(0x4000), b.addr(0x5002), 1);
|
b.addShiftedReference(0, b.addr(0x4000), b.addr(0x5002), 1);
|
||||||
}
|
}
|
||||||
|
@ -553,9 +575,9 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
manager.getReferencesFrom(0, b.addr(0x4000));
|
manager.getReferencesFrom(0, b.addr(0x4000));
|
||||||
assertEquals(3, refs.size());
|
assertEquals(3, refs.size());
|
||||||
|
|
||||||
DBTraceReference ref;
|
TraceReference ref;
|
||||||
|
|
||||||
ref = manager.getReference(0, b.addr(0x4000), b.addr(0x5000), -1);
|
ref = manager.getReference(0, b.addr(0x4000), b.range(0x5000, 0x5003), -1);
|
||||||
assertEquals(DBTraceReference.class, ref.getClass());
|
assertEquals(DBTraceReference.class, ref.getClass());
|
||||||
assertEquals(RefType.DATA, ref.getReferenceType());
|
assertEquals(RefType.DATA, ref.getReferenceType());
|
||||||
assertEquals(SourceType.DEFAULT, ref.getSource());
|
assertEquals(SourceType.DEFAULT, ref.getSource());
|
||||||
|
@ -574,7 +596,7 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
@Test
|
@Test
|
||||||
public void testUndo() throws IOException {
|
public void testUndo() throws IOException {
|
||||||
try (Transaction tx = b.startTransaction()) {
|
try (Transaction tx = b.startTransaction()) {
|
||||||
b.addMemoryReference(0, b.addr(0x4000), b.addr(0x5000));
|
b.addMemoryReference(0, b.addr(0x4000), b.range(0x5000, 0x5003));
|
||||||
b.addOffsetReference(0, b.addr(0x4000), b.addr(0x5001), false, 20);
|
b.addOffsetReference(0, b.addr(0x4000), b.addr(0x5001), false, 20);
|
||||||
b.addShiftedReference(0, b.addr(0x4000), b.addr(0x5002), 1);
|
b.addShiftedReference(0, b.addr(0x4000), b.addr(0x5002), 1);
|
||||||
}
|
}
|
||||||
|
@ -597,9 +619,9 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
.createOverlayAddressSpace("test",
|
.createOverlayAddressSpace("test",
|
||||||
b.trace.getBaseAddressFactory().getDefaultAddressSpace());
|
b.trace.getBaseAddressFactory().getDefaultAddressSpace());
|
||||||
|
|
||||||
b.addMemoryReference(0, os.getAddress(0x4000), os.getAddress(0x5000));
|
b.addMemoryReference(0, os.getAddress(0x4000), b.range(os, 0x5000, 0x5003));
|
||||||
b.addMemoryReference(0, os.getAddress(0x4001), b.addr(0x5001));
|
b.addMemoryReference(0, os.getAddress(0x4001), b.range(0x5004, 0x5007));
|
||||||
b.addMemoryReference(0, b.addr(0x4002), os.getAddress(0x5002));
|
b.addMemoryReference(0, b.addr(0x4002), b.range(os, 0x5008, 0x500b));
|
||||||
}
|
}
|
||||||
|
|
||||||
File saved = b.save();
|
File saved = b.save();
|
||||||
|
@ -613,19 +635,19 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
AddressSpace os = b.trace.getBaseAddressFactory().getAddressSpace("test");
|
AddressSpace os = b.trace.getBaseAddressFactory().getAddressSpace("test");
|
||||||
assertNotNull(os);
|
assertNotNull(os);
|
||||||
|
|
||||||
DBTraceReference ref;
|
TraceReference ref;
|
||||||
|
|
||||||
ref = manager.getReference(0, os.getAddress(0x4000), os.getAddress(0x5000), -1);
|
ref = manager.getReference(0, os.getAddress(0x4000), b.range(os, 0x5000, 0x5003), -1);
|
||||||
assertNotNull(ref);
|
assertNotNull(ref);
|
||||||
assertEquals(os, ref.getFromAddress().getAddressSpace());
|
assertEquals(os, ref.getFromAddress().getAddressSpace());
|
||||||
assertEquals(os, ref.getToAddress().getAddressSpace());
|
assertEquals(os, ref.getToAddress().getAddressSpace());
|
||||||
|
|
||||||
ref = manager.getReference(0, os.getAddress(0x4001), b.addr(0x5001), -1);
|
ref = manager.getReference(0, os.getAddress(0x4001), b.range(0x5004, 0x5007), -1);
|
||||||
assertNotNull(ref);
|
assertNotNull(ref);
|
||||||
assertEquals(os, ref.getFromAddress().getAddressSpace());
|
assertEquals(os, ref.getFromAddress().getAddressSpace());
|
||||||
assertEquals(ds, ref.getToAddress().getAddressSpace());
|
assertEquals(ds, ref.getToAddress().getAddressSpace());
|
||||||
|
|
||||||
ref = manager.getReference(0, b.addr(0x4002), os.getAddress(0x5002), -1);
|
ref = manager.getReference(0, b.addr(0x4002), b.range(os, 0x5008, 0x500b), -1);
|
||||||
assertNotNull(ref);
|
assertNotNull(ref);
|
||||||
assertEquals(ds, ref.getFromAddress().getAddressSpace());
|
assertEquals(ds, ref.getFromAddress().getAddressSpace());
|
||||||
assertEquals(os, ref.getToAddress().getAddressSpace());
|
assertEquals(os, ref.getToAddress().getAddressSpace());
|
||||||
|
@ -636,11 +658,11 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
||||||
assertEquals(0, manager.getReferenceCountFrom(0, os.getAddress(0x4002)));
|
assertEquals(0, manager.getReferenceCountFrom(0, os.getAddress(0x4002)));
|
||||||
assertEquals(1, manager.getReferenceCountFrom(0, b.addr(0x4002)));
|
assertEquals(1, manager.getReferenceCountFrom(0, b.addr(0x4002)));
|
||||||
|
|
||||||
assertEquals(0, manager.getReferenceCountTo(0, os.getAddress(0x5001)));
|
assertEquals(0, manager.getReferenceCountTo(0, os.getAddress(0x5004)));
|
||||||
assertEquals(1, manager.getReferenceCountTo(0, b.addr(0x5001)));
|
assertEquals(1, manager.getReferenceCountTo(0, b.addr(0x5004)));
|
||||||
|
|
||||||
assertEquals(0, manager.getReferenceCountTo(0, b.addr(0x5002)));
|
assertEquals(0, manager.getReferenceCountTo(0, b.addr(0x5008)));
|
||||||
assertEquals(1, manager.getReferenceCountTo(0, os.getAddress(0x5002)));
|
assertEquals(1, manager.getReferenceCountTo(0, os.getAddress(0x5008)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue