From 3e240563ab9ba4cca931e9e59d490664bff17bc5 Mon Sep 17 00:00:00 2001 From: dragonmacher <48328597+dragonmacher@users.noreply.github.com> Date: Tue, 19 Aug 2025 16:49:40 -0400 Subject: [PATCH 1/2] Test debug --- .../DecompilerDataTypeReferenceFinder.java | 36 +++++++-------- .../extension/datatype/finder/DtrfDbg.java | 26 ++++++++--- .../datatype/finder/VariableAccessDR.java | 46 ++++++++++--------- .../ConcurrentTestExceptionStatement.java | 11 ++--- 4 files changed, 66 insertions(+), 53 deletions(-) diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DecompilerDataTypeReferenceFinder.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DecompilerDataTypeReferenceFinder.java index b3de9e39ed..e583baae85 100644 --- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DecompilerDataTypeReferenceFinder.java +++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DecompilerDataTypeReferenceFinder.java @@ -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. @@ -130,7 +130,7 @@ public class DecompilerDataTypeReferenceFinder implements DataTypeReferenceFinde } results.addAll(callers); - + // Add any callers to external function that use any form of the data type it = listing.getExternalFunctions(); callers = new HashSet<>(); @@ -142,7 +142,7 @@ public class DecompilerDataTypeReferenceFinder implements DataTypeReferenceFinde callers.addAll(callingFunctions); } } - + results.addAll(callers); return results; @@ -298,16 +298,12 @@ public class DecompilerDataTypeReferenceFinder implements DataTypeReferenceFinde private DataType dataType; private FieldMatcher fieldMatcher; - private String dbgPrefix; - DecompilerDataTypeFinder(DecompileResults results, Function function, DataType dataType, FieldMatcher fieldMatcher) { this.decompilation = results; this.function = function; this.dataType = dataType; this.fieldMatcher = fieldMatcher; - - this.dbgPrefix = "f: " + function + "\n\t"; } List findUsage() { @@ -331,16 +327,16 @@ public class DecompilerDataTypeReferenceFinder implements DataTypeReferenceFinde return; } - DtrfDbg.println(dbgPrefix + "checking vars..."); + DtrfDbg.println(function, "checking vars..."); List variables = findVariableReferences(tokens); - DtrfDbg.println(dbgPrefix + "DONE searching decompilation\nMatching results"); + DtrfDbg.println(function, "DONE searching decompilation\nMatching results"); variables.forEach(v -> matchUsage(v, results)); } /** Finds any search input match in the given reference */ private void matchUsage(DecompilerReference reference, List results) { - DtrfDbg.println("Checking " + reference); + DtrfDbg.println(function, "Checking " + reference); reference.accumulateMatches(dataType, fieldMatcher, results); } @@ -388,12 +384,12 @@ public class DecompilerDataTypeReferenceFinder implements DataTypeReferenceFinde VariableAccessDR access = null; for (ClangToken token : filteredTokens) { - DtrfDbg.println(dbgPrefix + "checking token: " + token); + DtrfDbg.println(function, "checking token: " + token); if (token instanceof ClangTypeToken) { if (token.Parent() instanceof ClangReturnType) { - DtrfDbg.println(dbgPrefix + "\treturn type: " + line); + DtrfDbg.println(function, "\treturn type: " + line); results.add(new ReturnTypeDR(line, (ClangTypeToken) token)); } @@ -401,13 +397,13 @@ public class DecompilerDataTypeReferenceFinder implements DataTypeReferenceFinde // Note: variable refs will get their variable in an upcoming token if (isFunctionPrototype(token.Parent())) { - DtrfDbg.println(dbgPrefix + "\tparameter: " + line); + DtrfDbg.println(function, "\tparameter: " + line); declaration = new ParameterDR(line, (ClangTypeToken) token); } else { - DtrfDbg.println(dbgPrefix + "\tlocal var: " + line); + DtrfDbg.println(function, "\tlocal var: " + line); declaration = new LocalVariableDR(line, (ClangTypeToken) token); } @@ -416,7 +412,7 @@ public class DecompilerDataTypeReferenceFinder implements DataTypeReferenceFinde } else { - DtrfDbg.println(dbgPrefix + "\tadding a cast"); + DtrfDbg.println(function, "\tadding a cast"); // Assumption: this is a cast inside of a ClangStatement // Assumption: there can be multiple casts concatenated @@ -438,7 +434,7 @@ public class DecompilerDataTypeReferenceFinder implements DataTypeReferenceFinde // if (declaration != null) { - DtrfDbg.println(dbgPrefix + "\thave declaration - " + declaration); + DtrfDbg.println(function, "\thave declaration - " + declaration); declaration.setVariable((ClangVariableToken) token); declaration = null; @@ -446,7 +442,7 @@ public class DecompilerDataTypeReferenceFinder implements DataTypeReferenceFinde else { if (access == null || access.getVariable() != null) { - DtrfDbg.println(dbgPrefix + "\tcreating variable access: " + line); + DtrfDbg.println(function, "\tcreating variable access: " + line); access = new VariableAccessDR(line); results.add(access); @@ -479,8 +475,8 @@ public class DecompilerDataTypeReferenceFinder implements DataTypeReferenceFinde ClangFieldToken field = (ClangFieldToken) token; if (typesDoNotMatch(access, field)) { - DtrfDbg.println( - dbgPrefix + "\tcreating an anonymous variable access: " + line); + DtrfDbg.println(function, + "\tcreating an anonymous variable access: " + line); // this can happen when a field is used anonymously, such as directly // after a nested array index operation diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DtrfDbg.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DtrfDbg.java index 199bb656f6..5ab56184ce 100644 --- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DtrfDbg.java +++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/DtrfDbg.java @@ -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,10 +18,12 @@ package ghidra.app.extension.datatype.finder; import java.io.ByteArrayOutputStream; import java.io.PrintWriter; import java.util.*; +import java.util.Map.Entry; import org.apache.commons.lang3.StringUtils; import generic.io.NullPrintWriter; +import ghidra.program.model.listing.Function; import ghidra.util.Msg; /** @@ -36,6 +38,8 @@ class DtrfDbg { private static List clientFilters = new ArrayList<>(); + private static Map> linesByFunction = new HashMap<>(); + DtrfDbg() { // static class } @@ -57,6 +61,16 @@ class DtrfDbg { return; } + Set>> entries = linesByFunction.entrySet(); + for (Entry> entry : entries) { + Function function = entry.getKey(); + List lines = entry.getValue(); + debugWriter.println("\n\nFunction Debug: " + function.getName()); + for (String line : lines) { + debugWriter.println(line); + } + } + debugWriter.flush(); String output = debugBytes.toString(); if (!StringUtils.isBlank(output)) { @@ -76,16 +90,16 @@ class DtrfDbg { clientFilters.addAll(Arrays.asList(filters)); } - static void println(String s) { - debugWriter.println(s); + static void println(Function f, String s) { + linesByFunction.computeIfAbsent(f, ff -> new ArrayList<>()).add(s); } - static void println(Object client, String s) { + static void println(Function f, Object client, String s) { if (!passesFilter(client)) { return; } - debugWriter.println(s); + linesByFunction.computeIfAbsent(f, ff -> new ArrayList<>()).add(s); } private static boolean passesFilter(Object client) { diff --git a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/VariableAccessDR.java b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/VariableAccessDR.java index cb62fd64d2..a2ba9307a9 100644 --- a/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/VariableAccessDR.java +++ b/Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/VariableAccessDR.java @@ -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. @@ -25,7 +25,6 @@ import ghidra.app.services.FieldMatcher; import ghidra.program.model.address.Address; import ghidra.program.model.data.DataType; import ghidra.program.model.listing.Function; -import ghidra.program.model.pcode.HighGlobal; import ghidra.program.model.pcode.HighVariable; import ghidra.util.StringUtilities; import ghidra.util.exception.AssertException; @@ -106,7 +105,7 @@ public class VariableAccessDR extends DecompilerReference { private DecompilerVariable getMatch(DataType dt, FieldMatcher fieldMatcher, DecompilerVariable var, DecompilerVariable potentialField) { - String indent = "\t\t"; + String indent = "\t\t\t"; // Note: for now, I ignore the precedence of casting; if any cast type is a match, then // signal hooray @@ -114,19 +113,21 @@ public class VariableAccessDR extends DecompilerReference { DecompilerVariable fieldVar = searchForField ? potentialField : null; DecompilerVariable match = getMatchingVarialbe(dt, var, fieldVar); if (match == null) { - DtrfDbg.println(this, indent + "NO MATCHING VARIABLE"); + DtrfDbg.println(getFunction(), this, indent + "NO MATCHING VARIABLE"); return null; // wrong type, nothing to do } // Matches on the type, does the field match? if (fieldMatcher.isIgnored()) { - DtrfDbg.println(this, indent + "field macher is ignored; returning match"); + DtrfDbg.println(getFunction(), this, + indent + "field macher is ignored; returning match"); return match; // no field to match } if (potentialField == null) { - DtrfDbg.println(this, indent + "No potential field to match; name / offset match?"); + DtrfDbg.println(getFunction(), this, + indent + "No potential field to match; name / offset match?"); // check for the case where we have not been passed a 'potential field', but the given // 'var' is itself may be the field we seek, such as in an if statement like this: @@ -135,23 +136,25 @@ public class VariableAccessDR extends DecompilerReference { String name = var.getName(); int offset = var.getOffset(); if (fieldMatcher.matches(name, offset)) { - DtrfDbg.println(this, indent + "\tfield matcher matched on variable: " + var); + StringUtilities.indentLines(var.toString(), indent + '\t'); + DtrfDbg.println(getFunction(), this, + indent + "\tfield matcher matched on variable: " + var); return var; } - DtrfDbg.println(this, indent + "\tNO FIELD MATCHER MATCH"); + DtrfDbg.println(getFunction(), this, indent + "\tNO FIELD MATCHER MATCH"); return null; // we seek a field, but there is none } - DtrfDbg.println(this, indent + "Checking 'potential field' match..."); + DtrfDbg.println(getFunction(), this, indent + "Checking 'potential field' match..."); String name = potentialField.getName(); int offset = potentialField.getOffset(); if (fieldMatcher.matches(name, offset)) { - DtrfDbg.println(this, indent + "\tMATCHED"); + DtrfDbg.println(getFunction(), this, indent + "\tMATCHED"); return match; } - DtrfDbg.println(this, indent + "\tNO MATCH"); + DtrfDbg.println(getFunction(), this, indent + "\tNO MATCH"); return null; } @@ -160,26 +163,27 @@ public class VariableAccessDR extends DecompilerReference { String indent = "\t\t\t"; - DtrfDbg.println(this, indent + "Checking for matching variable; any casts?"); + DtrfDbg.println(getFunction(), this, indent + "Checking for matching variable; any casts?"); List castVariables = var.getCasts(); for (DecompilerVariable cast : castVariables) { if (matchesType(cast, dt)) { - DtrfDbg.println(this, indent + "MATCHED cast: " + cast); + DtrfDbg.println(getFunction(), this, indent + "MATCHED cast: " + cast); return cast; } } String dtString = dt == null ? "null" : dt.toString(); - DtrfDbg.println(this, + DtrfDbg.println(getFunction(), this, indent + "No matched casts; checking type against var:\n" + StringUtilities.indentLines("type: " + dtString, indent + "\t") + "\n" + StringUtilities.indentLines("var: " + var.toString(), indent + "\t")); if (matchesType(var, dt)) { - DtrfDbg.println(this, indent + "MATCHED type: "); + DtrfDbg.println(getFunction(), this, indent + "MATCHED type: "); return var; } - DtrfDbg.println(this, indent + "Type did not match; checking High Variable: "); + DtrfDbg.println(getFunction(), this, + indent + "Type did not match; checking High Variable: "); // // Unusual Code Alert! @@ -194,12 +198,12 @@ public class VariableAccessDR extends DecompilerReference { HighVariable highVariable = var.variable.getHighVariable(); if (highVariable != null) { if (matchesParentType(potentialField, dt)) { - DtrfDbg.println(this, indent + "MATCHED on parent type: " + dt); + DtrfDbg.println(getFunction(), this, indent + "MATCHED on parent type: " + dt); return potentialField; } } - DtrfDbg.println(this, indent + "NOT MATCHED"); + DtrfDbg.println(getFunction(), this, indent + "NOT MATCHED"); return null; } @@ -218,7 +222,7 @@ public class VariableAccessDR extends DecompilerReference { String indent = "\t\t\t\t"; if (var == null) { - DtrfDbg.println(this, indent + "Types Match? no variable to check"); + DtrfDbg.println(getFunction(), this, indent + "Types Match? no variable to check"); return false; } @@ -226,7 +230,7 @@ public class VariableAccessDR extends DecompilerReference { if (varType == null) { // it seems odd to me that there is no type, but I have seen this in the case // statement of a switch - DtrfDbg.println(this, indent + "ypes Match? no variable TYPE to check"); + DtrfDbg.println(getFunction(), this, indent + "ypes Match? no variable TYPE to check"); return false; } boolean matches = isEqual(varType, dt); diff --git a/Ghidra/Framework/Generic/src/main/java/generic/test/ConcurrentTestExceptionStatement.java b/Ghidra/Framework/Generic/src/main/java/generic/test/ConcurrentTestExceptionStatement.java index b8720a9e43..3009cdf2b1 100644 --- a/Ghidra/Framework/Generic/src/main/java/generic/test/ConcurrentTestExceptionStatement.java +++ b/Ghidra/Framework/Generic/src/main/java/generic/test/ConcurrentTestExceptionStatement.java @@ -16,12 +16,10 @@ package generic.test; import java.util.List; -import java.util.concurrent.TimeUnit; import org.junit.runners.model.Statement; import ghidra.util.Msg; -import ghidra.util.SystemUtilities; import ghidra.util.timer.GTimer; import ghidra.util.timer.GTimerMonitor; import junit.framework.AssertionFailedError; @@ -204,10 +202,11 @@ public class ConcurrentTestExceptionStatement extends Statement { return; } - if (SystemUtilities.isInDevelopmentMode()) { - throw new AssertionFailedError("Test timeout after " + - TimeUnit.MINUTES.convert(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS) + " mins"); - } +// Not sure why we were doing this before +// if (SystemUtilities.isInDevelopmentMode()) { +// throw new AssertionFailedError("Test timeout after " + +// TimeUnit.MINUTES.convert(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS) + " mins"); +// } String vmTrace = AbstractGenericTest.createStackTraceForAllThreads(); Msg.error(ConcurrentTestExceptionStatement.class, From d38f512437a45acc9ac882451c6eff8af2a74ae1 Mon Sep 17 00:00:00 2001 From: ghidra1 Date: Tue, 19 Aug 2025 18:08:30 -0400 Subject: [PATCH 2/2] GP-1 Added ability to skip building of all natives for gradle build --- GPL/nativeBuildProperties.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/GPL/nativeBuildProperties.gradle b/GPL/nativeBuildProperties.gradle index 23eb20a824..f2505898f3 100644 --- a/GPL/nativeBuildProperties.gradle +++ b/GPL/nativeBuildProperties.gradle @@ -107,6 +107,9 @@ def isNativeBinaryMakeTask(Task task, String platform) { * ******************************************************************************************/ def shouldSkipNative(task) { + if (rootProject.hasProperty("skipAllNatives")) { + return true; + } return task.ext.has("skipNative") && task.ext.get("skipNative") }