mirror of
https://github.com/NationalSecurityAgency/ghidra
synced 2024-08-27 21:10:26 +00:00
Merge remote-tracking branch 'origin/GT-2629-dragonmacher-decompiler-type-hovers'
This commit is contained in:
commit
96e860856d
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue