]> The Tcpdump Group git mirrors - libpcap/blobdiff - optimize.c
updates to CHANGES for libpcap 1.7
[libpcap] / optimize.c
index 7760569785e455a86fa8c1fc34e5ec7e8f367961..feaf2017213ae09ed3a01a574b3865951cb59dac 100644 (file)
  *
  *  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;