diff options
| author | Josh Ferrell <josh@vector35.com> | 2025-12-15 15:09:53 -0500 |
|---|---|---|
| committer | Josh Ferrell <josh@vector35.com> | 2025-12-15 23:55:53 -0500 |
| commit | 9bb8792f6be698ed9f2bd6e1dc555bfd91709044 (patch) | |
| tree | 22b6c523ea86cafe31356eeea0706d889d480121 /possiblevalueset.cpp | |
| parent | 95b849d05d05ae9e55eb839508536d5af314d331 (diff) | |
Add PossibleValueSet operation APIs and fixes to PVS python API
Diffstat (limited to 'possiblevalueset.cpp')
| -rw-r--r-- | possiblevalueset.cpp | 384 |
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; +} |
