X-Git-Url: https://git.tcpdump.org/libpcap/blobdiff_plain/0dff3376458819f2dc2e2cf934d68fcdb0b80df6..b599421837f171a69fbf2637f8b84a2b7dbb331c:/optimize.c?ds=inline diff --git a/optimize.c b/optimize.c index 77605697..feaf2017 100644 --- a/optimize.c +++ b/optimize.c @@ -20,10 +20,6 @@ * * Optimization module for tcpdump intermediate representation. */ -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.91 2008-01-02 04:16:46 guy Exp $ (LBL)"; -#endif #ifdef HAVE_CONFIG_H #include "config.h" @@ -579,6 +575,10 @@ vstore(struct stmt *s, int *valp, int newval, int alter) *valp = newval; } +/* + * Do constant-folding on binary operators. + * (Unary operators are handled elsewhere.) + */ static void fold_op(struct stmt *s, int v0, int v1) { @@ -606,6 +606,12 @@ fold_op(struct stmt *s, int v0, int v1) a /= b; break; + case BPF_MOD: + if (b == 0) + bpf_error("modulus by zero"); + a %= b; + break; + case BPF_AND: a &= b; break; @@ -614,6 +620,10 @@ fold_op(struct stmt *s, int v0, int v1) a |= b; break; + case BPF_XOR: + a ^= b; + break; + case BPF_LSH: a <<= b; break; @@ -974,8 +984,10 @@ opt_stmt(struct stmt *s, int val[], int alter) case BPF_ALU|BPF_SUB|BPF_K: case BPF_ALU|BPF_MUL|BPF_K: case BPF_ALU|BPF_DIV|BPF_K: + case BPF_ALU|BPF_MOD|BPF_K: case BPF_ALU|BPF_AND|BPF_K: case BPF_ALU|BPF_OR|BPF_K: + case BPF_ALU|BPF_XOR|BPF_K: case BPF_ALU|BPF_LSH|BPF_K: case BPF_ALU|BPF_RSH|BPF_K: op = BPF_OP(s->code); @@ -986,7 +998,7 @@ opt_stmt(struct stmt *s, int val[], int alter) * fixup the generated math code */ if (op == BPF_ADD || op == BPF_LSH || op == BPF_RSH || - op == BPF_OR) { + op == BPF_OR || op == BPF_XOR) { s->code = NOP; break; } @@ -1009,8 +1021,10 @@ opt_stmt(struct stmt *s, int val[], int alter) case BPF_ALU|BPF_SUB|BPF_X: case BPF_ALU|BPF_MUL|BPF_X: case BPF_ALU|BPF_DIV|BPF_X: + case BPF_ALU|BPF_MOD|BPF_X: case BPF_ALU|BPF_AND|BPF_X: case BPF_ALU|BPF_OR|BPF_X: + case BPF_ALU|BPF_XOR|BPF_X: case BPF_ALU|BPF_LSH|BPF_X: case BPF_ALU|BPF_RSH|BPF_X: op = BPF_OP(s->code); @@ -1037,12 +1051,12 @@ opt_stmt(struct stmt *s, int val[], int alter) */ if (alter && vmap[val[A_ATOM]].is_const && vmap[val[A_ATOM]].const_val == 0) { - if (op == BPF_ADD || op == BPF_OR) { + if (op == BPF_ADD || op == BPF_OR || op == BPF_XOR) { s->code = BPF_MISC|BPF_TXA; vstore(s, &val[A_ATOM], val[X_ATOM], alter); break; } - else if (op == BPF_MUL || op == BPF_DIV || + else if (op == BPF_MUL || op == BPF_DIV || op == BPF_MOD || op == BPF_AND || op == BPF_LSH || op == BPF_RSH) { s->code = BPF_LD|BPF_IMM; s->k = 0;