Merge branch
Some checks failed
Build Ghidra / build (ubuntu-latest) (push) Failing after 3s
Dependency Submission / dependency-submission (push) Failing after 3s

'GP-0_ryanmkurtz_PR-9512_sylvesterkaczmarek_fix_2445-sleigh-64-bit-constraint'
(Closes #9512, Closes #2445)
This commit is contained in:
Ryan Kurtz 2026-08-20 07:00:50 -04:00
commit e44be6f91f
2 changed files with 85 additions and 33 deletions

View file

@ -1,13 +1,12 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* 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.
@ -17,42 +16,48 @@
package ghidra.pcodeCPort.slghpatexpress;
import generic.stl.VectorSTL;
import ghidra.pcodeCPort.context.*;
import ghidra.pcodeCPort.context.SleighError;
import ghidra.sleigh.grammar.Location;
public class EqualEquation extends ValExpressEquation {
public EqualEquation(Location location, PatternValue l, PatternExpression r) {
super(location, l, r);
}
public EqualEquation(Location location, PatternValue l, PatternExpression r) {
super(location, l, r);
}
@Override
public void genPattern(VectorSTL<TokenPattern> ops) {
long lhsmin = lhs.minValue();
long lhsmax = lhs.maxValue();
VectorSTL<PatternValue> semval = new VectorSTL<PatternValue>();
VectorSTL<Long> min = new VectorSTL<Long>();
VectorSTL<Long> max = new VectorSTL<Long>();
VectorSTL<Long> cur = new VectorSTL<Long>();
int count = 0;
static boolean isValueInRange(long value, long min, long max) {
return Long.compareUnsigned(value, min) >= 0 && Long.compareUnsigned(value, max) <= 0;
}
rhs.listValues(semval);
rhs.getMinMax(min, max);
cur = min.copy();
@Override
public void genPattern(VectorSTL<TokenPattern> ops) {
long lhsmin = lhs.minValue();
long lhsmax = lhs.maxValue();
VectorSTL<PatternValue> semval = new VectorSTL<PatternValue>();
VectorSTL<Long> min = new VectorSTL<Long>();
VectorSTL<Long> max = new VectorSTL<Long>();
VectorSTL<Long> cur = new VectorSTL<Long>();
int count = 0;
do {
long val = rhs.getSubValue(cur);
if ((val >= lhsmin) && (val <= lhsmax)) {
if (count == 0)
setTokenPattern(ExpressUtils.buildPattern(lhs, val, semval, cur));
else
setTokenPattern(getTokenPattern().doOr(ExpressUtils.buildPattern(lhs, val, semval, cur)));
count += 1;
}
} while (ExpressUtils.advance_combo(cur, min, max));
if (count == 0) {
throw new SleighError("Equal constraint is impossible to match", location);
}
}
rhs.listValues(semval);
rhs.getMinMax(min, max);
cur = min.copy();
do {
long val = rhs.getSubValue(cur);
if (isValueInRange(val, lhsmin, lhsmax)) {
if (count == 0)
setTokenPattern(ExpressUtils.buildPattern(lhs, val, semval, cur));
else
setTokenPattern(
getTokenPattern().doOr(ExpressUtils.buildPattern(lhs, val, semval, cur)));
count += 1;
}
}
while (ExpressUtils.advance_combo(cur, min, max));
if (count == 0) {
throw new SleighError("Equal constraint is impossible to match", location);
}
}
}

View file

@ -0,0 +1,47 @@
/* ###
* IP: GHIDRA
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.pcodeCPort.slghpatexpress;
import static org.junit.Assert.*;
import org.junit.Test;
public class EqualEquationTest {
@Test
public void testNormalRange() {
assertTrue(EqualEquation.isValueInRange(0x1234, 0, 0xffff));
assertFalse(EqualEquation.isValueInRange(-1, 0, 0xffff));
}
@Test
public void testFullWidthUnsignedRange() {
assertTrue(EqualEquation.isValueInRange(0, 0, -1));
assertTrue(EqualEquation.isValueInRange(Long.MAX_VALUE, 0, -1));
assertTrue(EqualEquation.isValueInRange(Long.MIN_VALUE, 0, -1));
assertTrue(EqualEquation.isValueInRange(-1, 0, -1));
}
@Test
public void testUnsignedRangeCrossingSignedBoundary() {
assertFalse(EqualEquation.isValueInRange(4, 5, -2));
assertTrue(EqualEquation.isValueInRange(5, 5, -2));
assertTrue(EqualEquation.isValueInRange(Long.MAX_VALUE, 5, -2));
assertTrue(EqualEquation.isValueInRange(Long.MIN_VALUE, 5, -2));
assertTrue(EqualEquation.isValueInRange(-2, 5, -2));
assertFalse(EqualEquation.isValueInRange(-1, 5, -2));
}
}