Merge remote-tracking branch 'origin/patch'

This commit is contained in:
ghidra1 2022-01-04 19:18:55 -05:00
commit a5e16b7237
10 changed files with 112 additions and 73 deletions

View file

@ -57,7 +57,7 @@
<LI>Address - when evaluation succeeds, the address of the watch's value. This field is <LI>Address - when evaluation succeeds, the address of the watch's value. This field is
really only meaningful when the outermost operator of the expression is a memory dereference. really only meaningful when the outermost operator of the expression is a memory dereference.
Double-clicking a row will navigate the primary dynamic listing to this address, if Double-clicking this cell will navigate the primary dynamic listing to this address, if
possible.</LI> possible.</LI>
<LI>Value - the raw bytes of the watched buffer. If the expression is a register, then this <LI>Value - the raw bytes of the watched buffer. If the expression is a register, then this
@ -71,7 +71,9 @@
possible.</LI> possible.</LI>
<LI>Representation - the value of the watch as interpreted by the selected data type. This <LI>Representation - the value of the watch as interpreted by the selected data type. This
field is not yet user modifiable, even if the <B>Enable Edits</B> toggle is on.</LI> field is not yet user modifiable, even if the <B>Enable Edits</B> toggle is on. If the value
is an address, i.e., Type is a pointer, then double-clicking this cell will navigate the
primary dynamic listing, if possible.</LI>
<LI>Error - if an error occurs during compilation or evaluation of the expression, that error <LI>Error - if an error occurs during compilation or evaluation of the expression, that error
is rendered here. Double-clicking the row will display the stack trace. Note that errors is rendered here. Double-clicking the row will display the stack trace. Note that errors

View file

