Merge branch 'GP-1525_ghidra1_ExternalFunctionPrimary' into Ghidra_10.1

This commit is contained in:
ghidra1 2021-11-23 21:44:26 -05:00
commit 5c82f87905
18 changed files with 553 additions and 433 deletions

View file

@ -160,6 +160,15 @@ public abstract class AbstractDBTraceProgramViewReferenceManager implements Refe
new AddressRangeImpl(fromAddr, fromAddr));
}
@Override
public void removeAllReferencesTo(Address toAddr) {
if (refs(false) == null) {
return;
}
refs.clearReferencesTo(Range.closed(program.snap, program.snap),
new AddressRangeImpl(toAddr, toAddr));
}
@Override
public Reference[] getReferencesTo(Variable var) {
return TODO();

View file

@ -266,6 +266,11 @@ public class DBTraceReferenceManager extends
Collections.emptyList());
}
@Override
public void clearReferencesTo(Range<Long> span, AddressRange range) {
delegateDeleteV(range.getAddressSpace(), s -> s.clearReferencesTo(span, range));
}
@Override
public AddressSetView getReferenceSources(Range<Long> span) {
return new UnionAddressSetView(

View file

@ -578,28 +578,26 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
@Override
public void clearReferencesFrom(Range<Long> span, AddressRange range) {
long startSnap = DBTraceUtils.lowerEndpoint(span);
for (DBTraceReferenceEntry ref : referenceMapSpace.reduce(
TraceAddressSnapRangeQuery.intersecting(range, span)).values()) {
if (DBTraceUtils.lowerEndpoint(ref.getLifespan()) < startSnap) {
Range<Long> oldSpan = ref.getLifespan();
ref.setEndSnap(startSnap - 1);
trace.setChanged(new TraceChangeRecord<>(TraceReferenceChangeType.LIFESPAN_CHANGED,
this, ref.ref, oldSpan, ref.getLifespan()));
}
else {
ref.ref.delete();
try (LockHold hold = manager.getTrace().lockWrite()) {
long startSnap = DBTraceUtils.lowerEndpoint(span);
for (DBTraceReferenceEntry ref : referenceMapSpace.reduce(
TraceAddressSnapRangeQuery.intersecting(range, span)).values()) {
truncateOrDeleteEntry(ref, startSnap);
}
// TODO: Coalesce events?
}
}
protected DBTraceReference getRefForXRefEntry(DBTraceXRefEntry e) {
protected DBTraceReferenceEntry getRefEntryForXRefEntry(DBTraceXRefEntry e) {
AddressSpace fromAddressSpace =
baseLanguage.getAddressFactory().getAddressSpace(e.refSpaceId);
DBTraceReferenceSpace fromSpace = manager.getForSpace(fromAddressSpace, false);
assert fromSpace != null;
return fromSpace.referenceMapSpace.getDataByKey(e.refKey).ref;
return fromSpace.referenceMapSpace.getDataByKey(e.refKey);
}
protected DBTraceReference getRefForXRefEntry(DBTraceXRefEntry e) {
return getRefEntryForXRefEntry(e).ref;
}
@Override
@ -617,6 +615,31 @@ public class DBTraceReferenceSpace implements DBTraceSpaceBased, TraceReferenceS
this::getRefForXRefEntry);
}
protected void truncateOrDeleteEntry(DBTraceReferenceEntry ref, long otherStartSnap) {
if (DBTraceUtils.lowerEndpoint(ref.getLifespan()) < otherStartSnap) {
Range<Long> oldSpan = ref.getLifespan();
ref.setEndSnap(otherStartSnap - 1);
trace.setChanged(new TraceChangeRecord<>(TraceReferenceChangeType.LIFESPAN_CHANGED,
this, ref.ref, oldSpan, ref.getLifespan()));
}
else {
ref.ref.delete();
}
}
@Override
public void clearReferencesTo(Range<Long> span, AddressRange range) {
try (LockHold hold = manager.getTrace().lockWrite()) {
long startSnap = DBTraceUtils.lowerEndpoint(span);
for (DBTraceXRefEntry xref : xrefMapSpace.reduce(
TraceAddressSnapRangeQuery.intersecting(range, span)).values()) {
DBTraceReferenceEntry ref = getRefEntryForXRefEntry(xref);
truncateOrDeleteEntry(ref, startSnap);
}
// TODO: Coalesce events?
}
}
@Override
public AddressSetView getReferenceSources(Range<Long> span) {
return new DBTraceAddressSnapRangePropertyMapAddressSetView<>(space, lock,

View file

@ -72,6 +72,8 @@ public interface TraceReferenceOperations {
Collection<? extends TraceReference> getReferencesTo(long snap, Address toAddress);
void clearReferencesTo(Range<Long> span, AddressRange range);
/**
* TODO: Document me
*

View file

@ -461,6 +461,39 @@ public class DBTraceReferenceManagerTest extends AbstractGhidraHeadlessIntegrati
new HashSet<>(manager.getReferencesTo(0, b.addr(0x5000))));
}
@Test
public void testClearReferencesTo() {
DBTraceReference keptRef;
try (UndoableTransaction tid = b.startTransaction()) {
b.addMemoryReference(0, b.addr(0x4000), b.addr(0x5000), 3);
b.addOffsetReference(0, b.addr(0x4001), b.addr(0x5000), 20);
b.addShiftedReference(0, b.addr(0x4002), b.addr(0x5000), 1);
keptRef = b.addMemoryReference(0, b.addr(0x8000), b.addr(0x5001));
}
assertEquals(3, manager.getReferencesTo(0, b.addr(0x5000)).size());
assertEquals(1, manager.getReferencesTo(0, b.addr(0x5001)).size());
try (UndoableTransaction tid = b.startTransaction()) {
manager.clearReferencesTo(Range.atLeast(10L), b.range(0x4000, 0x5000));
}
assertEquals(3, manager.getReferencesTo(0, b.addr(0x5000)).size());
assertEquals(0, manager.getReferencesTo(10, b.addr(0x5000)).size());
assertEquals(Range.closed(0L, 9L),
manager.getReferencesTo(0, b.addr(0x5000)).iterator().next().getLifespan());
try (UndoableTransaction tid = b.startTransaction()) {
manager.clearReferencesTo(Range.atLeast(0L), b.range(0x4000, 0x5000));
}
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(Range.atLeast(0L), keptRef.getLifespan());
}
@Test
public void testGetReferenceSourcesAndDestinations() {
try (UndoableTransaction tid = b.startTransaction()) {