mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-24 13:21:22 +08:00
GP-6586: Allow wb-cache bypass. Update TenetLoader.
This commit is contained in:
+31
-45
@@ -52,6 +52,7 @@ import ghidra.trace.model.stack.TraceStackFrame;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.target.TraceObject.ConflictResolution;
|
||||
import ghidra.trace.model.target.TraceObjectManager;
|
||||
import ghidra.trace.model.target.TraceObjectManager.BypassWriteCache;
|
||||
import ghidra.trace.model.target.path.KeyPath;
|
||||
import ghidra.trace.model.target.schema.*;
|
||||
import ghidra.trace.model.target.schema.TraceObjectSchema.SchemaName;
|
||||
@@ -151,10 +152,10 @@ public class TenetLoader implements Loader {
|
||||
TENET_SESSION_SCHEMA = SAMPLE_CTX.getSchema(new SchemaName("TenetSession"));
|
||||
}
|
||||
|
||||
private static AddressSpace defaultSpace;
|
||||
private static Program program;
|
||||
private AddressSpace defaultSpace;
|
||||
private Program program;
|
||||
|
||||
private static boolean STORE_REG_ATTRS = false;
|
||||
private static final boolean STORE_REG_ATTRS = false;
|
||||
|
||||
/**
|
||||
* Create an address in the processor's default space.
|
||||
@@ -162,7 +163,7 @@ public class TenetLoader implements Loader {
|
||||
* @param offset the byte offset
|
||||
* @return the address
|
||||
*/
|
||||
private static Address addr(final long offset) {
|
||||
private Address addr(final long offset) {
|
||||
return defaultSpace.getAddress(offset);
|
||||
}
|
||||
|
||||
@@ -205,11 +206,11 @@ public class TenetLoader implements Loader {
|
||||
* @param max the maximum (inclusive) byte offset
|
||||
* @return the range
|
||||
*/
|
||||
private static AddressRange rng(final long min, final long max) {
|
||||
private AddressRange rng(final long min, final long max) {
|
||||
return new AddressRangeImpl(addr(min), addr(max));
|
||||
}
|
||||
|
||||
private static Address toAddr(final String addressString) {
|
||||
private Address toAddr(final String addressString) {
|
||||
return AddressEvaluator.evaluate(program, addressString);
|
||||
}
|
||||
|
||||
@@ -321,14 +322,16 @@ public class TenetLoader implements Loader {
|
||||
final Object consumer, final MessageLog log, final TaskMonitor monitor)
|
||||
throws LanguageNotFoundException, IOException, CancelledException {
|
||||
|
||||
TenetLoader.program = program;
|
||||
this.program = program;
|
||||
final Language lang = program.getLanguage();
|
||||
TenetLoader.defaultSpace = lang.getAddressFactory().getDefaultAddressSpace();
|
||||
this.defaultSpace = lang.getAddressFactory().getDefaultAddressSpace();
|
||||
|
||||
final Trace trace = new DBTrace(name, program.getCompilerSpec(), consumer);
|
||||
final TraceObjectManager om = trace.getObjectManager();
|
||||
|
||||
try (Transaction tx = trace.openTransaction("Import Tenet Trace: %s".formatted(name));
|
||||
BypassWriteCache bypass = om.withoutWriteCache()) {
|
||||
|
||||
try (Transaction tx = trace.openTransaction("Import Tenet Trace: %s".formatted(name))) {
|
||||
final TraceObjectManager om = trace.getObjectManager();
|
||||
om.createRootObject(TENET_SESSION_SCHEMA);
|
||||
|
||||
final TraceThread traceThread =
|
||||
@@ -364,8 +367,9 @@ public class TenetLoader implements Loader {
|
||||
line = reader.readLine();
|
||||
}
|
||||
|
||||
final TraceSnapshot snapshot =
|
||||
TraceSnapshot snapshot =
|
||||
trace.getTimeManager().createSnapshot("Snapshot %d".formatted(snapNumber));
|
||||
snapshot.setEventThread(traceThread);
|
||||
long snap = snapshot.getKey();
|
||||
|
||||
snapNumber++;
|
||||
@@ -381,51 +385,33 @@ public class TenetLoader implements Loader {
|
||||
}
|
||||
|
||||
final Matcher ipMatcher = ipPattern.matcher(line);
|
||||
if (!ipMatcher.find()) {
|
||||
if (ipMatcher.find()) {
|
||||
curIp = Long.parseLong(ipMatcher.group(1), 16);
|
||||
|
||||
if (parseRegisterOperations(snap, curIp, line, lineNumber, traceThread,
|
||||
trace, log, monitor)) {
|
||||
parseMemoryOperations(snap, curIp, line, trace, monitor);
|
||||
}
|
||||
else {
|
||||
errorCount++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.appendMsg(
|
||||
"Line %d: Unable to find PC, skipping...".formatted(lineNumber));
|
||||
errorCount++;
|
||||
lineNumber++;
|
||||
monitor.setProgress(lineNumber);
|
||||
|
||||
line = reader.readLine();
|
||||
if (line != null) {
|
||||
snap = trace.getTimeManager()
|
||||
.createSnapshot("Snapshot %d".formatted(snapNumber))
|
||||
.getKey();
|
||||
snapNumber++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
curIp = Long.parseLong(ipMatcher.group(1), 16);
|
||||
|
||||
if (!parseRegisterOperations(snap, curIp, line, lineNumber, traceThread,
|
||||
trace, log, monitor)) {
|
||||
errorCount++;
|
||||
lineNumber++;
|
||||
monitor.setProgress(lineNumber);
|
||||
|
||||
line = reader.readLine();
|
||||
if (line != null) {
|
||||
snap = trace.getTimeManager()
|
||||
.createSnapshot("Snapshot %d".formatted(snapNumber))
|
||||
.getKey();
|
||||
snapNumber++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
parseMemoryOperations(snap, curIp, line, trace, monitor);
|
||||
|
||||
lineNumber++;
|
||||
monitor.setProgress(lineNumber);
|
||||
|
||||
line = reader.readLine();
|
||||
if (line != null) {
|
||||
snap = trace.getTimeManager()
|
||||
.createSnapshot("Snapshot %d".formatted(snapNumber))
|
||||
.getKey();
|
||||
snapshot = trace.getTimeManager()
|
||||
.createSnapshot("Snapshot %d".formatted(snapNumber));
|
||||
snap = snapshot.getKey();
|
||||
snapshot.setEventThread(traceThread);
|
||||
snapNumber++;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-3
@@ -189,6 +189,7 @@ public class DBTraceObjectManager implements TraceObjectManager, DBTraceManager
|
||||
protected final DBTraceObjectValueRStarTree valueTree;
|
||||
protected final DBTraceObjectValueMap valueMap;
|
||||
protected final DBTraceObjectValueWriteBehindCache valueWbCache;
|
||||
protected boolean wbCacheDisabled;
|
||||
|
||||
protected final DBCachedObjectIndex<KeyPath, DBTraceObject> objectsByPath;
|
||||
|
||||
@@ -331,9 +332,10 @@ public class DBTraceObjectManager implements TraceObjectManager, DBTraceManager
|
||||
protected DBTraceObjectValue doCreateValue(Lifespan lifespan, DBTraceObject parent, String key,
|
||||
Object value) {
|
||||
// Root is never in write-behind cache
|
||||
DBTraceObjectValue entry =
|
||||
parent == null ? doCreateValueData(lifespan, parent, key, value).getWrapper()
|
||||
: valueWbCache.doCreateValue(lifespan, parent, key, value).getWrapper();
|
||||
boolean skipWb = wbCacheDisabled || parent == null;
|
||||
DBTraceObjectValue entry = skipWb
|
||||
? doCreateValueData(lifespan, parent, key, value).getWrapper()
|
||||
: valueWbCache.doCreateValue(lifespan, parent, key, value).getWrapper();
|
||||
if (parent != null) {
|
||||
parent.notifyValueCreated(entry);
|
||||
}
|
||||
@@ -867,4 +869,15 @@ public class DBTraceObjectManager implements TraceObjectManager, DBTraceManager
|
||||
public void waitWbWorkers() {
|
||||
valueWbCache.waitWorkers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BypassWriteCache withoutWriteCache() {
|
||||
wbCacheDisabled = true;
|
||||
return new BypassWriteCache() {
|
||||
@Override
|
||||
public void close() {
|
||||
wbCacheDisabled = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+22
@@ -196,4 +196,26 @@ public interface TraceObjectManager {
|
||||
* database permits schema modification, but requires that the entire model be replaced.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* A handle to automatically re-enable the write cache
|
||||
*/
|
||||
interface BypassWriteCache extends AutoCloseable {
|
||||
@Override
|
||||
void close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Bypass the write cache, usually for an import operation.
|
||||
* <p>
|
||||
* For live sessions, we typically want to complete object writes as promptly as possible, so we
|
||||
* don't tie up the connection and/or the remote debugger. However, for import operations, we'd
|
||||
* rather just have object writes go straight to the database. The importer will want to save,
|
||||
* which requires flushing the cache anyway. Disabling the cache gives more honest progress
|
||||
* reporting and assures any crashes or diagnostics occur during the import rather than during
|
||||
* the flush.
|
||||
*
|
||||
* @return a handle to automatically re-enable the write cache
|
||||
*/
|
||||
BypassWriteCache withoutWriteCache();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user