diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/graph/AddressBasedGraphDisplayListener.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/graph/AddressBasedGraphDisplayListener.java
index 71447e37b4..8b3224d38f 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/graph/AddressBasedGraphDisplayListener.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/graph/AddressBasedGraphDisplayListener.java
@@ -20,6 +20,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import docking.widgets.EventTrigger;
import ghidra.app.events.*;
+import ghidra.app.nav.NavigationUtils;
import ghidra.framework.model.*;
import ghidra.framework.plugintool.PluginEvent;
import ghidra.framework.plugintool.PluginTool;
@@ -158,9 +159,22 @@ public abstract class AddressBasedGraphDisplayListener
if (symbols.isEmpty()) {
return null;
}
- // there should only be one external symbol with the same name, so just assume the first one is good
- return symbols.get(0).getAddress();
+ // There should only be one external symbol with the same name.
+ // Since externals are not shown in the listing, we are going to do a hack and try
+ // and navigate to a "fake" function if one exists. A "fake" function in Ghidra is just
+ // an indirect pointer to the external function. If such a pointer exists, Ghidra marks
+ // up the location with the function signature.
+ Address symbolAddress = symbols.get(0).getAddress();
+ if (symbolAddress.isExternalAddress()) {
+ Address[] externalLinkageAddresses =
+ NavigationUtils.getExternalLinkageAddresses(program, symbolAddress);
+ // If this is a "fake" function situation, then there should only be one address
+ if (externalLinkageAddresses.length == 1) {
+ symbolAddress = externalLinkageAddresses[0];
+ }
+ }
+ return symbolAddress;
}
protected Address getAddress(AttributedVertex vertex) {
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/label/EditLabelAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/label/EditLabelAction.java
index b7769d8499..c687aca691 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/label/EditLabelAction.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/label/EditLabelAction.java
@@ -25,6 +25,7 @@ import ghidra.app.context.ListingActionContext;
import ghidra.app.context.ListingContextAction;
import ghidra.program.database.symbol.CodeSymbol;
import ghidra.program.model.symbol.Symbol;
+import ghidra.program.model.symbol.SymbolType;
import ghidra.program.util.LabelFieldLocation;
import ghidra.program.util.OperandFieldLocation;
@@ -64,6 +65,10 @@ class EditLabelAction extends ListingContextAction {
if (symbol.isExternal()) {
return false;
}
+ if (symbol.getSymbolType() == SymbolType.FUNCTION) {
+ // let the rename function action handle this
+ return false;
+ }
getPopupMenuData().setMenuItemName(EDIT_LABEL);
return true;
}
diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/RenameFunctionAction.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/RenameFunctionAction.java
index a978a5a314..60433152bb 100644
--- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/RenameFunctionAction.java
+++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/RenameFunctionAction.java
@@ -27,6 +27,8 @@ import ghidra.app.util.AddEditDialog;
import ghidra.app.util.HelpTopics;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program;
+import ghidra.program.model.pcode.HighFunctionShellSymbol;
+import ghidra.program.model.pcode.HighSymbol;
import ghidra.util.HelpLocation;
import ghidra.util.UndefinedFunction;
@@ -39,26 +41,32 @@ public class RenameFunctionAction extends AbstractDecompilerAction {
setPopupMenuData(new MenuData(new String[] { "Rename Function" }, "Decompile"));
}
- private Function getFunction(Program program, ClangToken tokenAtCursor) {
+ private Function getFunction(DecompilerActionContext context) {
+ Program program = context.getProgram();
+ ClangToken tokenAtCursor = context.getTokenAtCursor();
+
// try to look up the function that is at the current cursor location
// If there isn't one, just use the function we are in.
if (tokenAtCursor instanceof ClangFuncNameToken) {
return DecompilerUtils.getFunction(program, (ClangFuncNameToken) tokenAtCursor);
}
+ HighSymbol highSymbol = findHighSymbolFromToken(tokenAtCursor, context.getHighFunction());
+ if (highSymbol instanceof HighFunctionShellSymbol) {
+ return (Function) highSymbol.getSymbol().getObject();
+ }
return null;
}
@Override
protected boolean isEnabledForDecompilerContext(DecompilerActionContext context) {
- Function func =
- getFunction(context.getProgram(), context.getTokenAtCursor());
+ Function func = getFunction(context);
return func != null && !(func instanceof UndefinedFunction);
}
@Override
protected void decompilerActionPerformed(DecompilerActionContext context) {
Program program = context.getProgram();
- Function function = getFunction(program, context.getTokenAtCursor());
+ Function function = getFunction(context);
AddEditDialog dialog = new AddEditDialog("Edit Function Name", context.getTool());
dialog.editLabel(function.getSymbol(), program);
}
diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/RenameGlobalAction.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/RenameGlobalAction.java
index 48a8747a6b..b39094af4d 100644
--- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/RenameGlobalAction.java
+++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/RenameGlobalAction.java
@@ -28,6 +28,7 @@ import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Function;
import ghidra.program.model.pcode.HighCodeSymbol;
+import ghidra.program.model.pcode.HighFunctionShellSymbol;
import ghidra.program.model.pcode.HighSymbol;
import ghidra.program.model.symbol.Symbol;
import ghidra.program.model.symbol.SymbolTable;
@@ -62,7 +63,7 @@ public class RenameGlobalAction extends AbstractDecompilerAction {
return false;
}
HighSymbol highSymbol = findHighSymbolFromToken(tokenAtCursor, context.getHighFunction());
- if (highSymbol == null) {
+ if (highSymbol == null || highSymbol instanceof HighFunctionShellSymbol) {
return false;
}
return highSymbol.isGlobal();
diff --git a/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/DefaultGraphDisplay.java b/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/DefaultGraphDisplay.java
index 856126f516..90bb1741ce 100644
--- a/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/DefaultGraphDisplay.java
+++ b/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/DefaultGraphDisplay.java
@@ -666,6 +666,9 @@ public class DefaultGraphDisplay implements GraphDisplay {
satellite.getRenderContext().setVertexFillPaintFunction(Colors::getColor);
satellite.scaleToLayout();
satellite.getRenderContext().setVertexLabelFunction(n -> null);
+ // always get the current predicate from the main view and test with it,
+ satellite.getRenderContext()
+ .setVertexIncludePredicate(v -> viewer.getRenderContext().getVertexIncludePredicate().test(v));
satellite.getComponent().setBorder(BorderFactory.createEtchedBorder());
parentViewer.getComponent().addComponentListener(new ComponentAdapter() {
@Override
@@ -873,7 +876,7 @@ public class DefaultGraphDisplay implements GraphDisplay {
viewer.getRenderContext()
.setVertexIncludePredicate(
v -> v.getAttributeMap().values().stream().noneMatch(selected::contains));
- viewer.repaint();
+
});
edgeFilters = AttributeFilters.builder()
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/HighSymbol.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/HighSymbol.java
index ecbf29f663..fcf9ae229f 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/HighSymbol.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/HighSymbol.java
@@ -144,7 +144,7 @@ public class HighSymbol {
*/
public Symbol getSymbol() {
if (id != 0) {
- return function.getFunction().getProgram().getSymbolTable().getSymbol(id);
+ return getProgram().getSymbolTable().getSymbol(id);
}
return null;
}
diff --git a/Ghidra/Processors/ARM/data/languages/ARM.cspec b/Ghidra/Processors/ARM/data/languages/ARM.cspec
index 19c8bb9b00..4137ca1d69 100644
--- a/Ghidra/Processors/ARM/data/languages/ARM.cspec
+++ b/Ghidra/Processors/ARM/data/languages/ARM.cspec
@@ -82,7 +82,7 @@
-
+
@@ -158,8 +158,7 @@
tmpptr = lr & 0xfffffffe;
offset = *:1 (tmpptr + r0);
- offset = offset * 2;
- lr = lr + zext(offset);
+ lr = lr + 2 * zext(offset);
ISAModeSwitch = (lr & 1) != 0;
TB = ISAModeSwitch;
@@ -177,8 +176,7 @@
tmpptr = lr & 0xfffffffe;
offset = *:1 (tmpptr + r0);
- offset = offset * 2;
- lr = lr + sext(offset);
+ lr = lr + 2 * sext(offset);
ISAModeSwitch = (lr & 1) != 0;
TB = ISAModeSwitch;
@@ -197,8 +195,7 @@
index = r0 * 2;
offset = *:2 (tmpptr + index);
- offset = offset * 2;
- lr = lr + sext(offset);
+ lr = lr + 2 * sext(offset);
ISAModeSwitch = (lr & 1) != 0;
TB = ISAModeSwitch;
@@ -217,8 +214,7 @@
index = r0 * 2;
offset = *:2 (tmpptr + index);
- offset = offset * 2;
- lr = lr + zext(offset);
+ lr = lr + 2 * zext(offset);
ISAModeSwitch = (lr & 1) != 0;
TB = ISAModeSwitch;
diff --git a/Ghidra/Processors/ARM/data/languages/ARM_v45.cspec b/Ghidra/Processors/ARM/data/languages/ARM_v45.cspec
index db5ca37aae..5b6a05aaa1 100644
--- a/Ghidra/Processors/ARM/data/languages/ARM_v45.cspec
+++ b/Ghidra/Processors/ARM/data/languages/ARM_v45.cspec
@@ -59,6 +59,9 @@
+
+
+
@@ -117,8 +120,7 @@
tmpptr = lr & 0xfffffffe;
offset = *:1 (tmpptr + r0);
- offset = offset * 2;
- lr = lr + zext(offset);
+ lr = lr + 2 * zext(offset);
ISAModeSwitch = (lr & 1) != 0;
TB = ISAModeSwitch;
@@ -136,8 +138,7 @@
tmpptr = lr & 0xfffffffe;
offset = *:1 (tmpptr + r0);
- offset = offset * 2;
- lr = lr + sext(offset);
+ lr = lr + 2 * sext(offset);
ISAModeSwitch = (lr & 1) != 0;
TB = ISAModeSwitch;
@@ -156,8 +157,7 @@
index = r0 * 2;
offset = *:2 (tmpptr + index);
- offset = offset * 2;
- lr = lr + sext(offset);
+ lr = lr + 2 * sext(offset);
ISAModeSwitch = (lr & 1) != 0;
TB = ISAModeSwitch;
@@ -176,8 +176,7 @@
index = r0 * 2;
offset = *:2 (tmpptr + index);
- offset = offset * 2;
- lr = lr + zext(offset);
+ lr = lr + 2 * zext(offset);
ISAModeSwitch = (lr & 1) != 0;
TB = ISAModeSwitch;
diff --git a/Ghidra/Processors/ARM/data/languages/ARM_win.cspec b/Ghidra/Processors/ARM/data/languages/ARM_win.cspec
index 9e71ff4a04..f4e1dc2d1c 100644
--- a/Ghidra/Processors/ARM/data/languages/ARM_win.cspec
+++ b/Ghidra/Processors/ARM/data/languages/ARM_win.cspec
@@ -86,7 +86,7 @@
-
+