mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-06-01 01:00:46 +08:00
Updated broken color usage for function references and parameter references
This commit is contained in:
@@ -40,7 +40,7 @@ color.fg.listing.comment.pre = color.palette.indigo
|
||||
color.fg.listing.comment.offcut = color.fg.error
|
||||
color.fg.listing.ref.bad = color.fg.error
|
||||
color.fg.listing.ext.entrypoint = color.palette.magenta
|
||||
color.fg.listing.ext.ref.resolved = color.palette.darkorange
|
||||
color.fg.listing.ext.ref.resolved = color.palette.teal
|
||||
color.fg.listing.ext.ref.unresolved = color.fg.listing.ref.bad
|
||||
color.fg.listing.fieldname = color.fg
|
||||
|
||||
|
||||
@@ -382,10 +382,10 @@ public class SymbolInspector implements OptionsChangeListener {
|
||||
else if (isVariableSymbol(s)) {
|
||||
if (s.getSymbolType() == SymbolType.PARAMETER) {
|
||||
Function function = (Function) s.getParentNamespace();
|
||||
return function.hasCustomVariableStorage() ? OptionsGui.PARAMETER_CUSTOM
|
||||
: OptionsGui.PARAMETER_DYNAMIC;
|
||||
return function.hasCustomVariableStorage() ? OptionsGui.FUN_PARAM_CUSTOM
|
||||
: OptionsGui.FUN_PARAM_DYNAMIC;
|
||||
}
|
||||
return OptionsGui.VARIABLE;
|
||||
return OptionsGui.FUN_VARIABLE;
|
||||
}
|
||||
else if (isPrimarySymbol(s)) {
|
||||
return OptionsGui.LABELS_PRIMARY;
|
||||
|
||||
+11
-6
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -81,9 +81,9 @@ public abstract class AbstractVariableFieldFactory extends FieldFactory {
|
||||
|
||||
parameterFieldOptions = new ParameterFieldOptions[2];
|
||||
parameterFieldOptions[CUSTOM_PARAM_INDEX] =
|
||||
new ParameterFieldOptions(OptionsGui.PARAMETER_CUSTOM);
|
||||
new ParameterFieldOptions(OptionsGui.FUN_PARAM_CUSTOM);
|
||||
parameterFieldOptions[DYNAMIC_PARAM_INDEX] =
|
||||
new ParameterFieldOptions(OptionsGui.PARAMETER_DYNAMIC);
|
||||
new ParameterFieldOptions(OptionsGui.FUN_PARAM_DYNAMIC);
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
parameterFieldOptions[i].style =
|
||||
@@ -122,11 +122,16 @@ public abstract class AbstractVariableFieldFactory extends FieldFactory {
|
||||
}
|
||||
|
||||
protected Color getColor(Variable var) {
|
||||
if (var instanceof Parameter) {
|
||||
if (var instanceof Parameter param) {
|
||||
|
||||
if (param.isAutoParameter()) {
|
||||
return FunctionColors.PARAM_AUTO;
|
||||
}
|
||||
|
||||
return var.getFunction().hasCustomVariableStorage() ? FunctionColors.PARAM_CUSTOM
|
||||
: FunctionColors.PARAM_DYNAMIC;
|
||||
}
|
||||
return FunctionColors.PARAM;
|
||||
return FunctionColors.VARIABLE;
|
||||
}
|
||||
|
||||
protected FontMetrics getMetrics(Variable var) {
|
||||
|
||||
+418
-191
File diff suppressed because it is too large
Load Diff
+3
-12
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -45,7 +45,7 @@ public class VariableNameFieldFactory extends AbstractVariableFieldFactory {
|
||||
/**
|
||||
* Constructor
|
||||
* @param model the model that the field belongs to.
|
||||
* @param hsProvider the HightLightStringProvider.
|
||||
* @param hlProvider the HightLightStringProvider.
|
||||
* @param displayOptions the Options for display properties.
|
||||
* @param fieldOptions the Options for field specific properties.
|
||||
*/
|
||||
@@ -72,9 +72,6 @@ public class VariableNameFieldFactory extends AbstractVariableFieldFactory {
|
||||
width, hlProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.app.util.viewer.field.FieldFactory#getProgramLocation(int, int, ghidra.app.util.viewer.field.ListingField)
|
||||
*/
|
||||
@Override
|
||||
public ProgramLocation getProgramLocation(int row, int col, ListingField bf) {
|
||||
ProxyObj<?> proxy = bf.getProxy();
|
||||
@@ -88,9 +85,6 @@ public class VariableNameFieldFactory extends AbstractVariableFieldFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.app.util.viewer.field.FieldFactory#getFieldLocation(ghidra.app.util.viewer.field.ListingField, BigInteger, int, ghidra.program.util.ProgramLocation)
|
||||
*/
|
||||
@Override
|
||||
public FieldLocation getFieldLocation(ListingField bf, BigInteger index, int fieldNum,
|
||||
ProgramLocation loc) {
|
||||
@@ -111,9 +105,6 @@ public class VariableNameFieldFactory extends AbstractVariableFieldFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.app.util.viewer.field.FieldFactory#acceptsType(int, java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public boolean acceptsType(int category, Class<?> proxyObjectClass) {
|
||||
if (!Variable.class.isAssignableFrom(proxyObjectClass)) {
|
||||
|
||||
+138
-34
@@ -40,6 +40,7 @@ import generic.theme.GThemeDefaults.Colors.Palette;
|
||||
import ghidra.GhidraOptions;
|
||||
import ghidra.app.util.viewer.field.ListingColors;
|
||||
import ghidra.app.util.viewer.field.ListingColors.*;
|
||||
import ghidra.util.ColorUtils;
|
||||
|
||||
/**
|
||||
* Class for displaying and manipulating field colors and fonts.
|
||||
@@ -65,6 +66,9 @@ public class OptionsGui extends JPanel {
|
||||
public static final ScreenElement FUN_CALL_FIXUP = new ScreenElement("Function Call-Fixup", FunctionColors.CALL_FIXUP);
|
||||
public static final ScreenElement FUN_NAME = new ScreenElement("Function Name", FunctionColors.NAME);
|
||||
public static final ScreenElement FUN_PARAMS = new ScreenElement("Function Parameters", FunctionColors.PARAM);
|
||||
public static final ScreenElement FUN_PARAM_CUSTOM = new ScreenElement("Function Parameter, Custom Storage", FunctionColors.PARAM_CUSTOM);
|
||||
public static final ScreenElement FUN_PARAM_DYNAMIC = new ScreenElement("Function Parameter, Dynamic Storage", FunctionColors.PARAM_DYNAMIC);
|
||||
public static final ScreenElement FUN_VARIABLE = new ScreenElement("Function Variable", FunctionColors.VARIABLE);
|
||||
public static final ScreenElement FUN_TAG = new ScreenElement("Function Tag", FunctionColors.TAG);
|
||||
public static final ScreenElement FUN_AUTO_PARAMS = new ScreenElement("Function Auto-Parameters", FunctionColors.PARAM_AUTO);
|
||||
public static final ScreenElement FUN_RET_TYPE = new ScreenElement("Function Return Type", FunctionColors.RETURN_TYPE);
|
||||
@@ -73,7 +77,7 @@ public class OptionsGui extends JPanel {
|
||||
public static final ScreenElement LABELS_LOCAL = new ScreenElement("Labels, Local", LabelColors.LOCAL);
|
||||
public static final ScreenElement MNEMONIC = new ScreenElement("Mnemonic", MnemonicColors.NORMAL);
|
||||
public static final ScreenElement MNEMONIC_OVERRIDE = new ScreenElement("Mnemonic, Override", MnemonicColors.OVERRIDE);
|
||||
public static final ScreenElement MNEMONIC_UNIMPL = new ScreenElement("Unimplemented Mnemonic", MnemonicColors.UNIMPLEMENTED);
|
||||
public static final ScreenElement MNEMONIC_UNIMPL = new ScreenElement("Mnemonic, Unimplemented ", MnemonicColors.UNIMPLEMENTED);
|
||||
public static final ScreenElement FLOW_ARROW_ACTIVE = new ScreenElement("Flow Arrow, Active", FlowArrowColors.ACTIVE);
|
||||
public static final ScreenElement FLOW_ARROW_NON_ACTIVE = new ScreenElement("Flow Arrow, Not Active", FlowArrowColors.INACTIVE);
|
||||
public static final ScreenElement FLOW_ARROW_SELECTED = new ScreenElement("Flow Arrow, Selected", FlowArrowColors.SELECTED);
|
||||
@@ -83,9 +87,7 @@ public class OptionsGui extends JPanel {
|
||||
public static final ScreenElement COMMENT_POST = new ScreenElement("Comment, Post", "Post-Comment", CommentColors.POST);
|
||||
public static final ScreenElement COMMENT_PRE = new ScreenElement("Comment, Pre", "Pre-Comment", CommentColors.PRE);
|
||||
public static final ScreenElement SEPARATOR = new ScreenElement("Separator", ListingColors.SEPARATOR);
|
||||
public static final ScreenElement VARIABLE = new ScreenElement("Variable", FunctionColors.VARIABLE);
|
||||
public static final ScreenElement PARAMETER_CUSTOM = new ScreenElement("Parameter, Custom Storage", FunctionColors.PARAM_CUSTOM);
|
||||
public static final ScreenElement PARAMETER_DYNAMIC = new ScreenElement("Parameter, Dynamic Storage", FunctionColors.PARAM_DYNAMIC);
|
||||
public static final ScreenElement SEPARATOR_LINE = new ScreenElement("Separator Line", Colors.BACKGROUND);
|
||||
public static final ScreenElement XREF = new ScreenElement("XRef", XrefColors.DEFAULT);
|
||||
public static final ScreenElement XREF_OFFCUT = new ScreenElement("XRef, Offcut", XrefColors.OFFCUT);
|
||||
public static final ScreenElement XREF_READ = new ScreenElement("XRef Read", XrefColors.READ);
|
||||
@@ -98,19 +100,22 @@ public class OptionsGui extends JPanel {
|
||||
public static final ScreenElement PCODE_RAW_VARNODE = new ScreenElement("P-code Raw Varnode", PcodeColors.VARNODE);
|
||||
public static final ScreenElement PCODE_USEROP = new ScreenElement("P-code Userop", PcodeColors.USEROP);
|
||||
|
||||
static ScreenElement[] elements = {
|
||||
ADDRESS,
|
||||
BACKGROUND, BAD_REF_ADDR, BYTES,
|
||||
COMMENT_AUTO, COMMENT_EOL, COMMENT_PLATE, COMMENT_POST, COMMENT_PRE, COMMENT_REPEATABLE,
|
||||
COMMENT_REF_REPEAT, CONSTANT,
|
||||
ENTRY_POINT, EXT_REF_RESOLVED, EXT_REF_UNRESOLVED,
|
||||
FIELD_NAME, FLOW_ARROW_ACTIVE, FLOW_ARROW_NON_ACTIVE, FLOW_ARROW_SELECTED,
|
||||
FUN_NAME, FUN_PARAMS, FUN_AUTO_PARAMS, FUN_PARAM_DYNAMIC, FUN_PARAM_CUSTOM, FUN_VARIABLE,
|
||||
FUN_RET_TYPE, FUN_CALL_FIXUP, FUN_TAG,
|
||||
LABELS_LOCAL, LABELS_NON_PRIMARY, LABELS_PRIMARY, LABELS_UNREFD,
|
||||
MNEMONIC, MNEMONIC_OVERRIDE, MNEMONIC_UNIMPL,
|
||||
PCODE_LINE_LABEL, PCODE_ADDR_SPACE, PCODE_RAW_VARNODE, PCODE_USEROP,
|
||||
REGISTERS, SEPARATOR, UNDERLINE,
|
||||
XREF, XREF_OFFCUT, XREF_READ, XREF_WRITE, XREF_OTHER };
|
||||
//@formatter:on
|
||||
|
||||
static ScreenElement[] elements =
|
||||
{ ADDRESS, BACKGROUND, BAD_REF_ADDR, BYTES, COMMENT_AUTO, COMMENT_EOL, COMMENT_PLATE,
|
||||
COMMENT_POST, COMMENT_PRE, COMMENT_REPEATABLE, COMMENT_REF_REPEAT, CONSTANT,
|
||||
ENTRY_POINT, EXT_REF_RESOLVED, EXT_REF_UNRESOLVED, FIELD_NAME, FLOW_ARROW_ACTIVE,
|
||||
FLOW_ARROW_NON_ACTIVE, FLOW_ARROW_SELECTED, FUN_CALL_FIXUP, FUN_NAME, FUN_PARAMS,
|
||||
FUN_AUTO_PARAMS, FUN_RET_TYPE, FUN_TAG, LABELS_LOCAL, LABELS_NON_PRIMARY,
|
||||
LABELS_PRIMARY, LABELS_UNREFD, MNEMONIC, MNEMONIC_OVERRIDE, PARAMETER_CUSTOM,
|
||||
PARAMETER_DYNAMIC, PCODE_LINE_LABEL, PCODE_ADDR_SPACE, PCODE_RAW_VARNODE, PCODE_USEROP,
|
||||
REGISTERS, SEPARATOR, UNDERLINE, MNEMONIC_UNIMPL, VARIABLE, XREF, XREF_OFFCUT,
|
||||
XREF_READ, XREF_WRITE, XREF_OTHER };
|
||||
|
||||
private Map<Integer, FontMetrics> metricsMap = new HashMap<>();
|
||||
|
||||
private JList<ScreenElement> namesList;
|
||||
@@ -167,28 +172,31 @@ public class OptionsGui extends JPanel {
|
||||
}
|
||||
else {
|
||||
setSelectedIndex(index);
|
||||
setSelectedFieldElement(index);
|
||||
}
|
||||
});
|
||||
|
||||
setSelectedIndex(0);
|
||||
colorChooser.getSelectionModel().addChangeListener(e -> {
|
||||
Color c = colorChooser.getColor();
|
||||
Color oldColor = elements[selectedIndex].getColor();
|
||||
elements[selectedIndex].setColor(c);
|
||||
colorPanel.setBackground(c);
|
||||
genLayouts();
|
||||
fieldPanel.setBackgroundColor(BACKGROUND.getColor());
|
||||
enableApply();
|
||||
|
||||
if (!ColorUtils.hasSameRgb(oldColor, c)) {
|
||||
enableApply();
|
||||
}
|
||||
});
|
||||
|
||||
ActionListener styleListener = e -> {
|
||||
updateStyle();
|
||||
genLayouts();
|
||||
fieldPanel.setBackgroundColor(BACKGROUND.getColor());
|
||||
enableApply();
|
||||
};
|
||||
ActionListener familyListener = e -> {
|
||||
updateFonts();
|
||||
genLayouts();
|
||||
fieldPanel.setBackgroundColor(BACKGROUND.getColor());
|
||||
enableApply();
|
||||
};
|
||||
|
||||
@@ -217,7 +225,7 @@ public class OptionsGui extends JPanel {
|
||||
}
|
||||
|
||||
/**
|
||||
* callback for when the selected display field changes.
|
||||
* Callback for when the selected display field changes.
|
||||
*
|
||||
* @param index the index in the JList of the selected field.
|
||||
*/
|
||||
@@ -243,6 +251,26 @@ public class OptionsGui extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
private void setSelectedFieldElement(int index) {
|
||||
ListModel<ScreenElement> model = namesList.getModel();
|
||||
ScreenElement screenElement = model.getElementAt(index);
|
||||
|
||||
SimpleLayoutModel layoutModel = (SimpleLayoutModel) fieldPanel.getLayoutModel();
|
||||
FieldSelection selection = layoutModel.getFieldSelection(screenElement);
|
||||
if (selection == null) {
|
||||
fieldPanel.clearSelection();
|
||||
return;
|
||||
}
|
||||
|
||||
FieldRange range = selection.getFieldRange(0);
|
||||
FieldLocation loc = range.getStart();
|
||||
|
||||
fieldPanel.setCursorPosition(loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol());
|
||||
fieldPanel.setSelection(selection);
|
||||
fieldPanel.scrollTo(loc);
|
||||
fieldPanel.center(loc);
|
||||
}
|
||||
|
||||
public void setBaseFont(Font font) {
|
||||
baseFont = font;
|
||||
baseMetrics = getFontMetrics(font);
|
||||
@@ -515,6 +543,8 @@ public class OptionsGui extends JPanel {
|
||||
lb.add(".........", SEPARATOR);
|
||||
list.add(lb.getLayout());
|
||||
|
||||
list.add(blankLine());
|
||||
|
||||
lb = new LayoutBuilder(1);
|
||||
lb.add(" ", null);
|
||||
lb.add("sprintf", LABELS_NON_PRIMARY);
|
||||
@@ -557,6 +587,8 @@ public class OptionsGui extends JPanel {
|
||||
lb.add(".........", SEPARATOR);
|
||||
list.add(lb.getLayout());
|
||||
|
||||
list.add(blankLine());
|
||||
|
||||
lb = new LayoutBuilder(2);
|
||||
lb.add(" ", null);
|
||||
lb.add("LAB2000", LABELS_PRIMARY);
|
||||
@@ -610,6 +642,9 @@ public class OptionsGui extends JPanel {
|
||||
lb.add("33", CONSTANT);
|
||||
list.add(lb.getLayout());
|
||||
|
||||
list.add(blankLine());
|
||||
list.add(blankLine());
|
||||
|
||||
lb = new LayoutBuilder(1);
|
||||
lb.add(" ", null);
|
||||
lb.add("// This is a function comment", COMMENT_EOL);
|
||||
@@ -639,30 +674,30 @@ public class OptionsGui extends JPanel {
|
||||
|
||||
lb = new LayoutBuilder(3);
|
||||
lb.add(" ", null);
|
||||
lb.add("12 ", PARAMETER_DYNAMIC);
|
||||
lb.add("DWord ", PARAMETER_DYNAMIC);
|
||||
lb.add("param_12 ", PARAMETER_DYNAMIC);
|
||||
lb.add("12 ", FUN_PARAM_DYNAMIC);
|
||||
lb.add("DWord ", FUN_PARAM_DYNAMIC);
|
||||
lb.add("param_12 ", FUN_PARAM_DYNAMIC);
|
||||
list.add(lb.getLayout());
|
||||
|
||||
lb = new LayoutBuilder(3);
|
||||
lb.add(" ", null);
|
||||
lb.add("8 ", PARAMETER_CUSTOM);
|
||||
lb.add("DWord ", PARAMETER_CUSTOM);
|
||||
lb.add("param_8 ", PARAMETER_CUSTOM);
|
||||
lb.add("8 ", FUN_PARAM_CUSTOM);
|
||||
lb.add("DWord ", FUN_PARAM_CUSTOM);
|
||||
lb.add("param_8 ", FUN_PARAM_CUSTOM);
|
||||
list.add(lb.getLayout());
|
||||
|
||||
lb = new LayoutBuilder(3);
|
||||
lb.add(" ", null);
|
||||
lb.add("4 ", PARAMETER_CUSTOM);
|
||||
lb.add("Word ", PARAMETER_CUSTOM);
|
||||
lb.add("param_4 ", PARAMETER_CUSTOM);
|
||||
lb.add("4 ", FUN_PARAM_CUSTOM);
|
||||
lb.add("Word ", FUN_PARAM_CUSTOM);
|
||||
lb.add("param_4 ", FUN_PARAM_CUSTOM);
|
||||
list.add(lb.getLayout());
|
||||
|
||||
lb = new LayoutBuilder(3);
|
||||
lb.add(" ", null);
|
||||
lb.add("-4 ", VARIABLE);
|
||||
lb.add("Float ", VARIABLE);
|
||||
lb.add("local_4 ", VARIABLE);
|
||||
lb.add("-4 ", FUN_VARIABLE);
|
||||
lb.add("Float ", FUN_VARIABLE);
|
||||
lb.add("local_4 ", FUN_VARIABLE);
|
||||
list.add(lb.getLayout());
|
||||
|
||||
lb = new LayoutBuilder(2);
|
||||
@@ -689,8 +724,14 @@ public class OptionsGui extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
private Layout blankLine() {
|
||||
LayoutBuilder lb = new LayoutBuilder(1);
|
||||
lb.add(" ", SEPARATOR_LINE);
|
||||
return lb.getLayout();
|
||||
}
|
||||
|
||||
/**
|
||||
* updates the style of the field at the selected index.
|
||||
* Updates the style of the field at the selected index.
|
||||
*/
|
||||
private void updateStyle() {
|
||||
if (customCheckbox.isSelected()) {
|
||||
@@ -839,12 +880,75 @@ public class OptionsGui extends JPanel {
|
||||
return BigInteger.valueOf(layouts.length);
|
||||
}
|
||||
|
||||
FieldSelection getFieldSelection(ScreenElement element) {
|
||||
|
||||
List<FieldRange> ranges = getAllRanges(element);
|
||||
if (ranges.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
FieldSelection selection = new FieldSelection();
|
||||
for (FieldRange r : ranges) {
|
||||
selection.addRange(r);
|
||||
}
|
||||
|
||||
return selection;
|
||||
}
|
||||
|
||||
// finds all places this element is used; consecutive fields will be combined
|
||||
List<FieldRange> getAllRanges(ScreenElement element) {
|
||||
|
||||
List<FieldRange> ranges = new ArrayList<>();
|
||||
for (int index = 0; index < layouts.length; index++) {
|
||||
SingleRowLayout rowLayout = (SingleRowLayout) layouts[index];
|
||||
getRangesForRow(rowLayout, element, index, ranges);
|
||||
}
|
||||
return ranges;
|
||||
}
|
||||
|
||||
private void getRangesForRow(SingleRowLayout layout, ScreenElement element, int index,
|
||||
List<FieldRange> ranges) {
|
||||
|
||||
FieldRange lastRange = null;
|
||||
int n = layout.getNumFields();
|
||||
for (int i = 0; i < n; i++) {
|
||||
ScreenElementTextField field = (ScreenElementTextField) layout.getField(i);
|
||||
ScreenElement fieldElement = field.getScreenElement();
|
||||
String text = field.getText();
|
||||
if (element != fieldElement) {
|
||||
lastRange = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
int start = 0;
|
||||
if (lastRange == null) {
|
||||
start = getNonWhitespaceStart(text);
|
||||
}
|
||||
|
||||
lastRange = new FieldRange(
|
||||
new FieldLocation(index, i, 0, start),
|
||||
new FieldLocation(index, i, 0, start + text.trim().length()));
|
||||
ranges.add(lastRange);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int getNonWhitespaceStart(String text) {
|
||||
int start = 0;
|
||||
for (int j = 0; j < text.length(); j++) {
|
||||
char c = text.charAt(j);
|
||||
if (!Character.isWhitespace(c)) {
|
||||
break;
|
||||
}
|
||||
start++;
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to create the layouts for the preview panel.
|
||||
*/
|
||||
class LayoutBuilder {
|
||||
private class LayoutBuilder {
|
||||
private ClippingTextField[] fields;
|
||||
int startPos;
|
||||
int fieldNum;
|
||||
|
||||
@@ -1251,8 +1251,8 @@ public class CodeUnitFormat {
|
||||
}
|
||||
|
||||
result = addBlockName(program, toAddress, result, refBlock, withBlockName);
|
||||
LabelType labelType = (toSymbol != null && toSymbol.isExternal()) ? LabelString.EXTERNAL
|
||||
: LabelString.CODE_LABEL;
|
||||
LabelType labelType = (toSymbol != null && toSymbol.isExternal()) ? LabelType.EXTERNAL
|
||||
: LabelType.CODE_LABEL;
|
||||
LabelString label = new LabelString(result, labelType);
|
||||
|
||||
// Apply extended pointer markup if needed
|
||||
@@ -1291,8 +1291,8 @@ public class CodeUnitFormat {
|
||||
Symbol symbol = program.getSymbolTable().getSymbol(referencesFrom[0]);
|
||||
if (symbol != null && !symbol.isDynamic()) {
|
||||
String result = getSymbolLabelString(program, symbol, ref.getFromAddress());
|
||||
return new LabelString(result,
|
||||
symbol.isExternal() ? LabelString.EXTERNAL : LabelString.CODE_LABEL);
|
||||
return new LabelString(result, symbol,
|
||||
symbol.isExternal() ? LabelType.EXTERNAL : LabelType.CODE_LABEL);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ color.fg.decompiler.type = color.palette.blue
|
||||
color.fg.decompiler.parameter = color.palette.purple
|
||||
color.fg.decompiler.global = color.palette.darkcyan
|
||||
color.fg.decompiler.special = color.palette.crimson
|
||||
color.fg.decompiler.external.function = color.palette.fuchsia
|
||||
|
||||
color.bg.decompiler.current.variable = color.palette.highlight.transparent.yellow
|
||||
|
||||
|
||||
+29
-3
@@ -26,6 +26,7 @@ import docking.widgets.fieldpanel.field.*;
|
||||
import docking.widgets.fieldpanel.listener.IndexMapper;
|
||||
import docking.widgets.fieldpanel.listener.LayoutModelListener;
|
||||
import docking.widgets.fieldpanel.support.*;
|
||||
import generic.theme.GColor;
|
||||
import ghidra.app.decompiler.*;
|
||||
import ghidra.app.util.SymbolInspector;
|
||||
import ghidra.app.util.viewer.field.CommentUtils;
|
||||
@@ -41,6 +42,9 @@ import ghidra.util.UndefinedFunction;
|
||||
*/
|
||||
public class ClangLayoutController implements LayoutModel, LayoutModelListener {
|
||||
|
||||
private static GColor COLOR_EXTERNAL_FUNCTION =
|
||||
new GColor("color.fg.decompiler.external.function");
|
||||
|
||||
private int maxWidth;
|
||||
private int indentWidth;
|
||||
private SymbolInspector symbolInspector;
|
||||
@@ -202,22 +206,44 @@ public class ClangLayoutController implements LayoutModel, LayoutModelListener {
|
||||
|
||||
private Color getTokenColor(ClangToken token) {
|
||||
|
||||
Color tokenColor = syntaxColor[token.getSyntaxType()];
|
||||
if (token instanceof ClangFuncNameToken clangFunctionToken) {
|
||||
Program program = decompilerPanel.getProgram();
|
||||
Function function = DecompilerUtils.getFunction(program, clangFunctionToken);
|
||||
if (isValidFunction(function)) {
|
||||
Symbol symbol = function.getSymbol();
|
||||
tokenColor = symbolInspector.getColor(symbol);
|
||||
return getFunctionColor(function);
|
||||
}
|
||||
}
|
||||
|
||||
Color tokenColor = syntaxColor[token.getSyntaxType()];
|
||||
if (tokenColor != null) {
|
||||
return tokenColor;
|
||||
}
|
||||
return syntaxColor[ClangToken.ERROR_COLOR];
|
||||
}
|
||||
|
||||
private Color getFunctionColor(Function function) {
|
||||
Symbol symbol = function.getSymbol();
|
||||
|
||||
// For now we have decided that any external function, linked or not, will be one color, as
|
||||
// this makes it easy for the user to identify external function calls. Other functions will
|
||||
// be colored according to the SymbolInspector. If we use the SymbolInspector for all
|
||||
// colors, then some of the color values will be very close to some of the colors used by
|
||||
// the Decompiler. For example, non-linked external functions default to red and linked
|
||||
// external functions default to green.
|
||||
if (function.isExternal()) {
|
||||
return COLOR_EXTERNAL_FUNCTION;
|
||||
}
|
||||
|
||||
if (function.isThunk()) {
|
||||
Function thunkedFunction = function.getThunkedFunction(true);
|
||||
if (thunkedFunction.isExternal()) {
|
||||
return COLOR_EXTERNAL_FUNCTION;
|
||||
}
|
||||
}
|
||||
|
||||
return symbolInspector.getColor(symbol);
|
||||
}
|
||||
|
||||
private boolean isValidFunction(Function f) {
|
||||
return f != null && !(f instanceof UndefinedFunction);
|
||||
}
|
||||
|
||||
+3
-3
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -86,7 +86,7 @@ public class FieldLocation implements Comparable<FieldLocation> {
|
||||
* @param index the index of the layout containing the location
|
||||
* @param fieldNum the index of the field in the layout containing the location
|
||||
* @param row the text row in the field containing the location.
|
||||
* @param col the character position the row containing the location.
|
||||
* @param col the character position in the row containing the location.
|
||||
*/
|
||||
public FieldLocation(int index, int fieldNum, int row, int col) {
|
||||
this(BigInteger.valueOf(index), fieldNum, row, col);
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -18,6 +18,8 @@ package ghidra.util;
|
||||
import java.awt.Color;
|
||||
import java.util.Comparator;
|
||||
|
||||
import generic.theme.GColor;
|
||||
|
||||
public class ColorUtils {
|
||||
|
||||
private static final int MAX_COLOR_VALUE = 255;
|
||||
@@ -348,6 +350,26 @@ public class ColorUtils {
|
||||
return new Color(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if both colors are not null and have the same RGB value. This is useful to
|
||||
* compare colors that may have different classes, such as {@link Color} and {@link GColor}.
|
||||
*
|
||||
* @param c1 the first color
|
||||
* @param c2 the second color
|
||||
* @return true if the colors have the same RGB value
|
||||
*/
|
||||
public static boolean hasSameRgb(Color c1, Color c2) {
|
||||
int rgb1 = 0;
|
||||
int rgb2 = 0;
|
||||
if (c1 != null) {
|
||||
rgb1 = c1.getRGB();
|
||||
}
|
||||
if (c2 != null) {
|
||||
rgb2 = c2.getRGB();
|
||||
}
|
||||
return rgb1 == rgb2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blender of colors
|
||||
*/
|
||||
|
||||
+21
-10
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -15,27 +15,38 @@
|
||||
*/
|
||||
package ghidra.program.model.listing;
|
||||
|
||||
public class LabelString {
|
||||
|
||||
public enum LabelType { CODE_LABEL, VARIABLE, EXTERNAL }
|
||||
import ghidra.program.model.symbol.Symbol;
|
||||
|
||||
public class LabelString {
|
||||
|
||||
public enum LabelType {
|
||||
CODE_LABEL, VARIABLE, EXTERNAL
|
||||
}
|
||||
|
||||
public static final LabelType CODE_LABEL = LabelType.CODE_LABEL;
|
||||
public static final LabelType VARIABLE = LabelType.VARIABLE;
|
||||
public static final LabelType EXTERNAL = LabelType.EXTERNAL;
|
||||
|
||||
private final String label;
|
||||
private final LabelType type;
|
||||
private Symbol symbol;
|
||||
|
||||
public LabelString(String label, LabelType type) {
|
||||
this.label = label;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public LabelString(String label, Symbol symbol, LabelType type) {
|
||||
this.label = label;
|
||||
this.symbol = symbol;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Symbol getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return label;
|
||||
}
|
||||
|
||||
|
||||
public LabelType getLabelType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
+13
-21
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -15,12 +15,12 @@
|
||||
*/
|
||||
package ghidra.program.model.listing;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.listing.LabelString.LabelType;
|
||||
import ghidra.program.model.scalar.Scalar;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.util.SystemUtilities;
|
||||
@@ -43,7 +43,7 @@ public class VariableOffset {
|
||||
|
||||
/**
|
||||
* Constructor for an implied variable reference.
|
||||
* @param variable function variable
|
||||
* @param var function variable
|
||||
* @param offset offset into variable
|
||||
* @param indirect if true and variable data-type is a pointer, the offset
|
||||
* is relative to underlying data-type of the pointer-type. This should generally be
|
||||
@@ -51,8 +51,8 @@ public class VariableOffset {
|
||||
* whereas it would be false for stack-references.
|
||||
* @param dataAccess true if content of variable is being read and/or written
|
||||
*/
|
||||
public VariableOffset(Variable variable, long offset, boolean indirect, boolean dataAccess) {
|
||||
this.variable = variable;
|
||||
public VariableOffset(Variable var, long offset, boolean indirect, boolean dataAccess) {
|
||||
this.variable = Objects.requireNonNull(var, "Variable reference not bound to a variable");
|
||||
this.offset = offset;
|
||||
this.indirect = indirect;
|
||||
this.dataAccess = dataAccess;
|
||||
@@ -65,20 +65,14 @@ public class VariableOffset {
|
||||
*/
|
||||
public VariableOffset(Reference ref, Variable var) {
|
||||
|
||||
indirect = false;
|
||||
variable = var;
|
||||
if (variable == null) {
|
||||
throw new IllegalArgumentException("Variable reference not bound to a variable");
|
||||
}
|
||||
|
||||
this.indirect = false;
|
||||
this.variable = Objects.requireNonNull(var, "Variable reference not bound to a variable");
|
||||
RefType rt = ref.getReferenceType();
|
||||
dataAccess = rt.isRead() || rt.isWrite();
|
||||
this.dataAccess = rt.isRead() || rt.isWrite();
|
||||
|
||||
if (ref instanceof StackReference && variable.isStackVariable()) {
|
||||
offset = variable.getStackOffset();
|
||||
offset = ((StackReference) ref).getStackOffset() - variable.getStackOffset();
|
||||
this.offset = ((StackReference) ref).getStackOffset() - variable.getStackOffset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,6 +88,7 @@ public class VariableOffset {
|
||||
|
||||
/**
|
||||
* Sets the original replaced sub-operand Register.
|
||||
* @param reg the register
|
||||
*/
|
||||
public void setReplacedElement(Register reg) {
|
||||
replacedElement = reg;
|
||||
@@ -107,9 +102,6 @@ public class VariableOffset {
|
||||
return replacedElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
@@ -204,7 +196,7 @@ public class VariableOffset {
|
||||
}
|
||||
|
||||
List<Object> list = new ArrayList<>();
|
||||
list.add(new LabelString(name.toString(), LabelString.VARIABLE));
|
||||
list.add(new LabelString(name.toString(), LabelType.VARIABLE));
|
||||
|
||||
if (absOffset != 0 || scalarAdjustment != 0) {
|
||||
long adjustedOffset = (offset < 0 ? -absOffset : absOffset) + scalarAdjustment;
|
||||
|
||||
Reference in New Issue
Block a user