diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/QueryOpinionService.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/QueryOpinionService.java
index e9e1caeb70..03908b1f74 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/QueryOpinionService.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/QueryOpinionService.java
@@ -15,9 +15,10 @@
*/
package ghidra.app.util.opinion;
-import java.io.IOException;
import java.util.*;
+import java.io.IOException;
+
import org.apache.commons.lang3.StringUtils;
import org.xml.sax.*;
@@ -206,53 +207,60 @@ public class QueryOpinionService {
return queryResult;
}
- static boolean secondaryAttributeMatches(String eFlagsDecimalString, String attribute) {
-
- // eFlagDecimalString is the elf e_flags value, as a decimal string
- // sa is the secondary attribute string from the opinion file,
- // and it must start with "0x" or "0b"
- if (attribute == null) {
+ /**
+ * Match a secondaryKey value string against a binary or hex formatted constraint.
+ *
+ * The constraint value needs to be patterned as:
+ *
Binary: "0b1110_0001 111..." (spaces and "_" ignored, dots are wildcards)
+ * Hex: "0xaabb_ccdd" (hex digits, spaces and "_" ignored)
+ *
+ * @param secondaryKey decimal integer string that is being searched for
+ * @param constraint value or pattern that the secondaryKey is being compared against
+ * @return boolean true if the secondaryKey matches the constraint; false if it doesn't match
+ * or if the constraint isn't a binary or hex constraint, or if the secondaryKey value isn't
+ * an integer
+ */
+ static boolean secondaryAttributeMatches(String secondaryKey, String constraint) {
+ if (constraint == null) {
return false;
}
- if (!StringUtils.startsWithAny(attribute.toLowerCase(), "0x", "0b")) {
+ int secondaryKeyInt;
+ try {
+ secondaryKeyInt = Integer.parseInt(secondaryKey);
+ }
+ catch (NumberFormatException e) {
return false;
}
- int eFlagsInt = Integer.parseInt(eFlagsDecimalString);
- String eFlagsBinaryString = Integer.toBinaryString(eFlagsInt);
- if (eFlagsBinaryString == null) {
- return false;
- }
-
- eFlagsBinaryString = StringUtils.leftPad(eFlagsBinaryString, 32, "0");
- String eFlagsHexString = Integer.toHexString(eFlagsInt);
- eFlagsHexString = StringUtils.leftPad(eFlagsHexString, 8, "0");
-
- // Remove '_' and whitespace from the attribute string
- String cleaned = attribute.replace("_", "").replaceAll("\\s+", "").trim();
- String prefix = cleaned.substring(0, 2);
- String value = cleaned.substring(2);
- if (prefix.toLowerCase().startsWith("0x")) {
-
- // It's a hex string
- value = StringUtils.leftPad(value, 8, "0");
- return value.equals(eFlagsHexString);
- }
-
- // It's a binary string
- value = StringUtils.leftPad(value, 32, "0");
- for (int i = 0; i < 32; i++) {
- char c = value.charAt(i);
- if (c == '.') { // wildcard
- continue;
+ constraint = constraint.replaceAll("[_\\s]+", "").trim().toLowerCase();
+ if (constraint.startsWith("0x")) { // Hex constraint string
+ try {
+ int hexConstraint = Integer.parseUnsignedInt(constraint.substring(2), 16);
+ return secondaryKeyInt == hexConstraint;
}
-
- if (eFlagsBinaryString.charAt(i) != c) {
- return false;
+ catch (NumberFormatException e) {
+ // fall thru, return false
}
+ return false;
}
+ else if (constraint.startsWith("0b")) { // Binary constraint string
+ String secondaryKeyBinaryString = Integer.toBinaryString(secondaryKeyInt);
+ secondaryKeyBinaryString = StringUtils.leftPad(secondaryKeyBinaryString, 32, "0");
- return true;
+ String constraintBinaryString = StringUtils.leftPad(constraint.substring(2), 32, "0");
+ for (int i = 0; i < 32; i++) {
+ char c = constraintBinaryString.charAt(i);
+ if (c == '.') { // wildcard
+ continue;
+ }
+
+ if (secondaryKeyBinaryString.charAt(i) != c) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
}
}
diff --git a/Ghidra/Features/Base/src/test/java/ghidra/app/util/opinion/QueryOpinionServiceTest.java b/Ghidra/Features/Base/src/test/java/ghidra/app/util/opinion/QueryOpinionServiceTest.java
index 0d55819a57..e489a4ac57 100644
--- a/Ghidra/Features/Base/src/test/java/ghidra/app/util/opinion/QueryOpinionServiceTest.java
+++ b/Ghidra/Features/Base/src/test/java/ghidra/app/util/opinion/QueryOpinionServiceTest.java
@@ -50,4 +50,22 @@ public class QueryOpinionServiceTest {
}
+ @Test
+ public void testHexConstraint() {
+ assertTrue(QueryOpinionService.secondaryAttributeMatches("85", "0x55"));
+ assertTrue(QueryOpinionService.secondaryAttributeMatches("-1", "0xff ff_ff ff"));
+ }
+
+ @Test
+ public void testNotBinaryOrHexConstraint() {
+ assertFalse(QueryOpinionService.secondaryAttributeMatches("1", "not_a_valid_constraint"));
+ assertFalse(QueryOpinionService.secondaryAttributeMatches("1", "0b1x"));
+ assertFalse(QueryOpinionService.secondaryAttributeMatches("1", ""));
+ }
+
+ @Test
+ public void testNotIntegerKey() {
+ assertFalse(QueryOpinionService.secondaryAttributeMatches("abc", "0x1"));
+ assertFalse(QueryOpinionService.secondaryAttributeMatches("", "0b...."));
+ }
}
diff --git a/Ghidra/Processors/ARM/data/languages/ARM.opinion b/Ghidra/Processors/ARM/data/languages/ARM.opinion
index 64634f1136..49302336f4 100644
--- a/Ghidra/Processors/ARM/data/languages/ARM.opinion
+++ b/Ghidra/Processors/ARM/data/languages/ARM.opinion
@@ -1,4 +1,13 @@
+
diff --git a/Ghidra/Processors/MIPS/data/languages/MIPS.opinion b/Ghidra/Processors/MIPS/data/languages/MIPS.opinion
index 48698d8a21..a739a3631f 100644
--- a/Ghidra/Processors/MIPS/data/languages/MIPS.opinion
+++ b/Ghidra/Processors/MIPS/data/languages/MIPS.opinion
@@ -1,4 +1,13 @@
+