mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-10-22 21:21:02 +00:00
GP-4850: Fix bug in legacy-object compat in space-based managers.
This commit is contained in:
parent
d33af2b972
commit
032769a5a9
|
@ -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.
|
||||
|
@ -88,8 +88,7 @@ public abstract class AbstractDBTraceSpaceBasedManager<M extends DBTraceSpaceBas
|
|||
}
|
||||
}
|
||||
|
||||
private record Frame(TraceThread thread, int level) {
|
||||
}
|
||||
private record Frame(TraceThread thread, int level) {}
|
||||
|
||||
private record TabledSpace(DBTraceSpaceEntry entry, AddressSpace space, TraceThread thread) {
|
||||
private boolean isRegisterSpace() {
|
||||
|
@ -117,7 +116,7 @@ public abstract class AbstractDBTraceSpaceBasedManager<M extends DBTraceSpaceBas
|
|||
protected final Map<AddressSpace, M> memSpaces = new TreeMap<>();
|
||||
// Note: can use hash map here. I see no need to order these spaces
|
||||
protected final Map<Frame, M> regSpaces = new HashMap<>();
|
||||
protected final Map<TraceObject, M> regSpacesByObject = new HashMap<>();
|
||||
protected final Map<TraceObject, M> regSpacesByContainer = new HashMap<>();
|
||||
|
||||
protected final Collection<M> memSpacesView =
|
||||
Collections.unmodifiableCollection(memSpaces.values());
|
||||
|
@ -274,9 +273,8 @@ public abstract class AbstractDBTraceSpaceBasedManager<M extends DBTraceSpaceBas
|
|||
return getForRegisterSpace(frame.getStack().getThread(), frame.getLevel(), createIfAbsent);
|
||||
}
|
||||
|
||||
private M doGetForRegisterSpaceFoundContainer(TraceObject object, TraceObject objRegs,
|
||||
boolean createIfAbsent) {
|
||||
String name = objRegs.getCanonicalPath().toString();
|
||||
private M doGetForRegisterSpaceFoundContainer(TraceObject regsObject, boolean createIfAbsent) {
|
||||
String name = regsObject.getCanonicalPath().toString();
|
||||
if (!createIfAbsent) {
|
||||
try (LockHold hold = LockHold.lock(lock.readLock())) {
|
||||
AddressSpace as = trace.getBaseAddressFactory().getAddressSpace(name);
|
||||
|
@ -288,8 +286,8 @@ public abstract class AbstractDBTraceSpaceBasedManager<M extends DBTraceSpaceBas
|
|||
if (space == null) {
|
||||
return null;
|
||||
}
|
||||
synchronized (regSpacesByObject) {
|
||||
regSpacesByObject.put(object, space);
|
||||
synchronized (regSpacesByContainer) {
|
||||
regSpacesByContainer.put(regsObject, space);
|
||||
}
|
||||
return space;
|
||||
}
|
||||
|
@ -299,8 +297,8 @@ public abstract class AbstractDBTraceSpaceBasedManager<M extends DBTraceSpaceBas
|
|||
.getOrCreateOverlayAddressSpace(name,
|
||||
trace.getBaseAddressFactory().getRegisterSpace());
|
||||
M space = getForSpace(as, createIfAbsent);
|
||||
synchronized (regSpacesByObject) {
|
||||
regSpacesByObject.put(object, space);
|
||||
synchronized (regSpacesByContainer) {
|
||||
regSpacesByContainer.put(regsObject, space);
|
||||
}
|
||||
return space;
|
||||
}
|
||||
|
@ -311,24 +309,29 @@ public abstract class AbstractDBTraceSpaceBasedManager<M extends DBTraceSpaceBas
|
|||
return getForRegisterSpace(thread.getObject(), frameLevel, createIfAbsent);
|
||||
}
|
||||
|
||||
protected M getForRegisterSpace(TraceObject object, int frameLevel, boolean createIfAbsent) {
|
||||
synchronized (regSpacesByObject) {
|
||||
M space = regSpacesByObject.get(object);
|
||||
if (space != null) {
|
||||
return space;
|
||||
}
|
||||
protected TraceObject doGetRegisterContainer(TraceObject threadObject, int frameLevel) {
|
||||
if (threadObject.getTargetSchema()
|
||||
.getInterfaces()
|
||||
.contains(TargetRegisterContainer.class)) {
|
||||
return threadObject;
|
||||
}
|
||||
// It's not critical that we hold the regSpacesByObject the whole time.
|
||||
// If a second has to compute, too, aww well.
|
||||
return threadObject.queryRegisterContainer(frameLevel);
|
||||
}
|
||||
|
||||
protected M getForRegisterSpace(TraceObject threadObject, int frameLevel,
|
||||
boolean createIfAbsent) {
|
||||
try (LockHold hold = LockHold.lock(createIfAbsent ? lock.writeLock() : lock.readLock())) {
|
||||
if (object.getTargetSchema().getInterfaces().contains(TargetRegisterContainer.class)) {
|
||||
return doGetForRegisterSpaceFoundContainer(object, object, createIfAbsent);
|
||||
TraceObject regsObject = doGetRegisterContainer(threadObject, frameLevel);
|
||||
if (regsObject == null) {
|
||||
return null;
|
||||
}
|
||||
TraceObject objRegs = object.queryRegisterContainer(frameLevel);
|
||||
if (objRegs != null) {
|
||||
return doGetForRegisterSpaceFoundContainer(object, objRegs, createIfAbsent);
|
||||
synchronized (regSpacesByContainer) {
|
||||
M space = regSpacesByContainer.get(regsObject);
|
||||
if (space != null) {
|
||||
return space;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return doGetForRegisterSpaceFoundContainer(regsObject, createIfAbsent);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user