@ -20,7 +20,6 @@ import java.awt.FontMetrics;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map.Entry;
import docking.widgets.fieldpanel.internal.LayoutBackgroundColorManager; import docking.widgets.fieldpanel.internal.LayoutBackgroundColorManager;
import docking.widgets.fieldpanel.support.FieldSelection; import docking.widgets.fieldpanel.support.FieldSelection;
@ -34,7 +33,6 @@ import ghidra.framework.options.AutoOptions;
import ghidra.framework.options.annotation.AutoOptionConsumed; import ghidra.framework.options.annotation.AutoOptionConsumed;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.trace.model.Trace; import ghidra.trace.model.Trace;
import ghidra.trace.model.TraceAddressSnapRange;
import ghidra.trace.model.memory.TraceMemoryState; import ghidra.trace.model.memory.TraceMemoryState;
public class DebuggerMemoryByteViewerComponent extends ByteViewerComponent public class DebuggerMemoryByteViewerComponent extends ByteViewerComponent
@ -71,37 +69,45 @@ public class DebuggerMemoryByteViewerComponent extends ByteViewerComponent
} }
Trace trace = coordinates.getTrace(); Trace trace = coordinates.getTrace();
// TODO: Mimic the listing's background, or factor into common // TODO: Mimic the listing's background, or factor into common
long snap = coordinates.getSnap(); long viewSnap = coordinates.getViewSnap();
// TODO: Span out and cache? // TODO: Span out and cache?
AddressSetView lineAddresses = translator.convertFieldToAddress(lineFieldSel); AddressSetView lineAddresses = translator.convertFieldToAddress(lineFieldSel);
// Because UNKNOWN need not be explicitly recorded, compute it by subtracting others AddressSet known = new AddressSet();
AddressSet unknown = new AddressSet(lineAddresses); AddressSet error = new AddressSet();
for (AddressRange range : lineAddresses) {
for (Entry<TraceAddressSnapRange, TraceMemoryState> entry : trace.getMemoryManager() for (Address addr : lineAddresses.getAddresses(true)) {
.getStates(snap, range)) { TraceMemoryState state =
if (entry.getValue() != TraceMemoryState.UNKNOWN) { trace.getMemoryManager().getViewState(viewSnap, addr).getValue();
unknown.delete(entry.getKey().getRange()); switch (state) {
} case KNOWN:
Color color = colorForState(entry.getValue()); known.add(addr);
if (color == null) { break;
continue; case ERROR:
} error.add(addr);
// NOTE: Only TraceMemoryState.ERROR should reach here break;
FieldSelection resultFieldSel = default:
translator.convertAddressToField(entry.getKey().getRange()); // Don't care
if (!resultFieldSel.isEmpty()) {
selections.add(new ColoredFieldSelection(resultFieldSel, color));
}
} }
} }
if (unknownColor == null) { AddressSet unknown = new AddressSet(lineAddresses);
unknown.delete(known);
unknown.delete(error);
doAddSelections(unknownColor, unknown, translator, selections);
doAddSelections(errorColor, error, translator, selections);
}
protected void doAddSelections(Color color, AddressSetView set,
SelectionTranslator translator, List<ColoredFieldSelection> selections) {
if (color == null) {
return; return;
} }
for (AddressRange unk : unknown) { for (AddressRange rng : set) {
FieldSelection resultFieldSel = translator.convertAddressToField(unk); FieldSelection resultFieldSel = translator.convertAddressToField(rng);
if (!resultFieldSel.isEmpty()) { if (resultFieldSel.isEmpty()) {
selections.add(new ColoredFieldSelection(resultFieldSel, unknownColor)); continue;
} }
selections.add(new ColoredFieldSelection(resultFieldSel, color));
} }
} }
} }
@ -133,18 +139,6 @@ public class DebuggerMemoryByteViewerComponent extends ByteViewerComponent
// NOTE: Cursor, being line-by-line, is done via background color model in super // NOTE: Cursor, being line-by-line, is done via background color model in super
} }
protected Color colorForState(TraceMemoryState state) {
switch (state) {
case ERROR:
return errorColor;
case KNOWN:
return null;
case UNKNOWN:
return unknownColor;
}
throw new AssertionError();
}
@Override @Override
protected LayoutBackgroundColorManager getLayoutSelectionMap(BigInteger layoutIndex) { protected LayoutBackgroundColorManager getLayoutSelectionMap(BigInteger layoutIndex) {
Color backgroundColor = backgroundColorModel.getBackgroundColor(layoutIndex); Color backgroundColor = backgroundColorModel.getBackgroundColor(layoutIndex);

View file

@ -334,24 +334,7 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter {
if (e.getClickCount() != 2 || e.getButton() != MouseEvent.BUTTON1) { if (e.getClickCount() != 2 || e.getButton() != MouseEvent.BUTTON1) {
return; return;
} }
if (myActionContext == null) { navigateToSelectedWatch();
return;
}
WatchRow row = myActionContext.getWatchRow();
if (row == null) {
return;
}
Throwable error = row.getError();
if (error != null) {
Msg.showError(this, getComponent(), "Evaluation error",
"Could not evaluate watch", error);
return;
}
Address address = myActionContext.getWatchRow().getAddress();
if (listingService == null || address == null || !address.isMemoryAddress()) {
return;
}
listingService.goTo(address, true);
} }
}); });
@ -371,6 +354,44 @@ public class DebuggerWatchesProvider extends ComponentProviderAdapter {
super.contextChanged(); super.contextChanged();
} }
protected void navigateToSelectedWatch() {
if (myActionContext == null) {
return;
}
WatchRow row = myActionContext.getWatchRow();
if (row == null) {
return;
}
int modelCol = watchTable.convertColumnIndexToModel(watchTable.getSelectedColumn());
Throwable error = row.getError(); // I don't care the selected column for errors
if (error != null) {
Msg.showError(this, getComponent(), "Evaluation error",
"Could not evaluate watch", error);
}
else if (modelCol == WatchTableColumns.ADDRESS.ordinal()) {
Address address = row.getAddress();
if (address != null) {
navigateToAddress(address);
}
}
else if (modelCol == WatchTableColumns.REPR.ordinal()) {
Object val = row.getValueObj();
if (val instanceof Address) {
navigateToAddress((Address) val);
}
}
}
protected void navigateToAddress(Address address) {
if (listingService == null) {
return;
}
if (address.isMemoryAddress()) {
listingService.goTo(address, true);
return;
}
}
protected void createActions() { protected void createActions() {
actionEnableEdits = DebuggerResources.EnableEditsAction.builder(plugin) actionEnableEdits = DebuggerResources.EnableEditsAction.builder(plugin)
.enabledWhen(c -> current.getTrace() != null) .enabledWhen(c -> current.getTrace() != null)

View file

@ -64,6 +64,7 @@ public class WatchRow {
private byte[] value; private byte[] value;
private byte[] prevValue; // Value at previous coordinates private byte[] prevValue; // Value at previous coordinates
private String valueString; private String valueString;
private Object valueObj;
private Throwable error = null; private Throwable error = null;
public WatchRow(DebuggerWatchesProvider provider, String expression) { public WatchRow(DebuggerWatchesProvider provider, String expression) {
@ -77,6 +78,7 @@ public class WatchRow {
reads = null; reads = null;
value = null; value = null;
valueString = null; valueString = null;
valueObj = null;
} }
protected void recompile() { protected void recompile() {
@ -125,20 +127,29 @@ public class WatchRow {
address = valueWithAddress.getRight(); address = valueWithAddress.getRight();
reads = executorWithAddress.getReads(); reads = executorWithAddress.getReads();
valueString = parseAsDataType(); valueObj = parseAsDataTypeObj();
valueString = parseAsDataTypeStr();
} }
catch (Exception e) { catch (Exception e) {
error = e; error = e;
} }
} }
protected String parseAsDataType() { protected String parseAsDataTypeStr() {
if (dataType == null || value == null) { if (dataType == null || value == null) {
return ""; return "";
} }
MemBuffer buffer = new ByteMemBufferImpl(address, value, language.isBigEndian()); MemBuffer buffer = new ByteMemBufferImpl(address, value, language.isBigEndian());
return dataType.getRepresentation(buffer, SettingsImpl.NO_SETTINGS, value.length); return dataType.getRepresentation(buffer, SettingsImpl.NO_SETTINGS, value.length);
} }
protected Object parseAsDataTypeObj() {
if (dataType == null || value == null) {
return null;
}
MemBuffer buffer = new ByteMemBufferImpl(address, value, language.isBigEndian());
return dataType.getValue(buffer, SettingsImpl.NO_SETTINGS, value.length);
}
public static class ReadDepsTraceBytesPcodeExecutorState public static class ReadDepsTraceBytesPcodeExecutorState
extends TraceBytesPcodeExecutorState { extends TraceBytesPcodeExecutorState {
@ -299,7 +310,8 @@ public class WatchRow {
public void setDataType(DataType dataType) { public void setDataType(DataType dataType) {
this.typePath = dataType == null ? null : dataType.getPathName(); this.typePath = dataType == null ? null : dataType.getPathName();
this.dataType = dataType; this.dataType = dataType;
valueString = parseAsDataType(); valueString = parseAsDataTypeStr();
valueObj = parseAsDataTypeObj();
provider.contextChanged(); provider.contextChanged();
} }
@ -357,6 +369,10 @@ public class WatchRow {
return valueString; return valueString;
} }
public Object getValueObj() {
return valueObj;
}
public boolean isValueEditable() { public boolean isValueEditable() {
return address != null && provider.isEditsEnabled(); return address != null && provider.isEditsEnabled();
} }

View file

@ -54,7 +54,7 @@ dependencies {
runtimeOnly "org.slf4j:slf4j-nop:1.7.25" runtimeOnly "org.slf4j:slf4j-nop:1.7.25"
// use this if you want slf4j log messages sent to log4j // use this if you want slf4j log messages sent to log4j
// runtimeOnly "org.apache.logging.log4j:log4j-slf4j-impl:2.17.0" // runtimeOnly "org.apache.logging.log4j:log4j-slf4j-impl:2.17.1"
compileOnly "junit:junit:4.12" compileOnly "junit:junit:4.12"

View file

@ -52,7 +52,7 @@ public class ObjectiveC2_Class implements StructConverter {
AddressSpace space = _state.program.getAddressFactory().getDefaultAddressSpace(); AddressSpace space = _state.program.getAddressFactory().getDefaultAddressSpace();
Address addr = space.getAddress(_index); Address addr = space.getAddress(_index);
Symbol symbol = _state.program.getSymbolTable().getPrimarySymbol(addr); Symbol symbol = _state.program.getSymbolTable().getPrimarySymbol(addr);
if (symbol.getParentNamespace().getName().equals(SectionNames.SECT_GOT)) { if (symbol != null && symbol.getParentNamespace().getName().equals(SectionNames.SECT_GOT)) {
return; return;
} }

View file

@ -37,9 +37,15 @@ public class ObjectiveC2_Method extends ObjectiveC_Method {
if (isSmallList) { if (isSmallList) {
int nameOffset = (int)ObjectiveC1_Utilities.readNextIndex(reader, true); int nameOffset = (int)ObjectiveC1_Utilities.readNextIndex(reader, true);
int namePtr = reader.readInt(_index + nameOffset); long namePtr;
long imagebase = state.program.getImageBase().getOffset(); // When we support dyld_shared_cache, this base will likely have to change if (state.is32bit) {
name = reader.readAsciiString(imagebase + namePtr); namePtr = reader.readInt(_index + nameOffset);
}
else {
namePtr = reader.readLong(_index + nameOffset);
}
name = reader.readAsciiString(namePtr);
int typesOffset = (int)ObjectiveC1_Utilities.readNextIndex(reader, true); int typesOffset = (int)ObjectiveC1_Utilities.readNextIndex(reader, true);
types = reader.readAsciiString(_index + 4 + typesOffset); types = reader.readAsciiString(_index + 4 + typesOffset);

View file

@ -1,13 +1,13 @@
MODULE FILE LICENSE: lib/cglib-nodep-2.2.jar Apache License 2.0 MODULE FILE LICENSE: lib/cglib-nodep-2.2.jar Apache License 2.0
MODULE FILE LICENSE: lib/guava-19.0.jar Apache License 2.0 MODULE FILE LICENSE: lib/guava-19.0.jar Apache License 2.0
MODULE FILE LICENSE: lib/jdom-legacy-1.1.3.jar JDOM License MODULE FILE LICENSE: lib/jdom-legacy-1.1.3.jar JDOM License
MODULE FILE LICENSE: lib/log4j-api-2.17.0.jar Apache License 2.0 MODULE FILE LICENSE: lib/log4j-api-2.17.1.jar Apache License 2.0
MODULE FILE LICENSE: lib/log4j-core-2.17.0.jar Apache License 2.0 MODULE FILE LICENSE: lib/log4j-core-2.17.1.jar Apache License 2.0
MODULE FILE LICENSE: lib/commons-collections4-4.1.jar Apache License 2.0 MODULE FILE LICENSE: lib/commons-collections4-4.1.jar Apache License 2.0
MODULE FILE LICENSE: lib/commons-lang3-3.9.jar Apache License 2.0 MODULE FILE LICENSE: lib/commons-lang3-3.9.jar Apache License 2.0
MODULE FILE LICENSE: lib/commons-io-2.6.jar Apache License 2.0 MODULE FILE LICENSE: lib/commons-io-2.6.jar Apache License 2.0
MODULE FILE LICENSE: lib/commons-text-1.6.jar Apache License 2.0 MODULE FILE LICENSE: lib/commons-text-1.6.jar Apache License 2.0
MODULE FILE LICENSE: lib/gson-2.8.6.jar Apache License 2.0 MODULE FILE LICENSE: lib/gson-2.8.9.jar Apache License 2.0
MODULE FILE LICENSE: lib/bcpkix-jdk15on-1.69.jar Bouncy Castle License MODULE FILE LICENSE: lib/bcpkix-jdk15on-1.69.jar Bouncy Castle License
MODULE FILE LICENSE: lib/bcprov-jdk15on-1.69.jar Bouncy Castle License MODULE FILE LICENSE: lib/bcprov-jdk15on-1.69.jar Bouncy Castle License
MODULE FILE LICENSE: lib/bcutil-jdk15on-1.69.jar Bouncy Castle License MODULE FILE LICENSE: lib/bcutil-jdk15on-1.69.jar Bouncy Castle License

View file

@ -29,13 +29,13 @@ dependencies {
api "cglib:cglib-nodep:2.2" api "cglib:cglib-nodep:2.2"
api "com.google.guava:guava:19.0" api "com.google.guava:guava:19.0"
api "org.jdom:jdom-legacy:1.1.3" api "org.jdom:jdom-legacy:1.1.3"
api "org.apache.logging.log4j:log4j-api:2.17.0" api "org.apache.logging.log4j:log4j-api:2.17.1"
api "org.apache.logging.log4j:log4j-core:2.17.0" api "org.apache.logging.log4j:log4j-core:2.17.1"
api "org.apache.commons:commons-collections4:4.1" api "org.apache.commons:commons-collections4:4.1"
api "org.apache.commons:commons-lang3:3.9" api "org.apache.commons:commons-lang3:3.9"
api "org.apache.commons:commons-text:1.6" api "org.apache.commons:commons-text:1.6"
api "commons-io:commons-io:2.6" api "commons-io:commons-io:2.6"
api "com.google.code.gson:gson:2.8.6" api "com.google.code.gson:gson:2.8.9"
api 'org.bouncycastle:bcpkix-jdk15on:1.69' // requires bcutil and bcprov api 'org.bouncycastle:bcpkix-jdk15on:1.69' // requires bcutil and bcprov
api 'org.bouncycastle:bcprov-jdk15on:1.69' api 'org.bouncycastle:bcprov-jdk15on:1.69'
api 'org.bouncycastle:bcutil-jdk15on:1.69' api 'org.bouncycastle:bcutil-jdk15on:1.69'

View file

@ -19,7 +19,7 @@ eclipse.project.name = '_JsonDoclet'
apply plugin: 'java-library' apply plugin: 'java-library'
dependencies { dependencies {
api "com.google.code.gson:gson:2.8.6" api "com.google.code.gson:gson:2.8.9"
} }
rootProject.createJsondocs.dependsOn jar rootProject.createJsondocs.dependsOn jar