Skip to content

Commit fde1241

Browse files
committed
Add abs, min, and max instructions
1 parent fa09f36 commit fde1241

22 files changed

Lines changed: 599 additions & 17 deletions

binaryninjaapi.h

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15069,6 +15069,60 @@ namespace BinaryNinja {
1506915069
*/
1507015070
ExprId CountLeadingSigns(size_t size, ExprId a, uint32_t flags = 0, const ILSourceLocation& loc = ILSourceLocation());
1507115071

15072+
/*! Signed minimum of expressions \c left and \c right of size \c size potentially setting flags
15073+
15074+
\param size The size of the result in bytes
15075+
\param left The left expression
15076+
\param right The right expression
15077+
\param flags Flags to set
15078+
\param loc Optional IL Location this expression was added from.
15079+
\return The expression <tt>mins.<size>{<flags>}(left, right)</tt>
15080+
*/
15081+
ExprId MinSigned(size_t size, ExprId left, ExprId right, uint32_t flags = 0, const ILSourceLocation& loc = ILSourceLocation());
15082+
15083+
/*! Signed maximum of expressions \c left and \c right of size \c size potentially setting flags
15084+
15085+
\param size The size of the result in bytes
15086+
\param left The left expression
15087+
\param right The right expression
15088+
\param flags Flags to set
15089+
\param loc Optional IL Location this expression was added from.
15090+
\return The expression <tt>maxs.<size>{<flags>}(left, right)</tt>
15091+
*/
15092+
ExprId MaxSigned(size_t size, ExprId left, ExprId right, uint32_t flags = 0, const ILSourceLocation& loc = ILSourceLocation());
15093+
15094+
/*! Unsigned minimum of expressions \c left and \c right of size \c size potentially setting flags
15095+
15096+
\param size The size of the result in bytes
15097+
\param left The left expression
15098+
\param right The right expression
15099+
\param flags Flags to set
15100+
\param loc Optional IL Location this expression was added from.
15101+
\return The expression <tt>minu.<size>{<flags>}(left, right)</tt>
15102+
*/
15103+
ExprId MinUnsigned(size_t size, ExprId left, ExprId right, uint32_t flags = 0, const ILSourceLocation& loc = ILSourceLocation());
15104+
15105+
/*! Unsigned maximum of expressions \c left and \c right of size \c size potentially setting flags
15106+
15107+
\param size The size of the result in bytes
15108+
\param left The left expression
15109+
\param right The right expression
15110+
\param flags Flags to set
15111+
\param loc Optional IL Location this expression was added from.
15112+
\return The expression <tt>maxu.<size>{<flags>}(left, right)</tt>
15113+
*/
15114+
ExprId MaxUnsigned(size_t size, ExprId left, ExprId right, uint32_t flags = 0, const ILSourceLocation& loc = ILSourceLocation());
15115+
15116+
/*! Signed absolute value of expression \c value of size \c size potentially setting flags
15117+
15118+
\param size The size of the result in bytes
15119+
\param a The expression to take the absolute value of
15120+
\param flags Flags to set
15121+
\param loc Optional IL Location this expression was added from.
15122+
\return The expression <tt>abs.<size>{<flags>}(value)</tt>
15123+
*/
15124+
ExprId AbsoluteValue(size_t size, ExprId a, uint32_t flags = 0, const ILSourceLocation& loc = ILSourceLocation());
15125+
1507215126
/*! Two's complement sign-extends the expression in \c value to \c size bytes
1507315127

1507415128
\param size The size of the result in bytes
@@ -15955,6 +16009,11 @@ namespace BinaryNinja {
1595516009
ExprId CountTrailingZeros(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
1595616010
ExprId ReverseBits(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
1595716011
ExprId CountLeadingSigns(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
16012+
ExprId MinSigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation());
16013+
ExprId MaxSigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation());
16014+
ExprId MinUnsigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation());
16015+
ExprId MaxUnsigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation());
16016+
ExprId AbsoluteValue(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
1595816017
ExprId SignExtend(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
1595916018
ExprId ZeroExtend(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
1596016019
ExprId LowPart(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
@@ -16362,6 +16421,11 @@ namespace BinaryNinja {
1636216421
ExprId CountTrailingZeros(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
1636316422
ExprId ReverseBits(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
1636416423
ExprId CountLeadingSigns(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
16424+
ExprId MinSigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation());
16425+
ExprId MaxSigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation());
16426+
ExprId MinUnsigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation());
16427+
ExprId MaxUnsigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation());
16428+
ExprId AbsoluteValue(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
1636516429
ExprId SignExtend(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
1636616430
ExprId ZeroExtend(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
1636716431
ExprId LowPart(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());

binaryninjacore.h

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@
3737
// Current ABI version for linking to the core. This is incremented any time
3838
// there are changes to the API that affect linking, including new functions,
3939
// new types, or modifications to existing functions or types.
40-
#define BN_CURRENT_CORE_ABI_VERSION 173
40+
#define BN_CURRENT_CORE_ABI_VERSION 174
4141

4242
// Minimum ABI version that is supported for loading of plugins. Plugins that
4343
// are linked to an ABI version less than this will not be able to load and
4444
// will require rebuilding. The minimum version is increased when there are
4545
// incompatible changes that break binary compatibility, such as changes to
4646
// existing types or functions.
47-
#define BN_MINIMUM_CORE_ABI_VERSION 173
47+
#define BN_MINIMUM_CORE_ABI_VERSION 174
4848

4949
#ifdef __GNUC__
5050
#ifdef BINARYNINJACORE_LIBRARY
@@ -770,7 +770,14 @@ extern "C"
770770
LLIL_CLZ, // Count leading zero bits; clz(0) == 8 * size
771771
LLIL_CTZ, // Count trailing zero bits; ctz(0) == 8 * size
772772
LLIL_RBIT, // Reverse bit order of the whole value
773-
LLIL_CLS // Count leading sign bits; number of bits below the sign bit that match it
773+
LLIL_CLS, // Count leading sign bits; number of bits below the sign bit that match it
774+
775+
// Integer minimum, maximum and absolute value
776+
LLIL_MINS, // Signed minimum of left and right
777+
LLIL_MAXS, // Signed maximum of left and right
778+
LLIL_MINU, // Unsigned minimum of left and right
779+
LLIL_MAXU, // Unsigned maximum of left and right
780+
LLIL_ABS // Signed absolute value of src; abs(INT_MIN) == INT_MIN
774781
};
775782

776783
BN_ENUM(uint8_t, BNLowLevelILFlagCondition)
@@ -1556,7 +1563,14 @@ extern "C"
15561563
MLIL_CLZ, // Count leading zero bits; clz(0) == 8 * size
15571564
MLIL_CTZ, // Count trailing zero bits; ctz(0) == 8 * size
15581565
MLIL_RBIT, // Reverse bit order of the whole value
1559-
MLIL_CLS // Count leading sign bits; number of bits below the sign bit that match it
1566+
MLIL_CLS, // Count leading sign bits; number of bits below the sign bit that match it
1567+
1568+
// Integer minimum, maximum and absolute value
1569+
MLIL_MINS, // Signed minimum of left and right
1570+
MLIL_MAXS, // Signed maximum of left and right
1571+
MLIL_MINU, // Unsigned minimum of left and right
1572+
MLIL_MAXU, // Unsigned maximum of left and right
1573+
MLIL_ABS // Signed absolute value of src; abs(INT_MIN) == INT_MIN
15601574
};
15611575

15621576
typedef struct BNMediumLevelILInstruction
@@ -1738,7 +1752,14 @@ extern "C"
17381752
HLIL_CLZ, // Count leading zero bits; clz(0) == 8 * size
17391753
HLIL_CTZ, // Count trailing zero bits; ctz(0) == 8 * size
17401754
HLIL_RBIT, // Reverse bit order of the whole value
1741-
HLIL_CLS // Count leading sign bits; number of bits below the sign bit that match it
1755+
HLIL_CLS, // Count leading sign bits; number of bits below the sign bit that match it
1756+
1757+
// Integer minimum, maximum and absolute value
1758+
HLIL_MINS, // Signed minimum of left and right
1759+
HLIL_MAXS, // Signed maximum of left and right
1760+
HLIL_MINU, // Unsigned minimum of left and right
1761+
HLIL_MAXU, // Unsigned maximum of left and right
1762+
HLIL_ABS // Signed absolute value of src; abs(INT_MIN) == INT_MIN
17421763
};
17431764

17441765
typedef struct BNHighLevelILInstruction

docs/dev/bnil-hlil.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ There are a number of properties that can be queried on the [`HighLevelILInstruc
117117
* `HLIL_CTZ` - Count trailing zero bits of `src` expression; the result is `8 * size` when `src` is zero
118118
* `HLIL_RBIT` - Reverse the bit order of `src` expression
119119
* `HLIL_CLS` - Count leading sign bits of `src` expression (the number of bits below the sign bit that match it)
120+
* `HLIL_MINS` - Signed minimum of `left` expression and `right` expression
121+
* `HLIL_MAXS` - Signed maximum of `left` expression and `right` expression
122+
* `HLIL_MINU` - Unsigned minimum of `left` expression and `right` expression
123+
* `HLIL_MAXU` - Unsigned maximum of `left` expression and `right` expression
124+
* `HLIL_ABS` - Signed absolute value of `src` expression
120125
* `HLIL_FADD` - IEEE754 floating point addition of `left` expression with `right` expression
121126
* `HLIL_FSUB` - IEEE754 floating point subtraction of `left` expression with `right` expression
122127
* `HLIL_FMUL` - IEEE754 floating point multiplication of `left` expression with `right` expression

docs/dev/bnil-llil.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,11 @@ The double precision instruction multiply, divide, modulus instructions are part
263263
* `LLIL_CTZ` - Count trailing zero bits of `src`; the result is `8 * size` when `src` is zero
264264
* `LLIL_RBIT` - Reverse the bit order of `src`
265265
* `LLIL_CLS` - Count leading sign bits of `src` (the number of bits below the sign bit that match it)
266+
* `LLIL_MINS` - Signed minimum of `left` and `right`
267+
* `LLIL_MAXS` - Signed maximum of `left` and `right`
268+
* `LLIL_MINU` - Unsigned minimum of `left` and `right`
269+
* `LLIL_MAXU` - Unsigned maximum of `left` and `right`
270+
* `LLIL_ABS` - Signed absolute value of `src`
266271
* `LLIL_TEST_BIT ` - Test if bit `right` in expression `left` is set
267272
* `LLIL_BOOL_TO_INT ` - Converts a bool `src` to an integer
268273

docs/dev/bnil-mlil.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,11 @@ The parameter list can be accessed through the `params` property:
354354
* `MLIL_CTZ` - Count trailing zero bits of `src` expression; the result is `8 * size` when `src` is zero
355355
* `MLIL_RBIT` - Reverse the bit order of `src` expression
356356
* `MLIL_CLS` - Count leading sign bits of `src` expression (the number of bits below the sign bit that match it)
357+
* `MLIL_MINS` - Signed minimum of `left` expression and `right` expression
358+
* `MLIL_MAXS` - Signed maximum of `left` expression and `right` expression
359+
* `MLIL_MINU` - Unsigned minimum of `left` expression and `right` expression
360+
* `MLIL_MAXU` - Unsigned maximum of `left` expression and `right` expression
361+
* `MLIL_ABS` - Signed absolute value of `src` expression
357362
* `MLIL_FADD` - IEEE754 floating point addition of `left` expression with `right` expression
358363
* `MLIL_FSUB` - IEEE754 floating point subtraction of `left` expression with `right` expression
359364
* `MLIL_FMUL` - IEEE754 floating point multiplication of `left` expression with `right` expression

highlevelilinstruction.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,11 @@ static constexpr std::array s_instructionOperandUsage = {
266266
OperandUsage{HLIL_CTZ, {SourceExprHighLevelOperandUsage}},
267267
OperandUsage{HLIL_RBIT, {SourceExprHighLevelOperandUsage}},
268268
OperandUsage{HLIL_CLS, {SourceExprHighLevelOperandUsage}},
269+
OperandUsage{HLIL_MINS, {LeftExprHighLevelOperandUsage, RightExprHighLevelOperandUsage}},
270+
OperandUsage{HLIL_MAXS, {LeftExprHighLevelOperandUsage, RightExprHighLevelOperandUsage}},
271+
OperandUsage{HLIL_MINU, {LeftExprHighLevelOperandUsage, RightExprHighLevelOperandUsage}},
272+
OperandUsage{HLIL_MAXU, {LeftExprHighLevelOperandUsage, RightExprHighLevelOperandUsage}},
273+
OperandUsage{HLIL_ABS, {SourceExprHighLevelOperandUsage}},
269274
};
270275

271276

@@ -1273,6 +1278,7 @@ void HighLevelILInstruction::CollectSubExprs(stack<size_t>& toProcess) const
12731278
case HLIL_CTZ:
12741279
case HLIL_RBIT:
12751280
case HLIL_CLS:
1281+
case HLIL_ABS:
12761282
case HLIL_SX:
12771283
case HLIL_ZX:
12781284
case HLIL_LOW_PART:
@@ -1298,6 +1304,10 @@ void HighLevelILInstruction::CollectSubExprs(stack<size_t>& toProcess) const
12981304
case HLIL_AND:
12991305
case HLIL_OR:
13001306
case HLIL_XOR:
1307+
case HLIL_MINS:
1308+
case HLIL_MAXS:
1309+
case HLIL_MINU:
1310+
case HLIL_MAXU:
13011311
case HLIL_LSL:
13021312
case HLIL_LSR:
13031313
case HLIL_ASR:
@@ -1587,6 +1597,7 @@ ExprId HighLevelILInstruction::CopyTo(
15871597
case HLIL_CTZ:
15881598
case HLIL_RBIT:
15891599
case HLIL_CLS:
1600+
case HLIL_ABS:
15901601
case HLIL_SX:
15911602
case HLIL_ZX:
15921603
case HLIL_LOW_PART:
@@ -1611,6 +1622,10 @@ ExprId HighLevelILInstruction::CopyTo(
16111622
case HLIL_AND:
16121623
case HLIL_OR:
16131624
case HLIL_XOR:
1625+
case HLIL_MINS:
1626+
case HLIL_MAXS:
1627+
case HLIL_MINU:
1628+
case HLIL_MAXU:
16141629
case HLIL_LSL:
16151630
case HLIL_LSR:
16161631
case HLIL_ASR:
@@ -2073,6 +2088,10 @@ bool HighLevelILInstruction::operator<(const HighLevelILInstruction& other) cons
20732088
case HLIL_AND:
20742089
case HLIL_OR:
20752090
case HLIL_XOR:
2091+
case HLIL_MINS:
2092+
case HLIL_MAXS:
2093+
case HLIL_MINU:
2094+
case HLIL_MAXU:
20762095
case HLIL_LSL:
20772096
case HLIL_LSR:
20782097
case HLIL_ASR:
@@ -2154,6 +2173,7 @@ bool HighLevelILInstruction::operator<(const HighLevelILInstruction& other) cons
21542173
case HLIL_CTZ:
21552174
case HLIL_RBIT:
21562175
case HLIL_CLS:
2176+
case HLIL_ABS:
21572177
case HLIL_SX:
21582178
case HLIL_ZX:
21592179
case HLIL_LOW_PART:
@@ -3157,6 +3177,36 @@ ExprId HighLevelILFunction::CountLeadingSigns(size_t size, ExprId src, const ILS
31573177
}
31583178

31593179

3180+
ExprId HighLevelILFunction::MinSigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc)
3181+
{
3182+
return AddExprWithLocation(HLIL_MINS, loc, size, left, right);
3183+
}
3184+
3185+
3186+
ExprId HighLevelILFunction::MaxSigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc)
3187+
{
3188+
return AddExprWithLocation(HLIL_MAXS, loc, size, left, right);
3189+
}
3190+
3191+
3192+
ExprId HighLevelILFunction::MinUnsigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc)
3193+
{
3194+
return AddExprWithLocation(HLIL_MINU, loc, size, left, right);
3195+
}
3196+
3197+
3198+
ExprId HighLevelILFunction::MaxUnsigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc)
3199+
{
3200+
return AddExprWithLocation(HLIL_MAXU, loc, size, left, right);
3201+
}
3202+
3203+
3204+
ExprId HighLevelILFunction::AbsoluteValue(size_t size, ExprId src, const ILSourceLocation& loc)
3205+
{
3206+
return AddExprWithLocation(HLIL_ABS, loc, size, src);
3207+
}
3208+
3209+
31603210
ExprId HighLevelILFunction::SignExtend(size_t size, ExprId src, const ILSourceLocation& loc)
31613211
{
31623212
return AddExprWithLocation(HLIL_SX, loc, size, src);

highlevelilinstruction.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1472,6 +1472,21 @@ namespace BinaryNinja
14721472
struct HighLevelILInstructionAccessor<HLIL_CLS> : public HighLevelILOneOperandInstruction
14731473
{};
14741474
template <>
1475+
struct HighLevelILInstructionAccessor<HLIL_MINS> : public HighLevelILTwoOperandInstruction
1476+
{};
1477+
template <>
1478+
struct HighLevelILInstructionAccessor<HLIL_MAXS> : public HighLevelILTwoOperandInstruction
1479+
{};
1480+
template <>
1481+
struct HighLevelILInstructionAccessor<HLIL_MINU> : public HighLevelILTwoOperandInstruction
1482+
{};
1483+
template <>
1484+
struct HighLevelILInstructionAccessor<HLIL_MAXU> : public HighLevelILTwoOperandInstruction
1485+
{};
1486+
template <>
1487+
struct HighLevelILInstructionAccessor<HLIL_ABS> : public HighLevelILOneOperandInstruction
1488+
{};
1489+
template <>
14751490
struct HighLevelILInstructionAccessor<HLIL_SX> : public HighLevelILOneOperandInstruction
14761491
{};
14771492
template <>

lang/c/pseudoc.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2490,6 +2490,31 @@ void PseudoCFunction::GetExprTextInternal(const HighLevelILInstruction& instr, H
24902490
}();
24912491
break;
24922492

2493+
case HLIL_MINS:
2494+
case HLIL_MINU:
2495+
AppendTwoOperandFunction("min", instr, tokens, settings, false);
2496+
if (statement)
2497+
tokens.AppendSemicolon();
2498+
break;
2499+
2500+
case HLIL_MAXS:
2501+
case HLIL_MAXU:
2502+
AppendTwoOperandFunction("max", instr, tokens, settings, false);
2503+
if (statement)
2504+
tokens.AppendSemicolon();
2505+
break;
2506+
2507+
case HLIL_ABS:
2508+
[&]() {
2509+
tokens.Append(OperationToken, "abs");
2510+
tokens.AppendOpenParen();
2511+
GetExprTextInternal(instr.GetSourceExpr<HLIL_ABS>(), tokens, settings);
2512+
tokens.AppendCloseParen();
2513+
if (statement)
2514+
tokens.AppendSemicolon();
2515+
}();
2516+
break;
2517+
24932518
case HLIL_FLOAT_CONV:
24942519
[&]() {
24952520
const auto srcExpr = instr.GetSourceExpr<HLIL_FLOAT_CONV>();

lang/rust/pseudorust.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2434,6 +2434,7 @@ void PseudoRustFunction::GetExprText(const HighLevelILInstruction& instr, HighLe
24342434
case HLIL_CTZ:
24352435
case HLIL_RBIT:
24362436
case HLIL_CLS:
2437+
case HLIL_ABS:
24372438
[&]() {
24382439
const char* method;
24392440
switch (instr.operation)
@@ -2443,6 +2444,7 @@ void PseudoRustFunction::GetExprText(const HighLevelILInstruction& instr, HighLe
24432444
case HLIL_CLZ: method = "leading_zeros"; break;
24442445
case HLIL_CTZ: method = "trailing_zeros"; break;
24452446
case HLIL_RBIT: method = "reverse_bits"; break;
2447+
case HLIL_ABS: method = "abs"; break;
24462448
default: method = "leading_sign_bits"; break;
24472449
}
24482450
GetExprText(instr.GetSourceExpr(), tokens, settings, MemberAndFunctionOperatorPrecedence);
@@ -2455,6 +2457,30 @@ void PseudoRustFunction::GetExprText(const HighLevelILInstruction& instr, HighLe
24552457
}();
24562458
break;
24572459

2460+
case HLIL_MINS:
2461+
case HLIL_MAXS:
2462+
case HLIL_MINU:
2463+
case HLIL_MAXU:
2464+
[&]() {
2465+
const char* method;
2466+
switch (instr.operation)
2467+
{
2468+
case HLIL_MINS:
2469+
case HLIL_MINU: method = "min"; break;
2470+
default: method = "max"; break;
2471+
}
2472+
const auto& twoOperand = instr.AsTwoOperand();
2473+
GetExprText(twoOperand.GetLeftExpr(), tokens, settings, MemberAndFunctionOperatorPrecedence);
2474+
tokens.Append(TextToken, ".");
2475+
tokens.Append(OperationToken, method);
2476+
tokens.AppendOpenParen();
2477+
GetExprText(twoOperand.GetRightExpr(), tokens, settings);
2478+
tokens.AppendCloseParen();
2479+
if (exprType != InnerExpression)
2480+
tokens.AppendSemicolon();
2481+
}();
2482+
break;
2483+
24582484
case HLIL_FLOAT_CONV:
24592485
[&]() {
24602486
const auto srcExpr = instr.GetSourceExpr<HLIL_FLOAT_CONV>();

0 commit comments

Comments
 (0)