| 266 | } |
| 267 | |
| 268 | static void |
| 269 | eval_sub(struct bpf_reg_val *rd, const struct bpf_reg_val *rs, uint64_t msk) |
| 270 | { |
| 271 | struct bpf_reg_val rv; |
| 272 | |
| 273 | rv.u.min = (rd->u.min - rs->u.max) & msk; |
| 274 | rv.u.max = (rd->u.max - rs->u.min) & msk; |
| 275 | rv.s.min = (rd->s.min - rs->s.max) & msk; |
| 276 | rv.s.max = (rd->s.max - rs->s.min) & msk; |
| 277 | |
| 278 | /* |
| 279 | * if at least one of the operands is not constant, |
| 280 | * then check for overflow |
| 281 | */ |
| 282 | if ((rd->u.min != rd->u.max || rs->u.min != rs->u.max) && |
| 283 | (rv.u.min > rd->u.min || rv.u.max > rd->u.max)) |
| 284 | eval_umax_bound(&rv, msk); |
| 285 | |
| 286 | if ((rd->s.min != rd->s.max || rs->s.min != rs->s.max) && |
| 287 | (((rs->s.min < 0 && rv.s.min < rd->s.min) || |
| 288 | rv.s.min > rd->s.min) || |
| 289 | ((rs->s.max < 0 && rv.s.max < rd->s.max) || |
| 290 | rv.s.max > rd->s.max))) |
| 291 | eval_smax_bound(&rv, msk); |
| 292 | |
| 293 | rd->s = rv.s; |
| 294 | rd->u = rv.u; |
| 295 | } |
| 296 | |
| 297 | static void |
| 298 | eval_lsh(struct bpf_reg_val *rd, const struct bpf_reg_val *rs, size_t opsz, |
no test coverage detected