summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Ferrell <josh@vector35.com>2025-12-15 15:09:53 -0500
committerJosh Ferrell <josh@vector35.com>2025-12-15 23:55:53 -0500
commit9bb8792f6be698ed9f2bd6e1dc555bfd91709044 (patch)
tree22b6c523ea86cafe31356eeea0706d889d480121
parent95b849d05d05ae9e55eb839508536d5af314d331 (diff)
Add PossibleValueSet operation APIs and fixes to PVS python API
-rw-r--r--binaryninjaapi.h23
-rw-r--r--binaryninjacore.h25
-rw-r--r--function.cpp115
-rw-r--r--possiblevalueset.cpp384
-rw-r--r--python/variable.py171
-rw-r--r--rust/src/variable.rs207
6 files changed, 786 insertions, 139 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 55aa96ca..8da2e775 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -8361,7 +8361,7 @@ namespace BinaryNinja {
BulkSymbolModification(BulkSymbolModification&&) = default;
BulkSymbolModification& operator=(BulkSymbolModification&&) = default;
- private:
+ private:
Ref<BinaryView> m_view;
};
@@ -12442,6 +12442,27 @@ namespace BinaryNinja {
static PossibleValueSet FromAPIObject(BNPossibleValueSet& value);
BNPossibleValueSet ToAPIObject() const;
static void FreeAPIObject(BNPossibleValueSet* value);
+
+ PossibleValueSet Add(const PossibleValueSet& other, size_t size) const;
+ PossibleValueSet Subtract(const PossibleValueSet& other, size_t size) const;
+ PossibleValueSet Multiply(const PossibleValueSet& other, size_t size) const;
+ PossibleValueSet SignedDivide(const PossibleValueSet& other, size_t size) const;
+ PossibleValueSet UnsignedDivide(const PossibleValueSet& other, size_t size) const;
+ PossibleValueSet SignedMod(const PossibleValueSet& other, size_t size) const;
+ PossibleValueSet UnsignedMod(const PossibleValueSet& other, size_t size) const;
+ PossibleValueSet And(const PossibleValueSet& other, size_t size) const;
+ PossibleValueSet Or(const PossibleValueSet& other, size_t size) const;
+ PossibleValueSet Xor(const PossibleValueSet& other, size_t size) const;
+ PossibleValueSet ShiftLeft(const PossibleValueSet& other, size_t size) const;
+ PossibleValueSet LogicalShiftRight(const PossibleValueSet& other, size_t size) const;
+ PossibleValueSet ArithShiftRight(const PossibleValueSet& other, size_t size) const;
+ PossibleValueSet RotateLeft(const PossibleValueSet& other, size_t size) const;
+ PossibleValueSet RotateRight(const PossibleValueSet& other, size_t size) const;
+ PossibleValueSet Union(const PossibleValueSet& other, size_t size) const;
+ PossibleValueSet Intersection(const PossibleValueSet& other, size_t size) const;
+
+ PossibleValueSet Negate(size_t size) const;
+ PossibleValueSet Not(size_t size) const;
};
class FlowGraph;
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 8b26fb44..a1b22e4d 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -2883,7 +2883,7 @@ extern "C"
BNAnalysisState state;
size_t count, total;
} BNAnalysisProgress;
-
+
BN_ENUM(uint8_t, BNAnalysisMode)
{
FullAnalysisMode,
@@ -5097,7 +5097,6 @@ extern "C"
BNFunction* func, BNArchitecture* arch, uint64_t addr, BNType* functionType, size_t i);
BINARYNINJACOREAPI BNRegisterValue BNGetParameterValueAtLowLevelILInstruction(
BNFunction* func, size_t instr, BNType* functionType, size_t i);
- BINARYNINJACOREAPI void BNFreePossibleValueSet(BNPossibleValueSet* value);
BINARYNINJACOREAPI uint32_t* BNGetRegistersReadByInstruction(
BNFunction* func, BNArchitecture* arch, uint64_t addr, size_t* count);
BINARYNINJACOREAPI uint32_t* BNGetRegistersWrittenByInstruction(
@@ -8901,6 +8900,28 @@ extern "C"
BINARYNINJACOREAPI bool BNStringRecognizerRecognizeImport(BNStringRecognizer* recognizer, BNHighLevelILFunction* il,
size_t exprIndex, BNType* type, int64_t val, BNDerivedString* out);
+ // PossibleValueSet operations
+ BINARYNINJACOREAPI void BNFreePossibleValueSet(BNPossibleValueSet* object);
+ BINARYNINJACOREAPI BNPossibleValueSet BNPossibleValueSetUnion(const BNPossibleValueSet* object, const BNPossibleValueSet* other, size_t size);
+ BINARYNINJACOREAPI BNPossibleValueSet BNPossibleValueSetIntersection(const BNPossibleValueSet* object, const BNPossibleValueSet* other, size_t size);
+ BINARYNINJACOREAPI BNPossibleValueSet BNPossibleValueSetAdd(const BNPossibleValueSet* object, const BNPossibleValueSet* other, size_t size);
+ BINARYNINJACOREAPI BNPossibleValueSet BNPossibleValueSetSubtract(const BNPossibleValueSet* object, const BNPossibleValueSet* other, size_t size);
+ BINARYNINJACOREAPI BNPossibleValueSet BNPossibleValueSetMultiply(const BNPossibleValueSet* object, const BNPossibleValueSet* other, size_t size);
+ BINARYNINJACOREAPI BNPossibleValueSet BNPossibleValueSetSignedDivide(const BNPossibleValueSet* object, const BNPossibleValueSet* other, size_t size);
+ BINARYNINJACOREAPI BNPossibleValueSet BNPossibleValueSetUnsignedDivide(const BNPossibleValueSet* object, const BNPossibleValueSet* other, size_t size);
+ BINARYNINJACOREAPI BNPossibleValueSet BNPossibleValueSetSignedMod(const BNPossibleValueSet* object, const BNPossibleValueSet* other, size_t size);
+ BINARYNINJACOREAPI BNPossibleValueSet BNPossibleValueSetUnsignedMod(const BNPossibleValueSet* object, const BNPossibleValueSet* other, size_t size);
+ BINARYNINJACOREAPI BNPossibleValueSet BNPossibleValueSetAnd(const BNPossibleValueSet* object, const BNPossibleValueSet* other, size_t size);
+ BINARYNINJACOREAPI BNPossibleValueSet BNPossibleValueSetOr(const BNPossibleValueSet* object, const BNPossibleValueSet* other, size_t size);
+ BINARYNINJACOREAPI BNPossibleValueSet BNPossibleValueSetXor(const BNPossibleValueSet* object, const BNPossibleValueSet* other, size_t size);
+ BINARYNINJACOREAPI BNPossibleValueSet BNPossibleValueSetShiftLeft(const BNPossibleValueSet* object, const BNPossibleValueSet* other, size_t size);
+ BINARYNINJACOREAPI BNPossibleValueSet BNPossibleValueSetLogicalShiftRight(const BNPossibleValueSet* object, const BNPossibleValueSet* other, size_t size);
+ BINARYNINJACOREAPI BNPossibleValueSet BNPossibleValueSetArithShiftRight(const BNPossibleValueSet* object, const BNPossibleValueSet* other, size_t size);
+ BINARYNINJACOREAPI BNPossibleValueSet BNPossibleValueSetRotateLeft(const BNPossibleValueSet* object, const BNPossibleValueSet* other, size_t size);
+ BINARYNINJACOREAPI BNPossibleValueSet BNPossibleValueSetRotateRight(const BNPossibleValueSet* object, const BNPossibleValueSet* other, size_t size);
+ BINARYNINJACOREAPI BNPossibleValueSet BNPossibleValueSetNegate(const BNPossibleValueSet* object, size_t size);
+ BINARYNINJACOREAPI BNPossibleValueSet BNPossibleValueSetNot(const BNPossibleValueSet* object, size_t size);
+
#ifdef __cplusplus
}
#endif
diff --git a/function.cpp b/function.cpp
index 6a4564cd..68704e4d 100644
--- a/function.cpp
+++ b/function.cpp
@@ -418,121 +418,6 @@ RegisterValue RegisterValue::FromAPIObject(const BNRegisterValue& value)
}
-PossibleValueSet PossibleValueSet::FromAPIObject(BNPossibleValueSet& value)
-{
- PossibleValueSet result;
- result.state = value.state;
- result.value = value.value;
- result.offset = value.offset;
- result.size = value.size;
- if (value.state == LookupTableValue)
- {
- for (size_t i = 0; i < value.count; i++)
- {
- LookupTableEntry entry;
- entry.fromValues.insert(entry.fromValues.end(), &value.table[i].fromValues[0],
- &value.table[i].fromValues[value.table[i].fromCount]);
- entry.toValue = value.table[i].toValue;
- result.table.push_back(entry);
- }
- }
- else if ((value.state == SignedRangeValue) || (value.state == UnsignedRangeValue))
- {
- for (size_t i = 0; i < value.count; i++)
- result.ranges.push_back(value.ranges[i]);
- }
- else if ((value.state == InSetOfValues) || (value.state == NotInSetOfValues))
- {
- for (size_t i = 0; i < value.count; i++)
- result.valueSet.insert(value.valueSet[i]);
- }
-
- result.count = value.count;
- BNFreePossibleValueSet(&value);
- return result;
-}
-
-
-BNPossibleValueSet PossibleValueSet::ToAPIObject() const
-{
- BNPossibleValueSet result;
- result.state = state;
- result.value = value;
- result.offset = offset;
- result.size = size;
- result.count = 0;
-
- if ((state == SignedRangeValue) || (state == UnsignedRangeValue))
- {
- result.ranges = new BNValueRange[ranges.size()];
- result.count = ranges.size();
- for (size_t i = 0; i < ranges.size(); i++)
- result.ranges[i] = ranges[i];
- }
- else
- {
- result.ranges = nullptr;
- }
-
- if (state == LookupTableValue)
- {
- result.table = new BNLookupTableEntry[table.size()];
- result.count = table.size();
- for (size_t i = 0; i < table.size(); i++)
- {
- result.table[i].fromValues = new int64_t[table[i].fromValues.size()];
- memcpy(result.table[i].fromValues, &table[i].fromValues[0], sizeof(int64_t) * table[i].fromValues.size());
- result.table[i].fromCount = table[i].fromValues.size();
- result.table[i].toValue = table[i].toValue;
- }
- }
- else
- {
- result.table = nullptr;
- }
-
- if ((state == InSetOfValues) || (state == NotInSetOfValues))
- {
- result.valueSet = new int64_t[valueSet.size()];
- result.count = valueSet.size();
- size_t i = 0;
- for (auto j : valueSet)
- result.valueSet[i++] = j;
- }
- else
- {
- result.valueSet = nullptr;
- }
-
- return result;
-}
-
-
-void PossibleValueSet::FreeAPIObject(BNPossibleValueSet* value)
-{
- switch (value->state)
- {
- case SignedRangeValue:
- case UnsignedRangeValue:
- delete[] value->ranges;
- break;
- case LookupTableValue:
- for (size_t i = 0; i < value->count; i ++)
- {
- delete[] value->table[i].fromValues;
- }
- delete[] value->table;
- break;
- case InSetOfValues:
- case NotInSetOfValues:
- delete[] value->valueSet;
- break;
- default:
- break;
- }
-}
-
-
pair<DataBuffer, BNBuiltinType> Function::GetConstantData(BNRegisterValueType state, uint64_t value, size_t size)
{
BNBuiltinType builtin;
diff --git a/possiblevalueset.cpp b/possiblevalueset.cpp
new file mode 100644
index 00000000..93819782
--- /dev/null
+++ b/possiblevalueset.cpp
@@ -0,0 +1,384 @@
+// Copyright (c) 2015-2025 Vector 35 Inc
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include "binaryninjaapi.h"
+#include "ffi.h"
+
+using namespace BinaryNinja;
+using namespace std;
+
+
+PossibleValueSet PossibleValueSet::FromAPIObject(BNPossibleValueSet& value)
+{
+ PossibleValueSet result;
+ result.state = value.state;
+ result.value = value.value;
+ result.offset = value.offset;
+ result.size = value.size;
+ if (value.state == LookupTableValue)
+ {
+ for (size_t i = 0; i < value.count; i++)
+ {
+ LookupTableEntry entry;
+ entry.fromValues.insert(entry.fromValues.end(), &value.table[i].fromValues[0],
+ &value.table[i].fromValues[value.table[i].fromCount]);
+ entry.toValue = value.table[i].toValue;
+ result.table.push_back(entry);
+ }
+ }
+ else if ((value.state == SignedRangeValue) || (value.state == UnsignedRangeValue))
+ {
+ for (size_t i = 0; i < value.count; i++)
+ result.ranges.push_back(value.ranges[i]);
+ }
+ else if ((value.state == InSetOfValues) || (value.state == NotInSetOfValues))
+ {
+ for (size_t i = 0; i < value.count; i++)
+ result.valueSet.insert(value.valueSet[i]);
+ }
+
+ result.count = value.count;
+ BNFreePossibleValueSet(&value);
+ return result;
+}
+
+
+BNPossibleValueSet PossibleValueSet::ToAPIObject() const
+{
+ BNPossibleValueSet result;
+ result.state = state;
+ result.value = value;
+ result.offset = offset;
+ result.size = size;
+ result.count = 0;
+
+ if ((state == SignedRangeValue) || (state == UnsignedRangeValue))
+ {
+ result.ranges = new BNValueRange[ranges.size()];
+ result.count = ranges.size();
+ for (size_t i = 0; i < ranges.size(); i++)
+ result.ranges[i] = ranges[i];
+ }
+ else
+ {
+ result.ranges = nullptr;
+ }
+
+ if (state == LookupTableValue)
+ {
+ result.table = new BNLookupTableEntry[table.size()];
+ result.count = table.size();
+ for (size_t i = 0; i < table.size(); i++)
+ {
+ result.table[i].fromValues = new int64_t[table[i].fromValues.size()];
+ memcpy(result.table[i].fromValues, &table[i].fromValues[0], sizeof(int64_t) * table[i].fromValues.size());
+ result.table[i].fromCount = table[i].fromValues.size();
+ result.table[i].toValue = table[i].toValue;
+ }
+ }
+ else
+ {
+ result.table = nullptr;
+ }
+
+ if ((state == InSetOfValues) || (state == NotInSetOfValues))
+ {
+ result.valueSet = new int64_t[valueSet.size()];
+ result.count = valueSet.size();
+ size_t i = 0;
+ for (auto j : valueSet)
+ result.valueSet[i++] = j;
+ }
+ else
+ {
+ result.valueSet = nullptr;
+ }
+
+ return result;
+}
+
+
+void PossibleValueSet::FreeAPIObject(BNPossibleValueSet* value)
+{
+ switch (value->state)
+ {
+ case SignedRangeValue:
+ case UnsignedRangeValue:
+ delete[] value->ranges;
+ break;
+ case LookupTableValue:
+ for (size_t i = 0; i < value->count; i ++)
+ {
+ delete[] value->table[i].fromValues;
+ }
+ delete[] value->table;
+ break;
+ case InSetOfValues:
+ case NotInSetOfValues:
+ delete[] value->valueSet;
+ break;
+ default:
+ break;
+ }
+}
+
+
+PossibleValueSet PossibleValueSet::Add(const PossibleValueSet& other, size_t size) const
+{
+ BNPossibleValueSet apiObj = ToAPIObject();
+ BNPossibleValueSet otherObj = other.ToAPIObject();
+ BNPossibleValueSet resultObj = BNPossibleValueSetAdd(&apiObj, &otherObj, size);
+ PossibleValueSet::FreeAPIObject(&apiObj);
+ PossibleValueSet::FreeAPIObject(&otherObj);
+ PossibleValueSet result = PossibleValueSet::FromAPIObject(resultObj);
+ BNFreePossibleValueSet(&resultObj);
+ return result;
+}
+
+
+PossibleValueSet PossibleValueSet::Subtract(const PossibleValueSet& other, size_t size) const
+{
+ BNPossibleValueSet apiObj = ToAPIObject();
+ BNPossibleValueSet otherObj = other.ToAPIObject();
+ BNPossibleValueSet resultObj = BNPossibleValueSetSubtract(&apiObj, &otherObj, size);
+ PossibleValueSet::FreeAPIObject(&apiObj);
+ PossibleValueSet::FreeAPIObject(&otherObj);
+ PossibleValueSet result = PossibleValueSet::FromAPIObject(resultObj);
+ BNFreePossibleValueSet(&resultObj);
+ return result;
+}
+
+
+PossibleValueSet PossibleValueSet::Multiply(const PossibleValueSet& other, size_t size) const
+{
+ BNPossibleValueSet apiObj = ToAPIObject();
+ BNPossibleValueSet otherObj = other.ToAPIObject();
+ BNPossibleValueSet resultObj = BNPossibleValueSetMultiply(&apiObj, &otherObj, size);
+ PossibleValueSet::FreeAPIObject(&apiObj);
+ PossibleValueSet::FreeAPIObject(&otherObj);
+ PossibleValueSet result = PossibleValueSet::FromAPIObject(resultObj);
+ BNFreePossibleValueSet(&resultObj);
+ return result;
+}
+
+
+PossibleValueSet PossibleValueSet::SignedDivide(const PossibleValueSet& other, size_t size) const
+{
+ BNPossibleValueSet apiObj = ToAPIObject();
+ BNPossibleValueSet otherObj = other.ToAPIObject();
+ BNPossibleValueSet resultObj = BNPossibleValueSetSignedDivide(&apiObj, &otherObj, size);
+ PossibleValueSet::FreeAPIObject(&apiObj);
+ PossibleValueSet::FreeAPIObject(&otherObj);
+ PossibleValueSet result = PossibleValueSet::FromAPIObject(resultObj);
+ BNFreePossibleValueSet(&resultObj);
+ return result;
+}
+
+
+PossibleValueSet PossibleValueSet::UnsignedDivide(const PossibleValueSet& other, size_t size) const
+{
+ BNPossibleValueSet apiObj = ToAPIObject();
+ BNPossibleValueSet otherObj = other.ToAPIObject();
+ BNPossibleValueSet resultObj = BNPossibleValueSetUnsignedDivide(&apiObj, &otherObj, size);
+ PossibleValueSet::FreeAPIObject(&apiObj);
+ PossibleValueSet::FreeAPIObject(&otherObj);
+ PossibleValueSet result = PossibleValueSet::FromAPIObject(resultObj);
+ BNFreePossibleValueSet(&resultObj);
+ return result;
+}
+
+
+PossibleValueSet PossibleValueSet::SignedMod(const PossibleValueSet& other, size_t size) const
+{
+ BNPossibleValueSet apiObj = ToAPIObject();
+ BNPossibleValueSet otherObj = other.ToAPIObject();
+ BNPossibleValueSet resultObj = BNPossibleValueSetSignedMod(&apiObj, &otherObj, size);
+ PossibleValueSet::FreeAPIObject(&apiObj);
+ PossibleValueSet::FreeAPIObject(&otherObj);
+ PossibleValueSet result = PossibleValueSet::FromAPIObject(resultObj);
+ BNFreePossibleValueSet(&resultObj);
+ return result;
+}
+
+
+PossibleValueSet PossibleValueSet::UnsignedMod(const PossibleValueSet& other, size_t size) const
+{
+ BNPossibleValueSet apiObj = ToAPIObject();
+ BNPossibleValueSet otherObj = other.ToAPIObject();
+ BNPossibleValueSet resultObj = BNPossibleValueSetUnsignedMod(&apiObj, &otherObj, size);
+ PossibleValueSet::FreeAPIObject(&apiObj);
+ PossibleValueSet::FreeAPIObject(&otherObj);
+ PossibleValueSet result = PossibleValueSet::FromAPIObject(resultObj);
+ BNFreePossibleValueSet(&resultObj);
+ return result;
+}
+
+
+PossibleValueSet PossibleValueSet::And(const PossibleValueSet& other, size_t size) const
+{
+ BNPossibleValueSet apiObj = ToAPIObject();
+ BNPossibleValueSet otherObj = other.ToAPIObject();
+ BNPossibleValueSet resultObj = BNPossibleValueSetAnd(&apiObj, &otherObj, size);
+ PossibleValueSet::FreeAPIObject(&apiObj);
+ PossibleValueSet::FreeAPIObject(&otherObj);
+ PossibleValueSet result = PossibleValueSet::FromAPIObject(resultObj);
+ BNFreePossibleValueSet(&resultObj);
+ return result;
+}
+
+
+PossibleValueSet PossibleValueSet::Or(const PossibleValueSet& other, size_t size) const
+{
+ BNPossibleValueSet apiObj = ToAPIObject();
+ BNPossibleValueSet otherObj = other.ToAPIObject();
+ BNPossibleValueSet resultObj = BNPossibleValueSetOr(&apiObj, &otherObj, size);
+ PossibleValueSet::FreeAPIObject(&apiObj);
+ PossibleValueSet::FreeAPIObject(&otherObj);
+ PossibleValueSet result = PossibleValueSet::FromAPIObject(resultObj);
+ BNFreePossibleValueSet(&resultObj);
+ return result;
+}
+
+
+PossibleValueSet PossibleValueSet::Xor(const PossibleValueSet& other, size_t size) const
+{
+ BNPossibleValueSet apiObj = ToAPIObject();
+ BNPossibleValueSet otherObj = other.ToAPIObject();
+ BNPossibleValueSet resultObj = BNPossibleValueSetXor(&apiObj, &otherObj, size);
+ PossibleValueSet::FreeAPIObject(&apiObj);
+ PossibleValueSet::FreeAPIObject(&otherObj);
+ PossibleValueSet result = PossibleValueSet::FromAPIObject(resultObj);
+ BNFreePossibleValueSet(&resultObj);
+ return result;
+}
+
+
+PossibleValueSet PossibleValueSet::ShiftLeft(const PossibleValueSet& other, size_t size) const
+{
+ BNPossibleValueSet apiObj = ToAPIObject();
+ BNPossibleValueSet otherObj = other.ToAPIObject();
+ BNPossibleValueSet resultObj = BNPossibleValueSetShiftLeft(&apiObj, &otherObj, size);
+ PossibleValueSet::FreeAPIObject(&apiObj);
+ PossibleValueSet::FreeAPIObject(&otherObj);
+ PossibleValueSet result = PossibleValueSet::FromAPIObject(resultObj);
+ BNFreePossibleValueSet(&resultObj);
+ return result;
+}
+
+
+PossibleValueSet PossibleValueSet::LogicalShiftRight(const PossibleValueSet& other, size_t size) const
+{
+ BNPossibleValueSet apiObj = ToAPIObject();
+ BNPossibleValueSet otherObj = other.ToAPIObject();
+ BNPossibleValueSet resultObj = BNPossibleValueSetLogicalShiftRight(&apiObj, &otherObj, size);
+ PossibleValueSet::FreeAPIObject(&apiObj);
+ PossibleValueSet::FreeAPIObject(&otherObj);
+ PossibleValueSet result = PossibleValueSet::FromAPIObject(resultObj);
+ BNFreePossibleValueSet(&resultObj);
+ return result;
+}
+
+
+PossibleValueSet PossibleValueSet::ArithShiftRight(const PossibleValueSet& other, size_t size) const
+{
+ BNPossibleValueSet apiObj = ToAPIObject();
+ BNPossibleValueSet otherObj = other.ToAPIObject();
+ BNPossibleValueSet resultObj = BNPossibleValueSetArithShiftRight(&apiObj, &otherObj, size);
+ PossibleValueSet::FreeAPIObject(&apiObj);
+ PossibleValueSet::FreeAPIObject(&otherObj);
+ PossibleValueSet result = PossibleValueSet::FromAPIObject(resultObj);
+ BNFreePossibleValueSet(&resultObj);
+ return result;
+}
+
+
+PossibleValueSet PossibleValueSet::RotateLeft(const PossibleValueSet& other, size_t size) const
+{
+ BNPossibleValueSet apiObj = ToAPIObject();
+ BNPossibleValueSet otherObj = other.ToAPIObject();
+ BNPossibleValueSet resultObj = BNPossibleValueSetRotateLeft(&apiObj, &otherObj, size);
+ PossibleValueSet::FreeAPIObject(&apiObj);
+ PossibleValueSet::FreeAPIObject(&otherObj);
+ PossibleValueSet result = PossibleValueSet::FromAPIObject(resultObj);
+ BNFreePossibleValueSet(&resultObj);
+ return result;
+}
+
+
+PossibleValueSet PossibleValueSet::RotateRight(const PossibleValueSet& other, size_t size) const
+{
+ BNPossibleValueSet apiObj = ToAPIObject();
+ BNPossibleValueSet otherObj = other.ToAPIObject();
+ BNPossibleValueSet resultObj = BNPossibleValueSetRotateRight(&apiObj, &otherObj, size);
+ PossibleValueSet::FreeAPIObject(&apiObj);
+ PossibleValueSet::FreeAPIObject(&otherObj);
+ PossibleValueSet result = PossibleValueSet::FromAPIObject(resultObj);
+ BNFreePossibleValueSet(&resultObj);
+ return result;
+}
+
+
+PossibleValueSet PossibleValueSet::Union(const PossibleValueSet& other, size_t size) const
+{
+ BNPossibleValueSet apiObj = ToAPIObject();
+ BNPossibleValueSet otherObj = other.ToAPIObject();
+ BNPossibleValueSet resultObj = BNPossibleValueSetUnion(&apiObj, &otherObj, size);
+ PossibleValueSet::FreeAPIObject(&apiObj);
+ PossibleValueSet::FreeAPIObject(&otherObj);
+ PossibleValueSet result = PossibleValueSet::FromAPIObject(resultObj);
+ BNFreePossibleValueSet(&resultObj);
+ return result;
+}
+
+
+PossibleValueSet PossibleValueSet::Intersection(const PossibleValueSet& other, size_t size) const
+{
+ BNPossibleValueSet apiObj = ToAPIObject();
+ BNPossibleValueSet otherObj = other.ToAPIObject();
+ BNPossibleValueSet resultObj = BNPossibleValueSetIntersection(&apiObj, &otherObj, size);
+ PossibleValueSet::FreeAPIObject(&apiObj);
+ PossibleValueSet::FreeAPIObject(&otherObj);
+ PossibleValueSet result = PossibleValueSet::FromAPIObject(resultObj);
+ BNFreePossibleValueSet(&resultObj);
+ return result;
+}
+
+
+
+PossibleValueSet PossibleValueSet::Negate(size_t size) const
+{
+ BNPossibleValueSet apiObj = ToAPIObject();
+ BNPossibleValueSet resultObj = BNPossibleValueSetNegate(&apiObj, size);
+ PossibleValueSet::FreeAPIObject(&apiObj);
+ PossibleValueSet result = PossibleValueSet::FromAPIObject(resultObj);
+ BNFreePossibleValueSet(&resultObj);
+ return result;
+}
+
+
+PossibleValueSet PossibleValueSet::Not(size_t size) const
+{
+ BNPossibleValueSet apiObj = ToAPIObject();
+ BNPossibleValueSet resultObj = BNPossibleValueSetNot(&apiObj, size);
+ PossibleValueSet::FreeAPIObject(&apiObj);
+ PossibleValueSet result = PossibleValueSet::FromAPIObject(resultObj);
+ BNFreePossibleValueSet(&resultObj);
+ return result;
+}
diff --git a/python/variable.py b/python/variable.py
index 673f507a..52b079d6 100644
--- a/python/variable.py
+++ b/python/variable.py
@@ -43,6 +43,15 @@ class LookupTableEntry:
def __repr__(self):
return f"[{', '.join([f'{i:#x}' for i in self.from_values])}] -> {self.to_value:#x}"
+ def _to_core_struct(self) -> core.BNLookupTableEntry:
+ result = core.BNLookupTableEntry()
+ result.fromValues = (ctypes.c_longlong * len(self.from_values))()
+ for i in range(len(self.from_values)):
+ result.fromValues[i] = self.from_values[i]
+ result.fromCount = len(self.from_values)
+ result.toValue = self.to_value
+ return result
+
@dataclass(frozen=True)
class RegisterValue:
@@ -258,7 +267,11 @@ class PossibleValueSet:
that a variable can take. It contains methods to instantiate different
value sets such as Constant, Signed/Unsigned Ranges, etc.
"""
- def __init__(self, arch=None, value=None):
+ def __init__(
+ self,
+ arch: Optional['binaryninja.architecture.Architecture'] = None,
+ value: Optional[core.BNPossibleValueSet] = None,
+ ):
if value is None:
self._type = RegisterValueType.UndeterminedValue
return
@@ -361,7 +374,7 @@ class PossibleValueSet:
if self.type == RegisterValueType.InSetOfValues:
return other in self.values
if self.type == RegisterValueType.NotInSetOfValues:
- return not other in self.values
+ return other not in self.values
return NotImplemented
def __eq__(self, other):
@@ -390,6 +403,8 @@ class PossibleValueSet:
return self.values == other.values
elif self.type == RegisterValueType.UndeterminedValue:
return True # UndeterminedValue is always equal to itself
+ elif self.type == RegisterValueType.LookupTableValue:
+ return self.table == other.table and self.mapping == other.mapping
return NotImplemented
def __ne__(self, other):
@@ -407,7 +422,7 @@ class PossibleValueSet:
elif self.type == RegisterValueType.ConstantPointerValue:
result.value = self.value
elif self.type == RegisterValueType.StackFrameOffset:
- result.offset = self.value
+ result.offset = self.offset
elif self.type & RegisterValueType.ConstantDataValue == RegisterValueType.ConstantDataValue:
result.value = self.value
result.size = self.size
@@ -438,14 +453,10 @@ class PossibleValueSet:
result.ranges[i] = value_range
result.count = self.count
elif self.type == RegisterValueType.LookupTableValue:
- result.table = []
- result.mapping = {}
+ result.table = (core.BNLookupTableEntry * self.count)()
+ result.mapping = self.mapping
for i in range(self.count):
- from_list = []
- for j in range(0, len(self.table[i].from_values)):
- from_list.append(self.table[i].from_values[j])
- result.mapping[self.table[i].from_values[j]] = result.table[i].to_value
- result.table.append(LookupTableEntry(from_list, result.table[i].to_value))
+ result.table[i] = self.table[i]._to_core_struct()
result.count = self.count
elif (self.type == RegisterValueType.InSetOfValues) or (self.type == RegisterValueType.NotInSetOfValues):
values = (ctypes.c_longlong * self.count)()
@@ -590,7 +601,7 @@ class PossibleValueSet:
return result
@staticmethod
- def in_set_of_values(values: Union[List[int], Set[int]]) -> 'PossibleValueSet':
+ def in_set_of_values(values: List[int]) -> 'PossibleValueSet':
"""
Create a PossibleValueSet object for a value in a set of values.
@@ -604,7 +615,7 @@ class PossibleValueSet:
return result
@staticmethod
- def not_in_set_of_values(values) -> 'PossibleValueSet':
+ def not_in_set_of_values(values: List[int]) -> 'PossibleValueSet':
"""
Create a PossibleValueSet object for a value NOT in a set of values.
@@ -618,7 +629,7 @@ class PossibleValueSet:
return result
@staticmethod
- def lookup_table_value(lookup_table, mapping) -> 'PossibleValueSet':
+ def lookup_table_value(lookup_table: List[LookupTableEntry], mapping: Dict[int, int]) -> 'PossibleValueSet':
"""
Create a PossibleValueSet object for a value which is a member of a
lookup table.
@@ -631,8 +642,142 @@ class PossibleValueSet:
result._type = RegisterValueType.LookupTableValue
result._table = lookup_table
result._mapping = mapping
+ result._count = len(lookup_table)
return result
+ def union(self, other: "PossibleValueSet", size: int) -> "PossibleValueSet":
+ """Compute the union of two PossibleValueSets."""
+ res = core.BNPossibleValueSetUnion(ctypes.pointer(self._to_core_struct()), ctypes.pointer(other._to_core_struct()), size)
+ pvs = PossibleValueSet(value=res)
+ core.BNFreePossibleValueSet(ctypes.pointer(res))
+ return pvs
+
+ def intersection(self, other: "PossibleValueSet", size: int) -> "PossibleValueSet":
+ """Compute the intersection of two PossibleValueSets."""
+ res = core.BNPossibleValueSetIntersection(ctypes.pointer(self._to_core_struct()), ctypes.pointer(other._to_core_struct()), size)
+ pvs = PossibleValueSet(value=res)
+ core.BNFreePossibleValueSet(ctypes.pointer(res))
+ return pvs
+
+ def add(self, other: "PossibleValueSet", size: int) -> "PossibleValueSet":
+ """Add two PossibleValueSets."""
+ res = core.BNPossibleValueSetAdd(ctypes.pointer(self._to_core_struct()), ctypes.pointer(other._to_core_struct()), size)
+ pvs = PossibleValueSet(value=res)
+ core.BNFreePossibleValueSet(ctypes.pointer(res))
+ return pvs
+
+ def subtract(self, other: "PossibleValueSet", size: int) -> "PossibleValueSet":
+ """Subtract two PossibleValueSets."""
+ res = core.BNPossibleValueSetSubtract(ctypes.pointer(self._to_core_struct()), ctypes.pointer(other._to_core_struct()), size)
+ pvs = PossibleValueSet(value=res)
+ core.BNFreePossibleValueSet(ctypes.pointer(res))
+ return pvs
+
+ def multiply(self, other: "PossibleValueSet", size: int) -> "PossibleValueSet":
+ """Multiply two PossibleValueSets."""
+ res = core.BNPossibleValueSetMultiply(ctypes.pointer(self._to_core_struct()), ctypes.pointer(other._to_core_struct()), size)
+ pvs = PossibleValueSet(value=res)
+ core.BNFreePossibleValueSet(ctypes.pointer(res))
+ return pvs
+
+ def signed_divide(self, other: "PossibleValueSet", size: int) -> "PossibleValueSet":
+ """Perform signed division of two PossibleValueSets."""
+ res = core.BNPossibleValueSetSignedDivide(ctypes.pointer(self._to_core_struct()), ctypes.pointer(other._to_core_struct()), size)
+ pvs = PossibleValueSet(value=res)
+ core.BNFreePossibleValueSet(ctypes.pointer(res))
+ return pvs
+
+ def unsigned_divide(self, other: "PossibleValueSet", size: int) -> "PossibleValueSet":
+ """Perform unsigned division of two PossibleValueSets."""
+ res = core.BNPossibleValueSetUnsignedDivide(ctypes.pointer(self._to_core_struct()), ctypes.pointer(other._to_core_struct()), size)
+ pvs = PossibleValueSet(value=res)
+ core.BNFreePossibleValueSet(ctypes.pointer(res))
+ return pvs
+
+ def signed_mod(self, other: "PossibleValueSet", size: int) -> "PossibleValueSet":
+ """Perform signed modulo of two PossibleValueSets."""
+ res = core.BNPossibleValueSetSignedMod(ctypes.pointer(self._to_core_struct()), ctypes.pointer(other._to_core_struct()), size)
+ pvs = PossibleValueSet(value=res)
+ core.BNFreePossibleValueSet(ctypes.pointer(res))
+ return pvs
+
+ def unsigned_mod(self, other: "PossibleValueSet", size: int) -> "PossibleValueSet":
+ """Perform unsigned modulo of two PossibleValueSets."""
+ res = core.BNPossibleValueSetUnsignedMod(ctypes.pointer(self._to_core_struct()), ctypes.pointer(other._to_core_struct()), size)
+ pvs = PossibleValueSet(value=res)
+ core.BNFreePossibleValueSet(ctypes.pointer(res))
+ return pvs
+
+ def and_(self, other: "PossibleValueSet", size: int) -> "PossibleValueSet":
+ """Perform bitwise AND of two PossibleValueSets."""
+ res = core.BNPossibleValueSetAnd(ctypes.pointer(self._to_core_struct()), ctypes.pointer(other._to_core_struct()), size)
+ pvs = PossibleValueSet(value=res)
+ core.BNFreePossibleValueSet(ctypes.pointer(res))
+ return pvs
+
+ def or_(self, other: "PossibleValueSet", size: int) -> "PossibleValueSet":
+ """Perform bitwise OR of two PossibleValueSets."""
+ res = core.BNPossibleValueSetOr(ctypes.pointer(self._to_core_struct()), ctypes.pointer(other._to_core_struct()), size)
+ pvs = PossibleValueSet(value=res)
+ core.BNFreePossibleValueSet(ctypes.pointer(res))
+ return pvs
+
+ def xor(self, other: "PossibleValueSet", size: int) -> "PossibleValueSet":
+ """Perform bitwise XOR of two PossibleValueSets."""
+ res = core.BNPossibleValueSetXor(ctypes.pointer(self._to_core_struct()), ctypes.pointer(other._to_core_struct()), size)
+ pvs = PossibleValueSet(value=res)
+ core.BNFreePossibleValueSet(ctypes.pointer(res))
+ return pvs
+
+ def shift_left(self, other: "PossibleValueSet", size: int) -> "PossibleValueSet":
+ """Perform left shift of two PossibleValueSets."""
+ res = core.BNPossibleValueSetShiftLeft(ctypes.pointer(self._to_core_struct()), ctypes.pointer(other._to_core_struct()), size)
+ pvs = PossibleValueSet(value=res)
+ core.BNFreePossibleValueSet(ctypes.pointer(res))
+ return pvs
+
+ def logical_shift_right(self, other: "PossibleValueSet", size: int) -> "PossibleValueSet":
+ """Perform logical right shift of two PossibleValueSets."""
+ res = core.BNPossibleValueSetLogicalShiftRight(ctypes.pointer(self._to_core_struct()), ctypes.pointer(other._to_core_struct()), size)
+ pvs = PossibleValueSet(value=res)
+ core.BNFreePossibleValueSet(ctypes.pointer(res))
+ return pvs
+
+ def arith_shift_right(self, other: "PossibleValueSet", size: int) -> "PossibleValueSet":
+ """Perform arithmetic right shift of two PossibleValueSets."""
+ res = core.BNPossibleValueSetArithShiftRight(ctypes.pointer(self._to_core_struct()), ctypes.pointer(other._to_core_struct()), size)
+ pvs = PossibleValueSet(value=res)
+ core.BNFreePossibleValueSet(ctypes.pointer(res))
+ return pvs
+
+ def rotate_left(self, other: "PossibleValueSet", size: int) -> "PossibleValueSet":
+ """Perform left rotation of two PossibleValueSets."""
+ res = core.BNPossibleValueSetRotateLeft(ctypes.pointer(self._to_core_struct()), ctypes.pointer(other._to_core_struct()), size)
+ pvs = PossibleValueSet(value=res)
+ core.BNFreePossibleValueSet(ctypes.pointer(res))
+ return pvs
+
+ def rotate_right(self, other: "PossibleValueSet", size: int) -> "PossibleValueSet":
+ """Perform right rotation of two PossibleValueSets."""
+ res = core.BNPossibleValueSetRotateRight(ctypes.pointer(self._to_core_struct()), ctypes.pointer(other._to_core_struct()), size)
+ pvs = PossibleValueSet(value=res)
+ core.BNFreePossibleValueSet(ctypes.pointer(res))
+ return pvs
+
+ def negate(self, size: int) -> "PossibleValueSet":
+ """Negate a PossibleValueSet."""
+ res = core.BNPossibleValueSetNegate(ctypes.pointer(self._to_core_struct()), size)
+ pvs = PossibleValueSet(value=res)
+ core.BNFreePossibleValueSet(ctypes.pointer(res))
+ return pvs
+
+ def not_(self, size: int) -> "PossibleValueSet":
+ """Perform bitwise NOT of a PossibleValueSet."""
+ res = core.BNPossibleValueSetNot(ctypes.pointer(self._to_core_struct()), size)
+ pvs = PossibleValueSet(value=res)
+ core.BNFreePossibleValueSet(ctypes.pointer(res))
+ return pvs
+
@dataclass(frozen=True)
class StackVariableReference:
diff --git a/rust/src/variable.rs b/rust/src/variable.rs
index fe833f97..f9384b5d 100644
--- a/rust/src/variable.rs
+++ b/rust/src/variable.rs
@@ -7,14 +7,19 @@ use crate::rc::{CoreArrayProvider, CoreArrayProviderInner, Ref};
use crate::string::{raw_to_string, BnString};
use crate::types::Type;
use binaryninjacore_sys::{
- BNDataVariable, BNDataVariableAndName, BNFreeDataVariableAndName, BNFreeDataVariables,
- BNFreeDataVariablesAndName, BNFreeILInstructionList, BNFreeIndirectBranchList,
- BNFreeMergedVariableList, BNFreePossibleValueSet, BNFreeStackVariableReferenceList,
- BNFreeUserVariableValues, BNFreeVariableList, BNFreeVariableNameAndTypeList,
- BNFromVariableIdentifier, BNIndirectBranchInfo, BNLookupTableEntry, BNMergedVariable,
- BNPossibleValueSet, BNRegisterValue, BNRegisterValueType, BNStackVariableReference,
- BNToVariableIdentifier, BNTypeWithConfidence, BNUserVariableValue, BNValueRange, BNVariable,
- BNVariableNameAndType, BNVariableSourceType,
+ BNDataVariable, BNDataVariableAndName, BNFreeDataVariables, BNFreeDataVariablesAndName,
+ BNFreeILInstructionList, BNFreeMergedVariableList, BNFreePossibleValueSet,
+ BNFreeStackVariableReferenceList, BNFreeUserVariableValues, BNFreeVariableList,
+ BNFreeVariableNameAndTypeList, BNFromVariableIdentifier, BNLookupTableEntry, BNMergedVariable,
+ BNPossibleValueSet, BNPossibleValueSetAdd, BNPossibleValueSetAnd,
+ BNPossibleValueSetArithShiftRight, BNPossibleValueSetIntersection,
+ BNPossibleValueSetLogicalShiftRight, BNPossibleValueSetMultiply, BNPossibleValueSetNegate,
+ BNPossibleValueSetNot, BNPossibleValueSetOr, BNPossibleValueSetRotateLeft,
+ BNPossibleValueSetRotateRight, BNPossibleValueSetShiftLeft, BNPossibleValueSetSignedDivide,
+ BNPossibleValueSetSignedMod, BNPossibleValueSetSubtract, BNPossibleValueSetUnion,
+ BNPossibleValueSetUnsignedDivide, BNPossibleValueSetUnsignedMod, BNPossibleValueSetXor,
+ BNRegisterValue, BNRegisterValueType, BNStackVariableReference, BNToVariableIdentifier,
+ BNUserVariableValue, BNValueRange, BNVariable, BNVariableNameAndType, BNVariableSourceType,
};
use std::collections::HashSet;
@@ -926,4 +931,190 @@ impl PossibleValueSet {
}
}
}
+
+ pub fn add(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
+ let raw_value = PossibleValueSet::into_rust_raw(self.clone());
+ let raw_other = PossibleValueSet::into_rust_raw(other.clone());
+ let result;
+ unsafe { result = BNPossibleValueSetAdd(&raw_value, &raw_other, size) }
+ PossibleValueSet::free_rust_raw(raw_value);
+ PossibleValueSet::free_rust_raw(raw_other);
+ PossibleValueSet::from_owned_core_raw(result)
+ }
+
+ pub fn subtract(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
+ let raw_value = PossibleValueSet::into_rust_raw(self.clone());
+ let raw_other = PossibleValueSet::into_rust_raw(other.clone());
+ let result;
+ unsafe { result = BNPossibleValueSetSubtract(&raw_value, &raw_other, size) }
+ PossibleValueSet::free_rust_raw(raw_value);
+ PossibleValueSet::free_rust_raw(raw_other);
+ PossibleValueSet::from_owned_core_raw(result)
+ }
+
+ pub fn multiply(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
+ let raw_value = PossibleValueSet::into_rust_raw(self.clone());
+ let raw_other = PossibleValueSet::into_rust_raw(other.clone());
+ let result;
+ unsafe { result = BNPossibleValueSetMultiply(&raw_value, &raw_other, size) }
+ PossibleValueSet::free_rust_raw(raw_value);
+ PossibleValueSet::free_rust_raw(raw_other);
+ PossibleValueSet::from_owned_core_raw(result)
+ }
+
+ pub fn signed_divide(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
+ let raw_value = PossibleValueSet::into_rust_raw(self.clone());
+ let raw_other = PossibleValueSet::into_rust_raw(other.clone());
+ let result;
+ unsafe { result = BNPossibleValueSetSignedDivide(&raw_value, &raw_other, size) }
+ PossibleValueSet::free_rust_raw(raw_value);
+ PossibleValueSet::free_rust_raw(raw_other);
+ PossibleValueSet::from_owned_core_raw(result)
+ }
+
+ pub fn unsigned_divide(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
+ let raw_value = PossibleValueSet::into_rust_raw(self.clone());
+ let raw_other = PossibleValueSet::into_rust_raw(other.clone());
+ let result;
+ unsafe { result = BNPossibleValueSetUnsignedDivide(&raw_value, &raw_other, size) }
+ PossibleValueSet::free_rust_raw(raw_value);
+ PossibleValueSet::free_rust_raw(raw_other);
+ PossibleValueSet::from_owned_core_raw(result)
+ }
+
+ pub fn signed_mod(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
+ let raw_value = PossibleValueSet::into_rust_raw(self.clone());
+ let raw_other = PossibleValueSet::into_rust_raw(other.clone());
+ let result;
+ unsafe { result = BNPossibleValueSetSignedMod(&raw_value, &raw_other, size) }
+ PossibleValueSet::free_rust_raw(raw_value);
+ PossibleValueSet::free_rust_raw(raw_other);
+ PossibleValueSet::from_owned_core_raw(result)
+ }
+
+ pub fn unsigned_mod(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
+ let raw_value = PossibleValueSet::into_rust_raw(self.clone());
+ let raw_other = PossibleValueSet::into_rust_raw(other.clone());
+ let result;
+ unsafe { result = BNPossibleValueSetUnsignedMod(&raw_value, &raw_other, size) }
+ PossibleValueSet::free_rust_raw(raw_value);
+ PossibleValueSet::free_rust_raw(raw_other);
+ PossibleValueSet::from_owned_core_raw(result)
+ }
+
+ pub fn and(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
+ let raw_value = PossibleValueSet::into_rust_raw(self.clone());
+ let raw_other = PossibleValueSet::into_rust_raw(other.clone());
+ let result;
+ unsafe { result = BNPossibleValueSetAnd(&raw_value, &raw_other, size) }
+ PossibleValueSet::free_rust_raw(raw_value);
+ PossibleValueSet::free_rust_raw(raw_other);
+ PossibleValueSet::from_owned_core_raw(result)
+ }
+
+ pub fn or(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
+ let raw_value = PossibleValueSet::into_rust_raw(self.clone());
+ let raw_other = PossibleValueSet::into_rust_raw(other.clone());
+ let result;
+ unsafe { result = BNPossibleValueSetOr(&raw_value, &raw_other, size) }
+ PossibleValueSet::free_rust_raw(raw_value);
+ PossibleValueSet::free_rust_raw(raw_other);
+ PossibleValueSet::from_owned_core_raw(result)
+ }
+
+ pub fn xor(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
+ let raw_value = PossibleValueSet::into_rust_raw(self.clone());
+ let raw_other = PossibleValueSet::into_rust_raw(other.clone());
+ let result;
+ unsafe { result = BNPossibleValueSetXor(&raw_value, &raw_other, size) }
+ PossibleValueSet::free_rust_raw(raw_value);
+ PossibleValueSet::free_rust_raw(raw_other);
+ PossibleValueSet::from_owned_core_raw(result)
+ }
+
+ pub fn shift_left(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
+ let raw_value = PossibleValueSet::into_rust_raw(self.clone());
+ let raw_other = PossibleValueSet::into_rust_raw(other.clone());
+ let result;
+ unsafe { result = BNPossibleValueSetShiftLeft(&raw_value, &raw_other, size) }
+ PossibleValueSet::free_rust_raw(raw_value);
+ PossibleValueSet::free_rust_raw(raw_other);
+ PossibleValueSet::from_owned_core_raw(result)
+ }
+
+ pub fn logical_shift_right(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
+ let raw_value = PossibleValueSet::into_rust_raw(self.clone());
+ let raw_other = PossibleValueSet::into_rust_raw(other.clone());
+ let result;
+ unsafe { result = BNPossibleValueSetLogicalShiftRight(&raw_value, &raw_other, size) }
+ PossibleValueSet::free_rust_raw(raw_value);
+ PossibleValueSet::free_rust_raw(raw_other);
+ PossibleValueSet::from_owned_core_raw(result)
+ }
+
+ pub fn arith_shift_right(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
+ let raw_value = PossibleValueSet::into_rust_raw(self.clone());
+ let raw_other = PossibleValueSet::into_rust_raw(other.clone());
+ let result;
+ unsafe { result = BNPossibleValueSetArithShiftRight(&raw_value, &raw_other, size) }
+ PossibleValueSet::free_rust_raw(raw_value);
+ PossibleValueSet::free_rust_raw(raw_other);
+ PossibleValueSet::from_owned_core_raw(result)
+ }
+
+ pub fn rotate_left(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
+ let raw_value = PossibleValueSet::into_rust_raw(self.clone());
+ let raw_other = PossibleValueSet::into_rust_raw(other.clone());
+ let result;
+ unsafe { result = BNPossibleValueSetRotateLeft(&raw_value, &raw_other, size) }
+ PossibleValueSet::free_rust_raw(raw_value);
+ PossibleValueSet::free_rust_raw(raw_other);
+ PossibleValueSet::from_owned_core_raw(result)
+ }
+
+ pub fn rotate_right(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
+ let raw_value = PossibleValueSet::into_rust_raw(self.clone());
+ let raw_other = PossibleValueSet::into_rust_raw(other.clone());
+ let result;
+ unsafe { result = BNPossibleValueSetRotateRight(&raw_value, &raw_other, size) }
+ PossibleValueSet::free_rust_raw(raw_value);
+ PossibleValueSet::free_rust_raw(raw_other);
+ PossibleValueSet::from_owned_core_raw(result)
+ }
+
+ pub fn union(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
+ let raw_value = PossibleValueSet::into_rust_raw(self.clone());
+ let raw_other = PossibleValueSet::into_rust_raw(other.clone());
+ let result;
+ unsafe { result = BNPossibleValueSetUnion(&raw_value, &raw_other, size) }
+ PossibleValueSet::free_rust_raw(raw_value);
+ PossibleValueSet::free_rust_raw(raw_other);
+ PossibleValueSet::from_owned_core_raw(result)
+ }
+
+ pub fn intersection(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
+ let raw_value = PossibleValueSet::into_rust_raw(self.clone());
+ let raw_other = PossibleValueSet::into_rust_raw(other.clone());
+ let result;
+ unsafe { result = BNPossibleValueSetIntersection(&raw_value, &raw_other, size) }
+ PossibleValueSet::free_rust_raw(raw_value);
+ PossibleValueSet::free_rust_raw(raw_other);
+ PossibleValueSet::from_owned_core_raw(result)
+ }
+
+ pub fn negate(&self, size: usize) -> PossibleValueSet {
+ let raw_value = PossibleValueSet::into_rust_raw(self.clone());
+ let result;
+ unsafe { result = BNPossibleValueSetNegate(&raw_value, size) }
+ PossibleValueSet::free_rust_raw(raw_value);
+ PossibleValueSet::from_owned_core_raw(result)
+ }
+
+ pub fn not(&self, size: usize) -> PossibleValueSet {
+ let raw_value = PossibleValueSet::into_rust_raw(self.clone());
+ let result;
+ unsafe { result = BNPossibleValueSetNot(&raw_value, size) }
+ PossibleValueSet::free_rust_raw(raw_value);
+ PossibleValueSet::from_owned_core_raw(result)
+ }
}