Merge remote-tracking branch 'origin/GT-2629-dragonmacher-decompiler-type-hovers'

This commit is contained in:
Ryan Kurtz 2019-06-13 13:58:08 -04:00
commit 96e860856d
6 changed files with 86 additions and 90 deletions

View file

@ -31,7 +31,7 @@ import ghidra.app.services.HoverService;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.SystemUtilities; import ghidra.util.Swing;
public abstract class AbstractHoverProvider implements HoverProvider { public abstract class AbstractHoverProvider implements HoverProvider {
@ -40,12 +40,7 @@ public abstract class AbstractHoverProvider implements HoverProvider {
protected Program program; protected Program program;
protected Field lastField; protected Field lastField;
private static final Comparator<HoverService> HOVER_PRIORITY_COMPARATOR = private static final Comparator<HoverService> HOVER_PRIORITY_COMPARATOR =
new Comparator<HoverService>() { (service1, service2) -> service2.getPriority() - service1.getPriority();
@Override
public int compare(HoverService service1, HoverService service2) {
return service2.getPriority() - service1.getPriority();// Highest priority is first
}
};
protected HoverService activeHoverService; protected HoverService activeHoverService;
protected PopupWindow popupWindow; protected PopupWindow popupWindow;
@ -121,12 +116,9 @@ public abstract class AbstractHoverProvider implements HoverProvider {
public void dispose() { public void dispose() {
// we can be disposed from outside the swing thread // we can be disposed from outside the swing thread
SystemUtilities.runSwingLater(new Runnable() { Swing.runLater(() -> {
@Override
public void run() {
closeHover(); closeHover();
hoverServices.clear(); hoverServices.clear();
}
}); });
program = null; program = null;
@ -148,25 +140,15 @@ public abstract class AbstractHoverProvider implements HoverProvider {
} }
ProgramLocation loc = getHoverLocation(fieldLocation, field, fieldBounds, event); ProgramLocation loc = getHoverLocation(fieldLocation, field, fieldBounds, event);
if (loc == null) {
return;
}
JComponent comp = null;
for (HoverService hoverService : hoverServices) { for (HoverService hoverService : hoverServices) {
comp = hoverService.getHoverComponent(program, loc, fieldLocation, field); JComponent comp = hoverService.getHoverComponent(program, loc, fieldLocation, field);
if (comp != null) { if (comp != null) {
closeHover(); closeHover();
activeHoverService = hoverService; activeHoverService = hoverService;
break;
}
}
if (comp != null) {
showPopup(comp, field, event, fieldBounds); showPopup(comp, field, event, fieldBounds);
return;
}
} }
} }
protected void showPopup(JComponent comp, Field field, MouseEvent event, protected void showPopup(JComponent comp, Field field, MouseEvent event,

View file

@ -45,35 +45,32 @@ public class DecompilerHoverProvider extends AbstractHoverProvider {
protected ProgramLocation getHoverLocation(FieldLocation fieldLocation, Field field, protected ProgramLocation getHoverLocation(FieldLocation fieldLocation, Field field,
Rectangle fieldBounds, MouseEvent event) { Rectangle fieldBounds, MouseEvent event) {
ProgramLocation loc = null; if (!(field instanceof ClangTextField)) {
if (field instanceof ClangTextField) { return null;
}
ClangTextField decompilerField = (ClangTextField) field; ClangTextField decompilerField = (ClangTextField) field;
ClangToken token = decompilerField.getToken(fieldLocation); ClangToken token = decompilerField.getToken(fieldLocation);
if (token instanceof ClangOpToken) { if (token instanceof ClangOpToken) {
return null; return null;
} }
if (token instanceof ClangTypeToken) { if (token instanceof ClangTypeToken) {
ClangTypeToken typeToken = (ClangTypeToken) token; ClangTypeToken typeToken = (ClangTypeToken) token;
HighVariable hv = typeToken.getHighVariable(); HighVariable hv = typeToken.getHighVariable();
if (hv == null) { if (hv == null) {
return null; return null;
} }
Address localAddr = hv.getRepresentative().getAddress(); Address localAddr = hv.getRepresentative().getAddress();
return new ProgramLocation(program, localAddr);
loc = new ProgramLocation(program, localAddr);
} }
else {
if (token.getMinAddress() == null) { if (token.getMinAddress() == null) {
return null; return null;
} }
Address reference = null; Address reference = null;
Varnode vn = token.getVarnode(); Varnode vn = token.getVarnode();
if (vn != null) { if (vn != null) {
HighVariable highVar = vn.getHigh(); HighVariable highVar = vn.getHigh();
@ -82,9 +79,6 @@ public class DecompilerHoverProvider extends AbstractHoverProvider {
} }
} }
loc = new ProgramLocation(program, token.getMinAddress(), reference); return new ProgramLocation(program, token.getMinAddress(), reference);
}
}
return loc;
} }
} }

View file

@ -20,8 +20,7 @@ import javax.swing.JComponent;
import docking.widgets.fieldpanel.field.Field; import docking.widgets.fieldpanel.field.Field;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.GhidraOptions; import ghidra.GhidraOptions;
import ghidra.app.decompiler.ClangToken; import ghidra.app.decompiler.*;
import ghidra.app.decompiler.ClangTypeToken;
import ghidra.app.decompiler.component.ClangTextField; import ghidra.app.decompiler.component.ClangTextField;
import ghidra.app.plugin.core.hover.AbstractDataTypeHover; import ghidra.app.plugin.core.hover.AbstractDataTypeHover;
import ghidra.app.util.ToolTipUtils; import ghidra.app.util.ToolTipUtils;
@ -29,6 +28,8 @@ import ghidra.framework.options.Options;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataType;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.pcode.HighVariable;
import ghidra.program.model.pcode.Varnode;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
public class DataTypeDecompilerHover extends AbstractDataTypeHover public class DataTypeDecompilerHover extends AbstractDataTypeHover
@ -62,37 +63,53 @@ public class DataTypeDecompilerHover extends AbstractDataTypeHover
public JComponent getHoverComponent(Program program, ProgramLocation programLocation, public JComponent getHoverComponent(Program program, ProgramLocation programLocation,
FieldLocation fieldLocation, Field field) { FieldLocation fieldLocation, Field field) {
if (!enabled || programLocation == null) { if (!enabled) {
return null; return null;
} }
DataType dt = null; if (!(field instanceof ClangTextField)) {
return null;
}
boolean hasInvalidStorage = false;
if (field instanceof ClangTextField) {
ClangToken token = ((ClangTextField) field).getToken(fieldLocation); ClangToken token = ((ClangTextField) field).getToken(fieldLocation);
if (token instanceof ClangTypeToken) { DataType dt = getDataType(token);
dt = ((ClangTypeToken) token).getDataType(); if (dt == null) {
dt = getDataType(token.Parent());
} }
if (dt != null) { if (dt != null) {
String toolTipText = ToolTipUtils.getToolTipText(dt); String toolTipText = ToolTipUtils.getToolTipText(dt);
String warningMsg = "";
if (hasInvalidStorage) {
warningMsg += "WARNING! Invalid Storage";
}
if (warningMsg.length() != 0) {
String errorText =
"<HTML><center><font color=\"red\">" + warningMsg + "!</font></center><BR>";
toolTipText = toolTipText.replace("<HTML>", errorText);
}
return createTooltipComponent(toolTipText); return createTooltipComponent(toolTipText);
} }
}
return null; return null;
} }
private DataType getDataType(ClangNode node) {
if (node instanceof ClangVariableDecl) {
return ((ClangVariableDecl) node).getDataType();
}
if (node instanceof ClangReturnType) {
return ((ClangReturnType) node).getDataType();
}
if (node instanceof ClangTypeToken) {
return ((ClangTypeToken) node).getDataType();
}
if (node instanceof ClangVariableToken) {
Varnode vn = ((ClangVariableToken) node).getVarnode();
if (vn != null) {
HighVariable high = vn.getHigh();
if (high != null) {
return high.getDataType();
}
}
}
return null;
}
} }

View file

@ -73,7 +73,7 @@ public class FunctionSignatureDecompilerHover extends AbstractConfigurableHover
public JComponent getHoverComponent(Program program, ProgramLocation programLocation, public JComponent getHoverComponent(Program program, ProgramLocation programLocation,
FieldLocation fieldLocation, Field field) { FieldLocation fieldLocation, Field field) {
if (!enabled || programLocation == null) { if (!enabled) {
return null; return null;
} }

View file

@ -64,10 +64,14 @@ public class ReferenceDecompilerHover extends AbstractReferenceHover
} }
@Override @Override
public JComponent getHoverComponent(Program program, ProgramLocation programLocation, public JComponent getHoverComponent(Program program, ProgramLocation location,
FieldLocation fieldLocation, Field field) { FieldLocation fieldLocation, Field field) {
Address refAddr = programLocation.getRefAddress(); if (!enabled || location == null) {
return null;
}
Address refAddr = location.getRefAddress();
if (refAddr == null) { if (refAddr == null) {
return null; return null;
} }
@ -75,9 +79,8 @@ public class ReferenceDecompilerHover extends AbstractReferenceHover
if (other != null) { if (other != null) {
return null; return null;
} }
return super.getHoverComponent(program, programLocation, fieldLocation, field); return super.getHoverComponent(program, location, fieldLocation, field);
} }
} }

View file

@ -67,7 +67,7 @@ public class ScalarValueDecompilerHover extends AbstractScalarOperandHover
public JComponent getHoverComponent(Program program, ProgramLocation programLocation, public JComponent getHoverComponent(Program program, ProgramLocation programLocation,
FieldLocation fieldLocation, Field field) { FieldLocation fieldLocation, Field field) {
if (!enabled || programLocation == null) { if (!enabled) {
return null; return null;
} }