fix for reg names([]) and update in stack container

This commit is contained in:
d-millar 2020-12-18 17:19:33 -05:00 committed by Dan
parent 6d15c4e00e
commit 8871595322
4 changed files with 20 additions and 61 deletions

View File

@ -52,12 +52,12 @@ public class GdbModelTargetRegister
this.bitLength = register.getSize() * 8;
changeAttributes(List.of(), Map.of(
CONTAINER_ATTRIBUTE_NAME, registers,
LENGTH_ATTRIBUTE_NAME, bitLength,
DISPLAY_ATTRIBUTE_NAME, register.getName(),
UPDATE_MODE_ATTRIBUTE_NAME, TargetUpdateMode.FIXED),
"Initialized");
changeAttributes(List.of(), Map.of( //
CONTAINER_ATTRIBUTE_NAME, registers, //
LENGTH_ATTRIBUTE_NAME, bitLength, //
DISPLAY_ATTRIBUTE_NAME, getName(), //
UPDATE_MODE_ATTRIBUTE_NAME, TargetUpdateMode.FIXED //
), "Initialized");
}
@Override
@ -67,6 +67,6 @@ public class GdbModelTargetRegister
@Override
public String getDisplay() {
return register.getName();
return getName();
}
}

View File

@ -19,7 +19,8 @@ import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import agent.gdb.manager.*;
import agent.gdb.manager.GdbRegister;
import agent.gdb.manager.GdbStackFrame;
import ghidra.dbg.agent.DefaultTargetObject;
import ghidra.dbg.error.DebuggerRegisterAccessException;
import ghidra.dbg.target.*;
@ -53,8 +54,6 @@ public class GdbModelTargetStackFrame extends DefaultTargetObject<TargetObject,
protected final GdbModelTargetThread thread;
protected final GdbModelTargetInferior inferior;
private Set<GdbRegister> lastRead;
protected GdbStackFrame frame;
protected Address pc;
protected String func;
@ -98,7 +97,6 @@ public class GdbModelTargetStackFrame extends DefaultTargetObject<TargetObject,
}
toRead.add(reg.register);
}
this.lastRead = toRead;
return frame.readRegisters(toRead);
}).thenApply(vals -> {
Map<String, byte[]> result = new LinkedHashMap<>();
@ -168,8 +166,4 @@ public class GdbModelTargetStackFrame extends DefaultTargetObject<TargetObject,
return frame.select();
}
public CompletableFuture<GdbRegisterSet> listRegisters() {
GdbRegisterSet set = new GdbRegisterSet(lastRead);
return CompletableFuture.completedFuture(set);
}
}

View File

@ -58,7 +58,7 @@ public class GdbModelTargetStackFrameRegister
changeAttributes(List.of(), Map.of( //
CONTAINER_ATTRIBUTE_NAME, registers, //
LENGTH_ATTRIBUTE_NAME, bitLength, //
DISPLAY_ATTRIBUTE_NAME, register.getName(), //
DISPLAY_ATTRIBUTE_NAME, getName(), //
UPDATE_MODE_ATTRIBUTE_NAME, TargetUpdateMode.FIXED //
), "Initialized");
}

View File

@ -16,16 +16,11 @@
package agent.gdb.model.impl;
import java.math.BigInteger;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.*;
import agent.gdb.manager.GdbRegister;
import ghidra.async.AsyncUtils;
import ghidra.dbg.agent.DefaultTargetObject;
import ghidra.dbg.target.TargetRegisterContainer;
import ghidra.util.Msg;
import ghidra.util.datastruct.WeakValueHashMap;
public class GdbModelTargetStackFrameRegisterContainer
@ -46,62 +41,32 @@ public class GdbModelTargetStackFrameRegisterContainer
this.thread = frame.thread;
}
@Override
public CompletableFuture<Void> requestElements(boolean refresh) {
return doRefresh();
}
protected CompletableFuture<Void> doRefresh() {
return completeUsingThread();
}
protected CompletableFuture<Void> completeUsingThread() {
return frame.listRegisters().thenAccept(regs -> {
List<GdbModelTargetStackFrameRegister> registers;
synchronized (this) { // calls getTargetRegister
// No stale garbage. New architecture may re-use numbers, so clear cache out!
registersByNumber.clear();
registers = regs.stream().map(this::getTargetRegister).collect(Collectors.toList());
}
// TODO: Equality only considers paths, i.e., name. If a name is re-used, the old
// stuff has to go. Not sure how to accomplish that, yet.
setElements(registers, "Refreshed");
});
}
protected synchronized GdbModelTargetStackFrameRegister getTargetRegister(
GdbRegister register) {
return registersByNumber.computeIfAbsent(register.getNumber(),
n -> new GdbModelTargetStackFrameRegister(this, register));
}
public CompletableFuture<Void> refresh() {
if (!isObserved()) {
return AsyncUtils.NIL;
}
return doRefresh().exceptionally(ex -> {
Msg.error(this, "Problem refreshing frame's register descriptions", ex);
return null;
});
}
public void setValues(Map<GdbRegister, BigInteger> values) {
List<GdbModelTargetStackFrameRegister> registers = new ArrayList<>();
for (GdbRegister gdbreg : values.keySet()) {
GdbModelTargetStackFrameRegister reg = registersByNumber.get(gdbreg.getNumber());
if (reg == null) {
return;
}
String value = values.get(gdbreg).toString(16);
GdbModelTargetStackFrameRegister reg = getTargetRegister(gdbreg);
registers.add(reg);
}
changeElements(List.of(), registers, "Refreshed");
for (GdbModelTargetStackFrameRegister reg : registers) {
String value = values.get(reg.register).toString(16);
String oldval = (String) reg.getCachedAttributes().get(VALUE_ATTRIBUTE_NAME);
reg.changeAttributes(List.of(), Map.of( //
VALUE_ATTRIBUTE_NAME, value //
), "Refreshed");
if (values.get(gdbreg).longValue() != 0) {
if (values.get(reg.register).longValue() != 0) {
String newval = reg.getName() + " : " + value;
reg.changeAttributes(List.of(), Map.of( //
DISPLAY_ATTRIBUTE_NAME, newval //
), "Refreshed");
reg.setModified(!value.equals(oldval));
listeners.fire.displayChanged(this, newval);
}
}
}