mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
Merge remote-tracking branch 'origin/GT-2629-dragonmacher-decompiler-type-hovers'
This commit is contained in:
commit
96e860856d
6 changed files with 86 additions and 90 deletions
|
@ -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,
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue