summaryrefslogtreecommitdiff
path: root/possiblevalueset.cpp
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 /possiblevalueset.cpp
parent95b849d05d05ae9e55eb839508536d5af314d331 (diff)
Add PossibleValueSet operation APIs and fixes to PVS python API
Diffstat (limited to 'possiblevalueset.cpp')
-rw-r--r--possiblevalueset.cpp384
1 files changed, 384 insertions, 0 deletions
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;
+}