mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +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.SourceType;
|
||||
import ghidra.trace.database.data.DBTraceDataSettingsOperations;
|
||||
import ghidra.trace.database.symbol.DBTraceReference;
|
||||
import ghidra.trace.model.listing.TraceData;
|
||||
import ghidra.trace.model.symbol.TraceReference;
|
||||
import ghidra.trace.util.*;
|
||||
|
@ -63,7 +62,7 @@ public interface DBTraceDataAdapter extends DBTraceCodeUnitAdapter, DataAdapterM
|
|||
@Override
|
||||
default void removeValueReference(Address refAddr) {
|
||||
try (LockHold hold = getTrace().lockWrite()) {
|
||||
DBTraceReference ref = getTrace().getReferenceManager()
|
||||
TraceReference ref = getTrace().getReferenceManager()
|
||||
.getReference(getStartSnap(),
|
||||
getAddress(), refAddr, DATA_OP_INDEX);
|
||||
if (ref == null) {
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -36,8 +36,8 @@ public class DBTraceOffsetReference extends DBTraceReference implements TraceOff
|
|||
@Override
|
||||
public Address getBaseAddress() {
|
||||
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 ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressRange;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.trace.database.DBTrace;
|
||||
import ghidra.trace.database.symbol.DBTraceReferenceSpace.DBTraceReferenceEntry;
|
||||
|
@ -76,8 +77,8 @@ public class DBTraceReference implements TraceReference {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Address getToAddress() {
|
||||
return ent.toAddress;
|
||||
public AddressRange getToRange() {
|
||||
return ent.toRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -39,6 +39,7 @@ import ghidra.trace.model.symbol.TraceReference;
|
|||
import ghidra.trace.model.symbol.TraceReferenceManager;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.util.UnionAddressSetView;
|
||||
import ghidra.util.database.spatial.rect.Rectangle2DDirection;
|
||||
import ghidra.util.exception.VersionException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
|
@ -96,27 +97,27 @@ public class DBTraceReferenceManager extends AbstractDBTraceSpaceBasedManager<DB
|
|||
}
|
||||
|
||||
protected void doAddXRef(DBTraceReferenceEntry entry) {
|
||||
if (!entry.toAddress.isMemoryAddress()) {
|
||||
if (!entry.toAddrMin.isMemoryAddress()) {
|
||||
return;
|
||||
}
|
||||
DBTraceReferenceSpace space = getReferenceSpace(entry.toAddress.getAddressSpace(), true);
|
||||
DBTraceReferenceSpace space = getReferenceSpace(entry.toAddrMin.getAddressSpace(), true);
|
||||
space.doAddXRef(entry);
|
||||
}
|
||||
|
||||
protected void doDelXRef(DBTraceReferenceEntry entry) {
|
||||
if (!entry.toAddress.isMemoryAddress()) {
|
||||
if (!entry.toAddrMin.isMemoryAddress()) {
|
||||
return;
|
||||
}
|
||||
DBTraceReferenceSpace space = getReferenceSpace(entry.toAddress.getAddressSpace(), false);
|
||||
DBTraceReferenceSpace space = getReferenceSpace(entry.toAddrMin.getAddressSpace(), false);
|
||||
assert space != null;
|
||||
space.doDelXRef(entry);
|
||||
}
|
||||
|
||||
protected void doSetXRefLifespan(DBTraceReferenceEntry entry) {
|
||||
if (!entry.toAddress.isMemoryAddress()) {
|
||||
if (!entry.toAddrMin.isMemoryAddress()) {
|
||||
return;
|
||||
}
|
||||
DBTraceReferenceSpace space = getReferenceSpace(entry.toAddress.getAddressSpace(), false);
|
||||
DBTraceReferenceSpace space = getReferenceSpace(entry.toAddrMin.getAddressSpace(), false);
|
||||
assert space != null;
|
||||
space.doSetXRefLifespan(entry);
|
||||
}
|
||||
|
@ -164,9 +165,9 @@ public class DBTraceReferenceManager extends AbstractDBTraceSpaceBasedManager<DB
|
|||
|
||||
@Override
|
||||
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,
|
||||
fromAddress, toAddress, refType, source, operandIndex));
|
||||
fromAddress, toRange, refType, source, operandIndex));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -199,10 +200,10 @@ public class DBTraceReferenceManager extends AbstractDBTraceSpaceBasedManager<DB
|
|||
}
|
||||
|
||||
@Override
|
||||
public DBTraceReference getReference(long snap, Address fromAddress, Address toAddress,
|
||||
public DBTraceReference getReference(long snap, Address fromAddress, AddressRange toRange,
|
||||
int operandIndex) {
|
||||
return delegateRead(fromAddress.getAddressSpace(),
|
||||
s -> s.getReference(snap, fromAddress, toAddress, operandIndex));
|
||||
s -> s.getReference(snap, fromAddress, toRange, operandIndex));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -253,9 +254,9 @@ public class DBTraceReferenceManager extends AbstractDBTraceSpaceBasedManager<DB
|
|||
|
||||
@Override
|
||||
public Collection<? extends DBTraceReference> getReferencesToRange(Lifespan span,
|
||||
AddressRange range) {
|
||||
return delegateRead(range.getAddressSpace(), s -> s.getReferencesToRange(span, range),
|
||||
Collections.emptyList());
|
||||
AddressRange range, Rectangle2DDirection order) {
|
||||
return delegateRead(range.getAddressSpace(),
|
||||
s -> s.getReferencesToRange(span, range, order), Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -42,11 +42,11 @@ import ghidra.trace.model.Lifespan;
|
|||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
import ghidra.trace.model.symbol.TraceReference;
|
||||
import ghidra.trace.model.symbol.TraceReferenceSpace;
|
||||
import ghidra.trace.util.TraceChangeRecord;
|
||||
import ghidra.trace.util.TraceEvents;
|
||||
import ghidra.trace.util.*;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.database.*;
|
||||
import ghidra.util.database.annot.*;
|
||||
import ghidra.util.database.spatial.rect.Rectangle2DDirection;
|
||||
import ghidra.util.exception.VersionException;
|
||||
|
||||
public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceSpace {
|
||||
|
@ -59,7 +59,7 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
|||
*/
|
||||
@Override
|
||||
protected DBTraceReference construct(DBTraceReferenceEntry ent) {
|
||||
if (ent.toAddress.isStackAddress()) {
|
||||
if (ent.toAddrMin.isStackAddress()) {
|
||||
return new DBTraceStackReference(ent);
|
||||
}
|
||||
return new DBTraceReference(ent);
|
||||
|
@ -97,7 +97,7 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
|||
* <li>0: Initial version and previous unversioned implementation</li>
|
||||
* </ul>
|
||||
*/
|
||||
@DBAnnotatedObjectInfo(version = 1)
|
||||
@DBAnnotatedObjectInfo(version = 2)
|
||||
protected static class DBTraceReferenceEntry
|
||||
extends AbstractDBTraceAddressSnapRangePropertyMapData<DBTraceReferenceEntry>
|
||||
implements DecodesAddresses {
|
||||
|
@ -114,7 +114,8 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
|||
private static final byte TYPE_SHIFT = 5;
|
||||
//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 REF_TYPE_COLUMN_NAME = "RefType";
|
||||
static final String OP_INDEX_COLUMN_NAME = "OpIndex";
|
||||
|
@ -122,8 +123,10 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
|||
// bit-packed sourceType, isPrimary, type
|
||||
static final String FLAGS_COLUMN_NAME = "Flags";
|
||||
|
||||
@DBAnnotatedColumn(TO_ADDR_COLUMN_NAME)
|
||||
static DBObjectColumn TO_ADDR_COLUMN;
|
||||
@DBAnnotatedColumn(TO_ADDR_MIN_COLUMN_NAME)
|
||||
static DBObjectColumn TO_ADDR_MIN_COLUMN;
|
||||
@DBAnnotatedColumn(TO_ADDR_MAX_COLUMN_NAME)
|
||||
static DBObjectColumn TO_ADDR_MAX_COLUMN;
|
||||
@DBAnnotatedColumn(SYMBOL_ID_COLUMN_NAME)
|
||||
static DBObjectColumn SYMBOL_ID_COLUMN;
|
||||
@DBAnnotatedColumn(REF_TYPE_COLUMN_NAME)
|
||||
|
@ -140,10 +143,15 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
|||
}
|
||||
|
||||
@DBAnnotatedField(
|
||||
column = TO_ADDR_COLUMN_NAME,
|
||||
column = TO_ADDR_MIN_COLUMN_NAME,
|
||||
indexed = true,
|
||||
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)
|
||||
protected long symbolId; // TODO: Is this at the from or to address? I think TO...
|
||||
@DBAnnotatedField(column = REF_TYPE_COLUMN_NAME, codec = RefTypeDBFieldCodec.class)
|
||||
|
@ -157,6 +165,7 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
|||
|
||||
protected final DBTraceReferenceSpace space;
|
||||
|
||||
protected AddressRange toRange;
|
||||
protected DBTraceReference ref;
|
||||
|
||||
public DBTraceReferenceEntry(DBTraceReferenceSpace space,
|
||||
|
@ -177,6 +186,7 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
|||
if (created) {
|
||||
return;
|
||||
}
|
||||
toRange = new AddressRangeImpl(toAddrMin, toAddrMax);
|
||||
TypeEnum type = TypeEnum.values()[(flags >> TYPE_SHIFT) & TYPE_MASK];
|
||||
ref = type.construct(this);
|
||||
}
|
||||
|
@ -191,17 +201,20 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
|||
return this;
|
||||
}
|
||||
|
||||
protected void set(Address toAddress, long symbolId, RefType refType, int opIndex, long ext,
|
||||
boolean isPrimary, TypeEnum type, SourceType sourceType) {
|
||||
this.toAddress = toAddress;
|
||||
protected void set(AddressRange toRange, long symbolId, RefType refType,
|
||||
int opIndex, long ext, boolean isPrimary, TypeEnum type, SourceType sourceType) {
|
||||
this.toAddrMin = toRange.getMinAddress();
|
||||
this.toAddrMax = toRange.getMaxAddress();
|
||||
this.symbolId = symbolId;
|
||||
this.refType = refType;
|
||||
this.opIndex = (byte) opIndex;
|
||||
this.ext = ext;
|
||||
this.flags = (byte) ((isPrimary ? PRIMARY_MASK : 0) |
|
||||
(sourceType.ordinal() << SOURCE_SHIFT) | type.ordinal() << TYPE_SHIFT);
|
||||
update(TO_ADDR_COLUMN, SYMBOL_ID_COLUMN, REF_TYPE_COLUMN, OP_INDEX_COLUMN, EXT_COLUMN,
|
||||
FLAGS_COLUMN);
|
||||
update(TO_ADDR_MIN_COLUMN, TO_ADDR_MAX_COLUMN, SYMBOL_ID_COLUMN, REF_TYPE_COLUMN,
|
||||
OP_INDEX_COLUMN, EXT_COLUMN, FLAGS_COLUMN);
|
||||
|
||||
this.toRange = toRange;
|
||||
}
|
||||
|
||||
protected void setLifespan(Lifespan lifespan) {
|
||||
|
@ -369,7 +382,7 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
|||
|
||||
protected void doAddXRef(DBTraceReferenceEntry refEnt) {
|
||||
// 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(),
|
||||
refEnt.getKey());
|
||||
}
|
||||
|
@ -428,40 +441,40 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
|||
return addShiftedReference(lifespan, sRef.getFromAddress(), sRef.getToAddress(),
|
||||
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());
|
||||
}
|
||||
|
||||
protected void makeWay(Lifespan span, Address fromAddress, Address toAddress,
|
||||
protected void makeWay(Lifespan span, Address fromAddress, AddressRange toRange,
|
||||
int operandIndex) {
|
||||
// TODO: Do I consider "compatibility?" as in ReferenceDBManager?
|
||||
// Do I consider "compatibility?" as in ReferenceDBManager?
|
||||
// NOTE: Always call with the write lock
|
||||
for (DBTraceReferenceEntry ent : referenceMapSpace.reduce(
|
||||
TraceAddressSnapRangeQuery.intersecting(new AddressRangeImpl(fromAddress, fromAddress),
|
||||
span)).values()) {
|
||||
if (!ent.toAddress.equals(toAddress)) {
|
||||
continue;
|
||||
}
|
||||
if (ent.opIndex != operandIndex) {
|
||||
if (!ent.toRange.equals(toRange) ||
|
||||
ent.opIndex != operandIndex) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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) {
|
||||
throw new IllegalArgumentException("operandIndex");
|
||||
}
|
||||
try (LockHold hold = LockHold.lock(lock.writeLock())) {
|
||||
makeWay(lifespan, fromAddress, toAddress, operandIndex);
|
||||
makeWay(lifespan, fromAddress, toRange, operandIndex);
|
||||
|
||||
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);
|
||||
entry.ref = ref;
|
||||
manager.doAddXRef(entry);
|
||||
|
@ -520,10 +533,11 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
|||
" 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);
|
||||
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);
|
||||
entry.ref = ref;
|
||||
manager.doAddXRef(entry);
|
||||
|
@ -538,10 +552,11 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
|||
throw new IllegalArgumentException("operandIndex");
|
||||
}
|
||||
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);
|
||||
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);
|
||||
entry.ref = ref;
|
||||
manager.doAddXRef(entry);
|
||||
|
@ -552,8 +567,8 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
|||
@Override
|
||||
public DBTraceReference addRegisterReference(Lifespan lifespan, Address fromAddress,
|
||||
Register toRegister, RefType refType, SourceType source, int operandIndex) {
|
||||
return addMemoryReference(lifespan, fromAddress, toRegister.getAddress(), refType, source,
|
||||
operandIndex);
|
||||
return addMemoryReference(lifespan, fromAddress,
|
||||
TraceRegisterUtils.rangeForRegister(toRegister), refType, source, operandIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -561,20 +576,19 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
|||
int toStackOffset, RefType refType, SourceType source, int operandIndex) {
|
||||
// TODO: base and guest compiler specs, too?
|
||||
AddressSpace stack = baseLanguage.getDefaultCompilerSpec().getStackSpace();
|
||||
return addMemoryReference(lifespan, fromAddress, stack.getAddress(toStackOffset), refType,
|
||||
source, operandIndex);
|
||||
Address toAddress = stack.getAddress(toStackOffset);
|
||||
AddressRange toRange = new AddressRangeImpl(toAddress, toAddress);
|
||||
return addMemoryReference(lifespan, fromAddress, toRange, refType, source, operandIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DBTraceReference getReference(long snap, Address fromAddress, Address toAddress,
|
||||
public DBTraceReference getReference(long snap, Address fromAddress, AddressRange toRange,
|
||||
int operandIndex) {
|
||||
try (LockHold hold = LockHold.lock(lock.readLock())) {
|
||||
for (DBTraceReferenceEntry entry : referenceMapSpace.reduce(
|
||||
TraceAddressSnapRangeQuery.at(fromAddress, snap)).values()) {
|
||||
if (!toAddress.equals(entry.toAddress)) {
|
||||
continue;
|
||||
}
|
||||
if (entry.opIndex != operandIndex) {
|
||||
if (!entry.toRange.equals(toRange) ||
|
||||
entry.opIndex != operandIndex) {
|
||||
continue;
|
||||
}
|
||||
return entry.ref;
|
||||
|
@ -667,9 +681,10 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
|
|||
|
||||
@Override
|
||||
public Collection<? extends DBTraceReference> getReferencesToRange(Lifespan span,
|
||||
AddressRange range) {
|
||||
AddressRange range, Rectangle2DDirection order) {
|
||||
return new LazyCollection<>(
|
||||
() -> xrefMapSpace.reduce(TraceAddressSnapRangeQuery.intersecting(range, span))
|
||||
() -> xrefMapSpace
|
||||
.reduce(TraceAddressSnapRangeQuery.intersecting(range, span).starting(order))
|
||||
.values()
|
||||
.stream()
|
||||
.map(this::getRefForXRefEntry));
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -30,6 +30,6 @@ public class DBTraceShiftedReference extends DBTraceReference implements TraceSh
|
|||
|
||||
@Override
|
||||
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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package ghidra.trace.model.symbol;
|
||||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.symbol.OffsetReference;
|
||||
|
||||
public interface TraceOffsetReference extends TraceReference, OffsetReference {
|
||||
|
@ -22,4 +23,9 @@ public interface TraceOffsetReference extends TraceReference, OffsetReference {
|
|||
default boolean isOffsetReference() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
default Address getToAddress() {
|
||||
return TraceReference.super.getToAddress();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -15,17 +15,69 @@
|
|||
*/
|
||||
package ghidra.trace.model.symbol;
|
||||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressRange;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.Trace;
|
||||
|
||||
/**
|
||||
* A {@link Reference} within a {@link Trace}
|
||||
*/
|
||||
public interface TraceReference extends Reference {
|
||||
/**
|
||||
* Get the trace containing this reference
|
||||
*
|
||||
* @return the trace
|
||||
*/
|
||||
Trace getTrace();
|
||||
|
||||
/**
|
||||
* Get the lifespan for which this reference is effective
|
||||
*
|
||||
* @return the lifespan
|
||||
*/
|
||||
Lifespan getLifespan();
|
||||
|
||||
/**
|
||||
* Get the starting snapshot key of this reference's lifespan
|
||||
*
|
||||
* @return the starting snapshot
|
||||
* @see #getLifespan()
|
||||
*/
|
||||
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.
|
||||
*
|
||||
|
@ -43,10 +95,27 @@ public interface TraceReference extends Reference {
|
|||
*/
|
||||
void setReferenceType(RefType refType);
|
||||
|
||||
/**
|
||||
* Set the symbol associated with this reference
|
||||
*
|
||||
* @param symbol the symbol
|
||||
* @see #getSymbolID()
|
||||
*/
|
||||
void setAssociatedSymbol(Symbol symbol);
|
||||
|
||||
/**
|
||||
* Clear the associated symbol
|
||||
*
|
||||
* @see #getSymbolID()
|
||||
*/
|
||||
void clearAssociatedSymbol();
|
||||
|
||||
/**
|
||||
* Get the symbol associated with this reference
|
||||
*
|
||||
* @return the symbol
|
||||
* @see #getSymbolID()
|
||||
*/
|
||||
default Symbol getAssociatedSymbol() {
|
||||
long id = getSymbolID();
|
||||
return id == -1 ? null : getTrace().getSymbolManager().getSymbolByID(id);
|
||||
|
@ -115,5 +184,8 @@ public interface TraceReference extends Reference {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete this reference
|
||||
*/
|
||||
void delete();
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* 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.symbol.*;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.util.database.spatial.rect.Rectangle2DDirection;
|
||||
|
||||
/**
|
||||
* The operations for adding and retrieving references
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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 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);
|
||||
|
||||
/**
|
||||
* 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,
|
||||
Address toAddress, boolean toAddrIsBase, long offset, RefType refType,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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,
|
||||
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
|
||||
* index.
|
||||
*
|
||||
* @param span
|
||||
* @param range
|
||||
* @return
|
||||
* @param span the lifespan to examine
|
||||
* @param range the range to examine
|
||||
* @return the collection of results
|
||||
*/
|
||||
Collection<? extends TraceReference> getReferencesFromRange(Lifespan span,
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param range
|
||||
* @return
|
||||
* <ul>
|
||||
* <li>{@code null} - no particular order. This spares the cost of sorting.</li>
|
||||
* <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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
|
|
@ -837,7 +837,7 @@ public class ToyDBTraceBuilder implements AutoCloseable {
|
|||
* @param to the to address
|
||||
* @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);
|
||||
}
|
||||
|
||||
|
@ -850,7 +850,7 @@ public class ToyDBTraceBuilder implements AutoCloseable {
|
|||
* @param operandIndex the operand index, or -1 for mnemonic
|
||||
* @return the reference
|
||||
*/
|
||||
public DBTraceReference addMemoryReference(long creationSnap, Address from, Address to,
|
||||
public DBTraceReference addMemoryReference(long creationSnap, Address from, AddressRange to,
|
||||
int operandIndex) {
|
||||
return trace.getReferenceManager()
|
||||
.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.map.DBTraceAddressSnapRangePropertyMapTree.TraceAddressSnapRangeQuery;
|
||||
import ghidra.trace.database.memory.DBTraceMemorySpace;
|
||||
import ghidra.trace.database.symbol.DBTraceReference;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.guest.TraceGuestPlatform;
|
||||
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.util.TraceRegisterUtils;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
import ghidra.util.map.TypeMismatchException;
|
||||
|
||||
|
@ -620,7 +618,7 @@ public class DBTraceCodeUnitTest extends AbstractGhidraHeadlessIntegrationTest {
|
|||
|
||||
assertEquals(Set.of(mnemRef, opRef, stackRef, regRef), set(i4004.getReferencesFrom()));
|
||||
|
||||
DBTraceReference refTo;
|
||||
TraceReference refTo;
|
||||
try (Transaction tx = b.startTransaction()) {
|
||||
refTo = b.trace.getReferenceManager()
|
||||
.addMemoryReference(Lifespan.ALL, b.addr(0x3000), b.addr(0x4004),
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* 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.IOException;
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import db.Transaction;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.test.AbstractGhidraHeadlessIntegrationTest;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.symbol.*;
|
||||
import ghidra.trace.util.TraceRegisterUtils;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.VersionException;
|
||||
|
||||
|
@ -39,12 +40,12 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
|||
protected static class DummyTraceReference implements TraceReference {
|
||||
protected final Lifespan lifespan;
|
||||
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.fromAddress = fromAddress;
|
||||
this.toAddress = toAddress;
|
||||
this.toRange = toRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -53,8 +54,8 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
|||
}
|
||||
|
||||
@Override
|
||||
public Address getToAddress() {
|
||||
return toAddress;
|
||||
public AddressRange getToRange() {
|
||||
return toRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -130,7 +131,7 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
|||
|
||||
public DummyTraceOffsetReference(long startSnap, Address fromAddress, Address toAddress,
|
||||
long offset) {
|
||||
super(startSnap, fromAddress, toAddress);
|
||||
super(startSnap, fromAddress, new AddressRangeImpl(toAddress, toAddress));
|
||||
this.offset = offset;
|
||||
// NOTE: intended for test use in the absence of any EXTERNAL memory block concern
|
||||
this.baseAddress = toAddress.subtract(offset);
|
||||
|
@ -154,7 +155,7 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
|||
|
||||
public DummyTraceShiftedReference(long startSnap, Address fromAddress, Address toAddress,
|
||||
int shift) {
|
||||
super(startSnap, fromAddress, toAddress);
|
||||
super(startSnap, fromAddress, new AddressRangeImpl(toAddress, toAddress));
|
||||
this.shift = shift;
|
||||
this.value = toAddress.getOffset() >>> shift;
|
||||
}
|
||||
|
@ -190,8 +191,8 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
|||
DBTraceReference offRef;
|
||||
DBTraceReference sftRef;
|
||||
try (Transaction tx = b.startTransaction()) {
|
||||
memRef =
|
||||
manager.addReference(new DummyTraceReference(0, b.addr(0x4000), b.addr(0x5000)));
|
||||
memRef = manager.addReference(
|
||||
new DummyTraceReference(0, b.addr(0x4000), b.range(0x5000, 0x5003)));
|
||||
offRef = manager.addReference(
|
||||
new DummyTraceOffsetReference(0, b.addr(0x4001), b.addr(0x5001), 20));
|
||||
sftRef = manager.addReference(
|
||||
|
@ -203,6 +204,7 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
|||
assertTrue(sftRef instanceof DBTraceShiftedReference);
|
||||
|
||||
assertEquals(b.addr(0x4000), memRef.getFromAddress());
|
||||
assertEquals(b.range(0x5000, 0x5003), memRef.getToRange());
|
||||
assertEquals(b.addr(0x5000), memRef.getToAddress());
|
||||
|
||||
assertEquals(b.addr(0x4001), offRef.getFromAddress());
|
||||
|
@ -219,7 +221,7 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
|||
@Test
|
||||
public void testAddMemoryReference() {
|
||||
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 =
|
||||
manager.getReferenceSpace(b.language.getDefaultDataSpace(), false);
|
||||
|
@ -284,7 +286,7 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
|||
DBTraceReference regRef;
|
||||
DBTraceReference stkRef;
|
||||
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);
|
||||
sftRef = b.addShiftedReference(0, b.addr(0x4002), b.addr(0x5002), 1);
|
||||
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.range(0x5000, 0x5003), 0));
|
||||
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(-1, b.addr(0x4000), b.addr(0x5000), -1));
|
||||
assertEquals(memRef, manager.getReference(0, b.addr(0x4000), b.addr(0x5000), -1));
|
||||
assertEquals(memRef, manager.getReference(10, 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.range(0x5000, 0x5003), -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(regRef,
|
||||
manager.getReference(0, b.addr(0x4003), b.language.getRegister("r5").getAddress(), -1));
|
||||
assertNull(
|
||||
manager.getReference(0, b.addr(0x4003), b.language.getRegister("r6").getAddress(), -1));
|
||||
assertEquals(regRef, manager.getReference(0, b.addr(0x4003),
|
||||
TraceRegisterUtils.rangeForRegister(b.language.getRegister("r5")), -1));
|
||||
assertNull(manager.getReference(0, b.addr(0x4003),
|
||||
TraceRegisterUtils.rangeForRegister(b.language.getRegister("r6")), -1));
|
||||
|
||||
// TODO: A better way to manage the compiler spec
|
||||
assertEquals(stkRef, manager.getReference(0, b.addr(0x4004),
|
||||
|
@ -322,21 +325,21 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
|||
DBTraceReference regRef;
|
||||
DBTraceReference stkRef;
|
||||
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);
|
||||
sftRef = b.addShiftedReference(0, b.addr(0x4000), b.addr(0x5002), 1);
|
||||
regRef = b.addRegisterReference(0, b.addr(0x4000), "r5");
|
||||
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),
|
||||
new HashSet<>(manager.getReferencesFrom(0, b.addr(0x4000))));
|
||||
Set.copyOf(manager.getReferencesFrom(0, b.addr(0x4000))));
|
||||
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),
|
||||
new HashSet<>(manager.getReferencesFrom(0, b.addr(0x4000), -1)));
|
||||
Set.copyOf(manager.getReferencesFrom(0, b.addr(0x4000), -1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -347,23 +350,23 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
|||
DBTraceReference diffTo;
|
||||
DBTraceReference diffOpIndex;
|
||||
try (Transaction tx = b.startTransaction()) {
|
||||
at0 = b.addMemoryReference(0, b.addr(0x4000), b.addr(0x5000), 0);
|
||||
b.addMemoryReference(15, b.addr(0x4000), b.addr(0x5000), 0); // Lost
|
||||
at10 = b.addMemoryReference(10, 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.range(0x5000, 0x5003), 0); // Lost
|
||||
at10 = b.addMemoryReference(10, b.addr(0x4000), b.range(0x5000, 0x5003), 0);
|
||||
|
||||
diffFrom = b.addMemoryReference(0, b.addr(0x4001), b.addr(0x5000), 0);
|
||||
diffTo = b.addMemoryReference(0, b.addr(0x4000), b.addr(0x5001), 0);
|
||||
diffOpIndex = b.addMemoryReference(0, b.addr(0x4000), b.addr(0x5000), 1);
|
||||
diffFrom = b.addMemoryReference(0, b.addr(0x4001), b.range(0x5000, 0x5003), 0);
|
||||
diffTo = b.addMemoryReference(0, b.addr(0x4000), b.range(0x5004, 0x5007), 0);
|
||||
diffOpIndex = b.addMemoryReference(0, b.addr(0x4000), b.range(0x5000, 0x5003), 1);
|
||||
|
||||
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),
|
||||
new HashSet<>(manager.getReferencesFrom(15, b.addr(0x4000))));
|
||||
Set.copyOf(manager.getReferencesFrom(15, b.addr(0x4000))));
|
||||
|
||||
assertEquals(Set.of(diffFrom),
|
||||
new HashSet<>(manager.getReferencesFrom(0, b.addr(0x4001))));
|
||||
Set.copyOf(manager.getReferencesFrom(0, b.addr(0x4001))));
|
||||
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 offRef;
|
||||
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);
|
||||
|
||||
assertNull(manager.getPrimaryReferenceFrom(0, b.addr(0x4000), -1));
|
||||
|
@ -395,28 +398,28 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
|||
|
||||
@Test
|
||||
public void testGetFlowReferencesFrom() {
|
||||
DBTraceReference flowRef;
|
||||
TraceReference flowRef;
|
||||
try (Transaction tx = b.startTransaction()) {
|
||||
flowRef = manager.addMemoryReference(Lifespan.nowOn(0), b.addr(0x4000), b.addr(0x4001),
|
||||
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);
|
||||
}
|
||||
|
||||
assertEquals(Set.of(flowRef),
|
||||
new HashSet<>(manager.getFlowReferencesFrom(0, b.addr(0x4000))));
|
||||
Set.copyOf(manager.getFlowReferencesFrom(0, b.addr(0x4000))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClearReferencesFrom() {
|
||||
DBTraceReference keptRef;
|
||||
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.addShiftedReference(0, b.addr(0x4000), b.addr(0x5002), 1);
|
||||
b.addRegisterReference(0, b.addr(0x4000), "r5");
|
||||
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());
|
||||
|
@ -448,27 +451,46 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
|||
DBTraceReference offRef;
|
||||
DBTraceReference sftRef;
|
||||
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);
|
||||
sftRef = b.addShiftedReference(0, b.addr(0x4002), b.addr(0x5000), 1);
|
||||
b.addRegisterReference(0, b.addr(0x4003), "r5");
|
||||
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),
|
||||
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
|
||||
public void testClearReferencesTo() {
|
||||
DBTraceReference keptRef;
|
||||
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.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());
|
||||
|
@ -489,26 +511,26 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
|||
|
||||
assertEquals(0, manager.getReferencesTo(0, b.addr(0x5000)).size());
|
||||
assertEquals(0, manager.getReferencesTo(-1, b.addr(0x5000)).size());
|
||||
assertEquals(1, manager.getReferencesTo(0, b.addr(0x5001)).size());
|
||||
assertEquals(keptRef, manager.getReferencesTo(0, b.addr(0x5001)).iterator().next());
|
||||
assertEquals(1, manager.getReferencesTo(0, b.addr(0x5004)).size());
|
||||
assertEquals(keptRef, manager.getReferencesTo(0, b.addr(0x5004)).iterator().next());
|
||||
assertEquals(Lifespan.nowOn(0), keptRef.getLifespan());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetReferenceSourcesAndDestinations() {
|
||||
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.addShiftedReference(0, b.addr(0x4002), b.addr(0x5002), 1);
|
||||
b.addRegisterReference(0, b.addr(0x4003), "r5");
|
||||
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)),
|
||||
manager.getReferenceSources(Lifespan.span(0, 0)));
|
||||
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)));
|
||||
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)));
|
||||
|
||||
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.addShiftedReference(0, b.addr(0x4000), b.addr(0x5002), 1);
|
||||
b.addRegisterReference(0, b.addr(0x4000), "r5");
|
||||
b.addStackReference(0, b.addr(0x4000), 0x20);
|
||||
b.addMemoryReference(0, b.addr(0x4001), b.addr(0x5000));
|
||||
b.addMemoryReference(0, b.addr(0x4002), b.addr(0x5000));
|
||||
b.addMemoryReference(0, b.addr(0x4001), b.range(0x5000, 0x5003));
|
||||
b.addMemoryReference(0, b.addr(0x4002), b.range(0x5000, 0x5003));
|
||||
}
|
||||
|
||||
assertEquals(5, manager.getReferenceCountFrom(0, b.addr(0x4000)));
|
||||
|
@ -537,7 +559,7 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
|||
@Test
|
||||
public void testSaveAndLoad() throws CancelledException, IOException, VersionException {
|
||||
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.addShiftedReference(0, b.addr(0x4000), b.addr(0x5002), 1);
|
||||
}
|
||||
|
@ -553,9 +575,9 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
|||
manager.getReferencesFrom(0, b.addr(0x4000));
|
||||
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(RefType.DATA, ref.getReferenceType());
|
||||
assertEquals(SourceType.DEFAULT, ref.getSource());
|
||||
|
@ -574,7 +596,7 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
|||
@Test
|
||||
public void testUndo() throws IOException {
|
||||
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.addShiftedReference(0, b.addr(0x4000), b.addr(0x5002), 1);
|
||||
}
|
||||
|
@ -597,9 +619,9 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
|||
.createOverlayAddressSpace("test",
|
||||
b.trace.getBaseAddressFactory().getDefaultAddressSpace());
|
||||
|
||||
b.addMemoryReference(0, os.getAddress(0x4000), os.getAddress(0x5000));
|
||||
b.addMemoryReference(0, os.getAddress(0x4001), b.addr(0x5001));
|
||||
b.addMemoryReference(0, b.addr(0x4002), os.getAddress(0x5002));
|
||||
b.addMemoryReference(0, os.getAddress(0x4000), b.range(os, 0x5000, 0x5003));
|
||||
b.addMemoryReference(0, os.getAddress(0x4001), b.range(0x5004, 0x5007));
|
||||
b.addMemoryReference(0, b.addr(0x4002), b.range(os, 0x5008, 0x500b));
|
||||
}
|
||||
|
||||
File saved = b.save();
|
||||
|
@ -613,19 +635,19 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
|||
AddressSpace os = b.trace.getBaseAddressFactory().getAddressSpace("test");
|
||||
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);
|
||||
assertEquals(os, ref.getFromAddress().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);
|
||||
assertEquals(os, ref.getFromAddress().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);
|
||||
assertEquals(ds, ref.getFromAddress().getAddressSpace());
|
||||
assertEquals(os, ref.getToAddress().getAddressSpace());
|
||||
|
@ -636,11 +658,11 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
|
|||
assertEquals(0, manager.getReferenceCountFrom(0, os.getAddress(0x4002)));
|
||||
assertEquals(1, manager.getReferenceCountFrom(0, b.addr(0x4002)));
|
||||
|
||||
assertEquals(0, manager.getReferenceCountTo(0, os.getAddress(0x5001)));
|
||||
assertEquals(1, manager.getReferenceCountTo(0, b.addr(0x5001)));
|
||||
assertEquals(0, manager.getReferenceCountTo(0, os.getAddress(0x5004)));
|
||||
assertEquals(1, manager.getReferenceCountTo(0, b.addr(0x5004)));
|
||||
|
||||
assertEquals(0, manager.getReferenceCountTo(0, b.addr(0x5002)));
|
||||
assertEquals(1, manager.getReferenceCountTo(0, os.getAddress(0x5002)));
|
||||
assertEquals(0, manager.getReferenceCountTo(0, b.addr(0x5008)));
|
||||
assertEquals(1, manager.getReferenceCountTo(0, os.getAddress(0x5008)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue