Skip to content

Commit f86ba52

Browse files
author
Alan Jowett
committed
PR feedback
Signed-off-by: Alan Jowett <[email protected]>
1 parent 5f381d8 commit f86ba52

File tree

1 file changed

+30
-25
lines changed

1 file changed

+30
-25
lines changed

src/crab/split_dbm.cpp

+30-25
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,32 @@ void SplitDBM::apply(arith_binop_t op, variable_t x, variable_t y, variable_t z,
998998
normalize();
999999
}
10001000

1001+
// As defined in the BPF ISA specification, the immediate value of an unsigned modulo and division is treated
1002+
// differently depending on the width:
1003+
// * for 32 bit, as a 32-bit unsigned integer
1004+
// * for 64 bit, as a 32-bit (not 64 bit) signed integer
1005+
number_t read_imm_for_udiv_or_umod(const number_t& imm, int width) {
1006+
assert(width == 32 || width == 64);
1007+
if (width == 32) {
1008+
return number_t{imm.cast_to<uint32_t>()};
1009+
} else {
1010+
return number_t{imm.cast_to<int32_t>()};
1011+
}
1012+
}
1013+
1014+
// As defined in the BPF ISA specification, the immediate value of a signed modulo and division is treated
1015+
// differently depending on the width:
1016+
// * for 32 bit, as a 32-bit signed integer
1017+
// * for 64 bit, as a 64-bit signed integer
1018+
number_t read_imm_for_sdiv_or_smod(const number_t& imm, int width) {
1019+
assert(width == 32 || width == 64);
1020+
if (width == 32) {
1021+
return number_t{imm.cast_to<int32_t>()};
1022+
} else {
1023+
return number_t{imm.cast_to<int64_t>()};
1024+
}
1025+
}
1026+
10011027
void SplitDBM::apply(arith_binop_t op, variable_t x, variable_t y, const number_t& k, int finite_width) {
10021028
CrabStats::count("SplitDBM.count.apply");
10031029
ScopedCrabStats __st__("SplitDBM.apply");
@@ -1007,31 +1033,10 @@ void SplitDBM::apply(arith_binop_t op, variable_t x, variable_t y, const number_
10071033
case arith_binop_t::SUB: assign(x, linear_expression_t(y).subtract(k)); break;
10081034
case arith_binop_t::MUL: assign(x, linear_expression_t(k, y)); break;
10091035
// For the rest of operations, we fall back on intervals.
1010-
case arith_binop_t::SDIV: set(x, get_interval(y, finite_width).SDiv(interval_t(k))); break;
1011-
case arith_binop_t::UDIV: {
1012-
if (finite_width == 32) {
1013-
// As defined in the BPF ISA specification, for 32 bit unsigned division the immediate value is
1014-
// treated as a 32-bit unsigned integer, so we need to cast it to uint32_t.
1015-
set(x, get_interval(y, finite_width).UDiv(interval_t(k.cast_to<uint32_t>())));
1016-
} else {
1017-
// As defined in the BPF ISA specification, for 64 bit unsigned division the immediate value is
1018-
// treated as a 32-bit signed integer, so we need to cast it to int32_t.
1019-
set(x, get_interval(y, finite_width).UDiv(interval_t(k.cast_to<int32_t>())));
1020-
}
1021-
break;
1022-
}
1023-
case arith_binop_t::SREM: set(x, get_interval(y, finite_width).SRem(interval_t(k))); break;
1024-
case arith_binop_t::UREM:
1025-
if (finite_width == 32) {
1026-
// As defined in the BPF ISA specification, for 32 bit unsigned modulo the immediate value is
1027-
// treated as a 32-bit unsigned integer, so we need to cast it to uint32_t.
1028-
set(x, get_interval(y, finite_width).URem(interval_t(k.cast_to<uint32_t>())));
1029-
} else {
1030-
// As defined in the BPF ISA specification, for 64 bit unsigned modulo the immediate value is
1031-
// treated as a 32-bit signed integer, so we need to cast it to int32_t.
1032-
set(x, get_interval(y, finite_width).URem(interval_t(k.cast_to<int32_t>())));
1033-
}
1034-
break;
1036+
case arith_binop_t::SDIV: set(x, get_interval(y, finite_width).SDiv(interval_t(read_imm_for_sdiv_or_smod(k, finite_width)))); break;
1037+
case arith_binop_t::UDIV: set(x, get_interval(y, finite_width).UDiv(interval_t(read_imm_for_udiv_or_umod(k, finite_width)))); break;
1038+
case arith_binop_t::SREM: set(x, get_interval(y, finite_width).SRem(interval_t(read_imm_for_sdiv_or_smod(k, finite_width)))); break;
1039+
case arith_binop_t::UREM: set(x, get_interval(y, finite_width).URem(interval_t(read_imm_for_udiv_or_umod(k, finite_width)))); break;
10351040
default: CRAB_ERROR("DBM: unreachable");
10361041
}
10371042
normalize();

0 commit comments

Comments
 (0)