GT-2629 - Decompiler - fixed hovers for return type and variables

This commit is contained in:
dragonmacher 2019-06-12 17:34:39 -04:00
parent dbbc2d91e5
commit 30063c68d0
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.util.ProgramLocation;
import ghidra.util.Msg;
import ghidra.util.SystemUtilities;
import ghidra.util.Swing;
public abstract class AbstractHoverProvider implements HoverProvider {
@ -40,12 +40,7 @@ public abstract class AbstractHoverProvider implements HoverProvider {
protected Program program;
protected Field lastField;
private static final Comparator<HoverService> HOVER_PRIORITY_COMPARATOR =
new Comparator<HoverService>() {
@Override
public int compare(HoverService service1, HoverService service2) {
return service2.getPriority() - service1.getPriority();// Highest priority is first
}
};
(service1, service2) -> service2.getPriority() - service1.getPriority();
protected HoverService activeHoverService;
protected PopupWindow popupWindow;
@ -121,12 +116,9 @@ public abstract class AbstractHoverProvider implements HoverProvider {
public void dispose() {
// we can be disposed from outside the swing thread
SystemUtilities.runSwingLater(new Runnable() {
@Override
public void run() {
closeHover();
hoverServices.clear();
}
Swing.runLater(() -> {
closeHover();
hoverServices.clear();
});
program = null;
@ -148,25 +140,15 @@ public abstract class AbstractHoverProvider implements HoverProvider {
}
ProgramLocation loc = getHoverLocation(fieldLocation, field, fieldBounds, event);
if (loc == null) {
return;
}
JComponent comp = null;
for (HoverService hoverService : hoverServices) {
comp = hoverService.getHoverComponent(program, loc, fieldLocation, field);
JComponent comp = hoverService.getHoverComponent(program, loc, fieldLocation, field);
if (comp != null) {
closeHover();
activeHoverService = hoverService;
break;
showPopup(comp, field, event, fieldBounds);
return;
}
}
if (comp != null) {
showPopup(comp, field, event, fieldBounds);
}
}
protected void showPopup(JComponent comp, Field field, MouseEvent event,

View file

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

View file

@ -20,8 +20,7 @@ import javax.swing.JComponent;
import docking.widgets.fieldpanel.field.Field;
import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.GhidraOptions;
import ghidra.app.decompiler.ClangToken;
import ghidra.app.decompiler.ClangTypeToken;
import ghidra.app.decompiler.*;
import ghidra.app.decompiler.component.ClangTextField;
import ghidra.app.plugin.core.hover.AbstractDataTypeHover;
import ghidra.app.util.ToolTipUtils;
@ -29,6 +28,8 @@ import ghidra.framework.options.Options;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.data.DataType;
import ghidra.program.model.listing.Program;
import ghidra.program.model.pcode.HighVariable;
import ghidra.program.model.pcode.Varnode;
import ghidra.program.util.ProgramLocation;
public class DataTypeDecompilerHover extends AbstractDataTypeHover
@ -62,37 +63,53 @@ public class DataTypeDecompilerHover extends AbstractDataTypeHover
public JComponent getHoverComponent(Program program, ProgramLocation programLocation,
FieldLocation fieldLocation, Field field) {
if (!enabled || programLocation == null) {
if (!enabled) {
return null;
}
DataType dt = null;
if (!(field instanceof ClangTextField)) {
return null;
}
boolean hasInvalidStorage = false;
ClangToken token = ((ClangTextField) field).getToken(fieldLocation);
if (field instanceof ClangTextField) {
ClangToken token = ((ClangTextField) field).getToken(fieldLocation);
DataType dt = getDataType(token);
if (dt == null) {
dt = getDataType(token.Parent());
}
if (token instanceof ClangTypeToken) {
dt = ((ClangTypeToken) token).getDataType();
}
if (dt != null) {
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);
}
if (dt != null) {
String toolTipText = ToolTipUtils.getToolTipText(dt);
return createTooltipComponent(toolTipText);
}
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,
FieldLocation fieldLocation, Field field) {
if (!enabled || programLocation == null) {
if (!enabled) {
return null;
}

View file

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