]> granicus.if.org Git - yasm/commitdiff
Add _copy() constructor.
authorPeter Johnson <peter@tortall.net>
Mon, 15 Oct 2001 07:04:01 +0000 (07:04 -0000)
committerPeter Johnson <peter@tortall.net>
Mon, 15 Oct 2001 07:04:01 +0000 (07:04 -0000)
Add expr_expand_equ().

svn path=/trunk/yasm/; revision=284

16 files changed:
libyasm/expr.c
libyasm/expr.h
libyasm/floatnum.c
libyasm/floatnum.h
libyasm/intnum.c
libyasm/intnum.h
modules/arch/x86/expr.c
modules/arch/x86/x86expr.c
src/arch/x86/expr.c
src/arch/x86/x86expr.c
src/expr.c
src/expr.h
src/floatnum.c
src/floatnum.h
src/intnum.c
src/intnum.h

index f4ac1394899ff0ef61ad5e95d21c1e22fd874bf1..49521ee413ee6268d8657dd9b5f789eff945deac 100644 (file)
@@ -83,8 +83,8 @@ struct expr {
 
 static int expr_traverse_nodes_post(expr *e, void *d,
                                    int (*func) (expr *e, void *d));
-static int expr_traverse_leaves_in(const expr *e, void *d,
-                                  int (*func) (const ExprItem *ei, void *d));
+static int expr_traverse_leaves_in(expr *e, void *d,
+                                  int (*func) (ExprItem *ei, void *d));
 
 /* allocate a new expression node, with children as defined.
  * If it's a unary operator, put the element on the right */
@@ -162,6 +162,51 @@ ExprReg(unsigned char reg, unsigned char size)
     return e;
 }
 
+static void
+expr_copy_side(ExprItem *dest, const ExprItem *ei)
+{
+    dest->type = ei->type;
+    switch (ei->type) {
+       case EXPR_SYM:
+           dest->data.sym = ei->data.sym;
+           break;
+       case EXPR_EXPR:
+           dest->data.expn = expr_copy(ei->data.expn);
+           break;
+       case EXPR_INT:
+           dest->data.intn = intnum_copy(ei->data.intn);
+           break;
+       case EXPR_FLOAT:
+           dest->data.flt = floatnum_copy(ei->data.flt);
+           break;
+       case EXPR_REG:
+           dest->data.reg.num = ei->data.reg.num;
+           dest->data.reg.size = ei->data.reg.size;
+           break;
+       default:
+           break;
+    }
+}
+
+expr *
+expr_copy(const expr *e)
+{
+    expr *n;
+    
+    if (!e)
+       return 0;
+
+    n = xmalloc(sizeof(expr));
+
+    expr_copy_side(&n->left, &e->left);
+    expr_copy_side(&n->right, &e->right);
+    n->op = e->op;
+    n->filename = xstrdup(e->filename);
+    n->line = e->line;
+
+    return n;
+}
+
 static
 int expr_delete_each(expr *e, void *d)
 {
@@ -197,13 +242,13 @@ expr_delete(expr *e)
 }
 
 static int
-expr_contains_float_callback(const ExprItem *ei, void *d)
+expr_contains_float_callback(ExprItem *ei, void *d)
 {
     return (ei->type == EXPR_FLOAT);
 }
 
 int
-expr_contains_float(const expr *e)
+expr_contains_float(expr *e)
 {
     return expr_traverse_leaves_in(e, NULL, expr_contains_float_callback);
 }
@@ -300,7 +345,7 @@ expr_checkea_invalid16_callback(expr *e, void *d)
 }
 
 static int
-expr_checkea_getregsize_callback(const ExprItem *ei, void *d)
+expr_checkea_getregsize_callback(ExprItem *ei, void *d)
 {
     unsigned char *addrsize = (unsigned char *)d;
 
@@ -490,6 +535,26 @@ expr_checkea(expr **e, unsigned char *addrsize, unsigned char bits,
     return 1;
 }
 
+static int
+expr_expand_equ_callback(ExprItem *ei, void *d)
+{
+    const expr *equ_expr;
+    if (ei->type == EXPR_SYM) {
+       equ_expr = symrec_get_equ(ei->data.sym);
+       if (equ_expr) {
+           ei->type = EXPR_EXPR;
+           ei->data.expn = expr_copy(equ_expr);
+       }
+    }
+    return 0;
+}
+
+void
+expr_expand_equ(expr *e)
+{
+    expr_traverse_leaves_in(e, NULL, expr_expand_equ_callback);
+}
+
 /* Traverse over expression tree, calling func for each operation AFTER the
  * two branches (if expressions) have been traversed (eg, postorder
  * traversal).  The data pointer d is passed to each func call.
@@ -522,40 +587,25 @@ expr_traverse_nodes_post(expr *e, void *d, int (*func) (expr *e, void *d))
  * Stops early (and returns 1) if func returns 1.  Otherwise returns 0.
  */
 static int
-expr_traverse_leaves_in(const expr *e, void *d,
-                       int (*func) (const ExprItem *ei, void *d))
+expr_traverse_leaves_in(expr *e, void *d,
+                       int (*func) (ExprItem *ei, void *d))
 {
     if (!e)
        return 0;
 
-    switch (e->left.type) {
-       case EXPR_SYM:
-           if (expr_traverse_leaves_in(symrec_get_equ(e->left.data.sym), d,
-                                       func))
-               return 1;
-           break;
-       case EXPR_EXPR:
-           if (expr_traverse_leaves_in(e->left.data.expn, d, func))
-               return 1;
-           break;
-       default:
-           if (func(&e->left, d))
-               return 1;
+    if (e->left.type == EXPR_EXPR) {
+       if (expr_traverse_leaves_in(e->left.data.expn, d, func))
+           return 1;
+    } else {
+       if (func(&e->left, d))
+           return 1;
     }
 
-    switch (e->right.type) {
-       case EXPR_SYM:
-           if (expr_traverse_leaves_in(symrec_get_equ(e->right.data.sym), d,
-                                       func))
-               return 1;
-           break;
-       case EXPR_EXPR:
-           if (expr_traverse_leaves_in(e->right.data.expn, d, func))
-               return 1;
-           break;
-       default:
-           return func(&e->right, d);
-    }
+    if (e->right.type == EXPR_EXPR) {
+       if (expr_traverse_leaves_in(e->right.data.expn, d, func))
+           return 1;
+    } else
+       return func(&e->right, d);
 
     return 0;
 }
index 5ce86f7228fb59f8f48e15bec5aef908d28bd656..18de13916bda0a45c2a919330c15ffd5ba57ee63 100644 (file)
@@ -89,9 +89,12 @@ ExprItem *ExprReg(unsigned char reg, unsigned char size);
 #define expr_new_ident(r) \
     expr_new ((ExprItem *)NULL, EXPR_IDENT, (r))
 
+/* allocates and makes an exact duplicate of e */
+expr *expr_copy(const expr *e);
+
 void expr_delete(expr *e);
 
-int expr_contains_float(const expr *);
+int expr_contains_float(expr *);
 
 int expr_checkea(expr **e, unsigned char *addrsize, unsigned char bits,
                 unsigned char *displen, unsigned char *modrm,
@@ -99,6 +102,11 @@ int expr_checkea(expr **e, unsigned char *addrsize, unsigned char bits,
                 unsigned char *sib, unsigned char *v_sib,
                 unsigned char *n_sib);
 
+/* Expands all (symrec) equ's in the expression into full expression
+ * instances.
+ */
+void expr_expand_equ(expr *e);
+
 /* Simplifies the expression e as much as possible, eliminating extraneous
  * branches and simplifying integer-only subexpressions.
  */
index 103e569ec9f3faae968e4f5bdd1dacc9fb179a5d..2c1075f18360e538aed46e9fcdce71a4be021dd7 100644 (file)
@@ -477,6 +477,19 @@ floatnum_new(const char *str)
     return flt;
 }
 
+floatnum *
+floatnum_copy(const floatnum *flt)
+{
+    floatnum *f = xmalloc(sizeof(floatnum));
+
+    f->mantissa = BitVector_Clone(flt->mantissa);
+    f->exponent = flt->exponent;
+    f->sign = flt->sign;
+    f->flags = flt->flags;
+
+    return f;
+}
+
 void
 floatnum_delete(floatnum *flt)
 {
index 1e1389514e8d53c8e4a293c33c0e323e54ef0e5b..cf265b2a7c83252220fe432f6c3900517e744322 100644 (file)
@@ -60,6 +60,7 @@ typedef struct floatnum floatnum;
 #endif
 
 floatnum *floatnum_new(const char *str);
+floatnum *floatnum_copy(const floatnum *flt);
 void floatnum_delete(floatnum *flt);
 
 /* calculation function: acc = acc op operand */
index 0826a7aebb738bc6251857f82cc76f3e052c2509..1d6c9fb46acbfcc068f3a2ca4a0b561986af38bb 100644 (file)
@@ -195,6 +195,25 @@ intnum_new_int(unsigned long i)
     return intn;
 }
 
+intnum *
+intnum_copy(const intnum *intn)
+{
+    intnum *n = xmalloc(sizeof(intnum));
+
+    switch (intn->type) {
+       case INTNUM_UL:
+           n->val.ul = intn->val.ul;
+           break;
+       case INTNUM_BV:
+           n->val.bv = BitVector_Clone(intn->val.bv);
+           break;
+    }
+    n->type = intn->type;
+    n->origsize = intn->origsize;
+
+    return n;
+}
+
 void
 intnum_delete(intnum *intn)
 {
index 38f3248e2aff129e8c164ec26de3886c5bdee90e..5aec73891120367573c1a262797e91b94f87d82d 100644 (file)
@@ -64,6 +64,7 @@ intnum *intnum_new_hex(char *str);
 /* convert character constant to integer value, using NASM rules */
 intnum *intnum_new_charconst_nasm(const char *str);
 intnum *intnum_new_int(unsigned long i);
+intnum *intnum_copy(const intnum *intn);
 void intnum_delete(intnum *intn);
 
 /* calculation function: acc = acc op operand */
index f4ac1394899ff0ef61ad5e95d21c1e22fd874bf1..49521ee413ee6268d8657dd9b5f789eff945deac 100644 (file)
@@ -83,8 +83,8 @@ struct expr {
 
 static int expr_traverse_nodes_post(expr *e, void *d,
                                    int (*func) (expr *e, void *d));
-static int expr_traverse_leaves_in(const expr *e, void *d,
-                                  int (*func) (const ExprItem *ei, void *d));
+static int expr_traverse_leaves_in(expr *e, void *d,
+                                  int (*func) (ExprItem *ei, void *d));
 
 /* allocate a new expression node, with children as defined.
  * If it's a unary operator, put the element on the right */
@@ -162,6 +162,51 @@ ExprReg(unsigned char reg, unsigned char size)
     return e;
 }
 
+static void
+expr_copy_side(ExprItem *dest, const ExprItem *ei)
+{
+    dest->type = ei->type;
+    switch (ei->type) {
+       case EXPR_SYM:
+           dest->data.sym = ei->data.sym;
+           break;
+       case EXPR_EXPR:
+           dest->data.expn = expr_copy(ei->data.expn);
+           break;
+       case EXPR_INT:
+           dest->data.intn = intnum_copy(ei->data.intn);
+           break;
+       case EXPR_FLOAT:
+           dest->data.flt = floatnum_copy(ei->data.flt);
+           break;
+       case EXPR_REG:
+           dest->data.reg.num = ei->data.reg.num;
+           dest->data.reg.size = ei->data.reg.size;
+           break;
+       default:
+           break;
+    }
+}
+
+expr *
+expr_copy(const expr *e)
+{
+    expr *n;
+    
+    if (!e)
+       return 0;
+
+    n = xmalloc(sizeof(expr));
+
+    expr_copy_side(&n->left, &e->left);
+    expr_copy_side(&n->right, &e->right);
+    n->op = e->op;
+    n->filename = xstrdup(e->filename);
+    n->line = e->line;
+
+    return n;
+}
+
 static
 int expr_delete_each(expr *e, void *d)
 {
@@ -197,13 +242,13 @@ expr_delete(expr *e)
 }
 
 static int
-expr_contains_float_callback(const ExprItem *ei, void *d)
+expr_contains_float_callback(ExprItem *ei, void *d)
 {
     return (ei->type == EXPR_FLOAT);
 }
 
 int
-expr_contains_float(const expr *e)
+expr_contains_float(expr *e)
 {
     return expr_traverse_leaves_in(e, NULL, expr_contains_float_callback);
 }
@@ -300,7 +345,7 @@ expr_checkea_invalid16_callback(expr *e, void *d)
 }
 
 static int
-expr_checkea_getregsize_callback(const ExprItem *ei, void *d)
+expr_checkea_getregsize_callback(ExprItem *ei, void *d)
 {
     unsigned char *addrsize = (unsigned char *)d;
 
@@ -490,6 +535,26 @@ expr_checkea(expr **e, unsigned char *addrsize, unsigned char bits,
     return 1;
 }
 
+static int
+expr_expand_equ_callback(ExprItem *ei, void *d)
+{
+    const expr *equ_expr;
+    if (ei->type == EXPR_SYM) {
+       equ_expr = symrec_get_equ(ei->data.sym);
+       if (equ_expr) {
+           ei->type = EXPR_EXPR;
+           ei->data.expn = expr_copy(equ_expr);
+       }
+    }
+    return 0;
+}
+
+void
+expr_expand_equ(expr *e)
+{
+    expr_traverse_leaves_in(e, NULL, expr_expand_equ_callback);
+}
+
 /* Traverse over expression tree, calling func for each operation AFTER the
  * two branches (if expressions) have been traversed (eg, postorder
  * traversal).  The data pointer d is passed to each func call.
@@ -522,40 +587,25 @@ expr_traverse_nodes_post(expr *e, void *d, int (*func) (expr *e, void *d))
  * Stops early (and returns 1) if func returns 1.  Otherwise returns 0.
  */
 static int
-expr_traverse_leaves_in(const expr *e, void *d,
-                       int (*func) (const ExprItem *ei, void *d))
+expr_traverse_leaves_in(expr *e, void *d,
+                       int (*func) (ExprItem *ei, void *d))
 {
     if (!e)
        return 0;
 
-    switch (e->left.type) {
-       case EXPR_SYM:
-           if (expr_traverse_leaves_in(symrec_get_equ(e->left.data.sym), d,
-                                       func))
-               return 1;
-           break;
-       case EXPR_EXPR:
-           if (expr_traverse_leaves_in(e->left.data.expn, d, func))
-               return 1;
-           break;
-       default:
-           if (func(&e->left, d))
-               return 1;
+    if (e->left.type == EXPR_EXPR) {
+       if (expr_traverse_leaves_in(e->left.data.expn, d, func))
+           return 1;
+    } else {
+       if (func(&e->left, d))
+           return 1;
     }
 
-    switch (e->right.type) {
-       case EXPR_SYM:
-           if (expr_traverse_leaves_in(symrec_get_equ(e->right.data.sym), d,
-                                       func))
-               return 1;
-           break;
-       case EXPR_EXPR:
-           if (expr_traverse_leaves_in(e->right.data.expn, d, func))
-               return 1;
-           break;
-       default:
-           return func(&e->right, d);
-    }
+    if (e->right.type == EXPR_EXPR) {
+       if (expr_traverse_leaves_in(e->right.data.expn, d, func))
+           return 1;
+    } else
+       return func(&e->right, d);
 
     return 0;
 }
index f4ac1394899ff0ef61ad5e95d21c1e22fd874bf1..49521ee413ee6268d8657dd9b5f789eff945deac 100644 (file)
@@ -83,8 +83,8 @@ struct expr {
 
 static int expr_traverse_nodes_post(expr *e, void *d,
                                    int (*func) (expr *e, void *d));
-static int expr_traverse_leaves_in(const expr *e, void *d,
-                                  int (*func) (const ExprItem *ei, void *d));
+static int expr_traverse_leaves_in(expr *e, void *d,
+                                  int (*func) (ExprItem *ei, void *d));
 
 /* allocate a new expression node, with children as defined.
  * If it's a unary operator, put the element on the right */
@@ -162,6 +162,51 @@ ExprReg(unsigned char reg, unsigned char size)
     return e;
 }
 
+static void
+expr_copy_side(ExprItem *dest, const ExprItem *ei)
+{
+    dest->type = ei->type;
+    switch (ei->type) {
+       case EXPR_SYM:
+           dest->data.sym = ei->data.sym;
+           break;
+       case EXPR_EXPR:
+           dest->data.expn = expr_copy(ei->data.expn);
+           break;
+       case EXPR_INT:
+           dest->data.intn = intnum_copy(ei->data.intn);
+           break;
+       case EXPR_FLOAT:
+           dest->data.flt = floatnum_copy(ei->data.flt);
+           break;
+       case EXPR_REG:
+           dest->data.reg.num = ei->data.reg.num;
+           dest->data.reg.size = ei->data.reg.size;
+           break;
+       default:
+           break;
+    }
+}
+
+expr *
+expr_copy(const expr *e)
+{
+    expr *n;
+    
+    if (!e)
+       return 0;
+
+    n = xmalloc(sizeof(expr));
+
+    expr_copy_side(&n->left, &e->left);
+    expr_copy_side(&n->right, &e->right);
+    n->op = e->op;
+    n->filename = xstrdup(e->filename);
+    n->line = e->line;
+
+    return n;
+}
+
 static
 int expr_delete_each(expr *e, void *d)
 {
@@ -197,13 +242,13 @@ expr_delete(expr *e)
 }
 
 static int
-expr_contains_float_callback(const ExprItem *ei, void *d)
+expr_contains_float_callback(ExprItem *ei, void *d)
 {
     return (ei->type == EXPR_FLOAT);
 }
 
 int
-expr_contains_float(const expr *e)
+expr_contains_float(expr *e)
 {
     return expr_traverse_leaves_in(e, NULL, expr_contains_float_callback);
 }
@@ -300,7 +345,7 @@ expr_checkea_invalid16_callback(expr *e, void *d)
 }
 
 static int
-expr_checkea_getregsize_callback(const ExprItem *ei, void *d)
+expr_checkea_getregsize_callback(ExprItem *ei, void *d)
 {
     unsigned char *addrsize = (unsigned char *)d;
 
@@ -490,6 +535,26 @@ expr_checkea(expr **e, unsigned char *addrsize, unsigned char bits,
     return 1;
 }
 
+static int
+expr_expand_equ_callback(ExprItem *ei, void *d)
+{
+    const expr *equ_expr;
+    if (ei->type == EXPR_SYM) {
+       equ_expr = symrec_get_equ(ei->data.sym);
+       if (equ_expr) {
+           ei->type = EXPR_EXPR;
+           ei->data.expn = expr_copy(equ_expr);
+       }
+    }
+    return 0;
+}
+
+void
+expr_expand_equ(expr *e)
+{
+    expr_traverse_leaves_in(e, NULL, expr_expand_equ_callback);
+}
+
 /* Traverse over expression tree, calling func for each operation AFTER the
  * two branches (if expressions) have been traversed (eg, postorder
  * traversal).  The data pointer d is passed to each func call.
@@ -522,40 +587,25 @@ expr_traverse_nodes_post(expr *e, void *d, int (*func) (expr *e, void *d))
  * Stops early (and returns 1) if func returns 1.  Otherwise returns 0.
  */
 static int
-expr_traverse_leaves_in(const expr *e, void *d,
-                       int (*func) (const ExprItem *ei, void *d))
+expr_traverse_leaves_in(expr *e, void *d,
+                       int (*func) (ExprItem *ei, void *d))
 {
     if (!e)
        return 0;
 
-    switch (e->left.type) {
-       case EXPR_SYM:
-           if (expr_traverse_leaves_in(symrec_get_equ(e->left.data.sym), d,
-                                       func))
-               return 1;
-           break;
-       case EXPR_EXPR:
-           if (expr_traverse_leaves_in(e->left.data.expn, d, func))
-               return 1;
-           break;
-       default:
-           if (func(&e->left, d))
-               return 1;
+    if (e->left.type == EXPR_EXPR) {
+       if (expr_traverse_leaves_in(e->left.data.expn, d, func))
+           return 1;
+    } else {
+       if (func(&e->left, d))
+           return 1;
     }
 
-    switch (e->right.type) {
-       case EXPR_SYM:
-           if (expr_traverse_leaves_in(symrec_get_equ(e->right.data.sym), d,
-                                       func))
-               return 1;
-           break;
-       case EXPR_EXPR:
-           if (expr_traverse_leaves_in(e->right.data.expn, d, func))
-               return 1;
-           break;
-       default:
-           return func(&e->right, d);
-    }
+    if (e->right.type == EXPR_EXPR) {
+       if (expr_traverse_leaves_in(e->right.data.expn, d, func))
+           return 1;
+    } else
+       return func(&e->right, d);
 
     return 0;
 }
index f4ac1394899ff0ef61ad5e95d21c1e22fd874bf1..49521ee413ee6268d8657dd9b5f789eff945deac 100644 (file)
@@ -83,8 +83,8 @@ struct expr {
 
 static int expr_traverse_nodes_post(expr *e, void *d,
                                    int (*func) (expr *e, void *d));
-static int expr_traverse_leaves_in(const expr *e, void *d,
-                                  int (*func) (const ExprItem *ei, void *d));
+static int expr_traverse_leaves_in(expr *e, void *d,
+                                  int (*func) (ExprItem *ei, void *d));
 
 /* allocate a new expression node, with children as defined.
  * If it's a unary operator, put the element on the right */
@@ -162,6 +162,51 @@ ExprReg(unsigned char reg, unsigned char size)
     return e;
 }
 
+static void
+expr_copy_side(ExprItem *dest, const ExprItem *ei)
+{
+    dest->type = ei->type;
+    switch (ei->type) {
+       case EXPR_SYM:
+           dest->data.sym = ei->data.sym;
+           break;
+       case EXPR_EXPR:
+           dest->data.expn = expr_copy(ei->data.expn);
+           break;
+       case EXPR_INT:
+           dest->data.intn = intnum_copy(ei->data.intn);
+           break;
+       case EXPR_FLOAT:
+           dest->data.flt = floatnum_copy(ei->data.flt);
+           break;
+       case EXPR_REG:
+           dest->data.reg.num = ei->data.reg.num;
+           dest->data.reg.size = ei->data.reg.size;
+           break;
+       default:
+           break;
+    }
+}
+
+expr *
+expr_copy(const expr *e)
+{
+    expr *n;
+    
+    if (!e)
+       return 0;
+
+    n = xmalloc(sizeof(expr));
+
+    expr_copy_side(&n->left, &e->left);
+    expr_copy_side(&n->right, &e->right);
+    n->op = e->op;
+    n->filename = xstrdup(e->filename);
+    n->line = e->line;
+
+    return n;
+}
+
 static
 int expr_delete_each(expr *e, void *d)
 {
@@ -197,13 +242,13 @@ expr_delete(expr *e)
 }
 
 static int
-expr_contains_float_callback(const ExprItem *ei, void *d)
+expr_contains_float_callback(ExprItem *ei, void *d)
 {
     return (ei->type == EXPR_FLOAT);
 }
 
 int
-expr_contains_float(const expr *e)
+expr_contains_float(expr *e)
 {
     return expr_traverse_leaves_in(e, NULL, expr_contains_float_callback);
 }
@@ -300,7 +345,7 @@ expr_checkea_invalid16_callback(expr *e, void *d)
 }
 
 static int
-expr_checkea_getregsize_callback(const ExprItem *ei, void *d)
+expr_checkea_getregsize_callback(ExprItem *ei, void *d)
 {
     unsigned char *addrsize = (unsigned char *)d;
 
@@ -490,6 +535,26 @@ expr_checkea(expr **e, unsigned char *addrsize, unsigned char bits,
     return 1;
 }
 
+static int
+expr_expand_equ_callback(ExprItem *ei, void *d)
+{
+    const expr *equ_expr;
+    if (ei->type == EXPR_SYM) {
+       equ_expr = symrec_get_equ(ei->data.sym);
+       if (equ_expr) {
+           ei->type = EXPR_EXPR;
+           ei->data.expn = expr_copy(equ_expr);
+       }
+    }
+    return 0;
+}
+
+void
+expr_expand_equ(expr *e)
+{
+    expr_traverse_leaves_in(e, NULL, expr_expand_equ_callback);
+}
+
 /* Traverse over expression tree, calling func for each operation AFTER the
  * two branches (if expressions) have been traversed (eg, postorder
  * traversal).  The data pointer d is passed to each func call.
@@ -522,40 +587,25 @@ expr_traverse_nodes_post(expr *e, void *d, int (*func) (expr *e, void *d))
  * Stops early (and returns 1) if func returns 1.  Otherwise returns 0.
  */
 static int
-expr_traverse_leaves_in(const expr *e, void *d,
-                       int (*func) (const ExprItem *ei, void *d))
+expr_traverse_leaves_in(expr *e, void *d,
+                       int (*func) (ExprItem *ei, void *d))
 {
     if (!e)
        return 0;
 
-    switch (e->left.type) {
-       case EXPR_SYM:
-           if (expr_traverse_leaves_in(symrec_get_equ(e->left.data.sym), d,
-                                       func))
-               return 1;
-           break;
-       case EXPR_EXPR:
-           if (expr_traverse_leaves_in(e->left.data.expn, d, func))
-               return 1;
-           break;
-       default:
-           if (func(&e->left, d))
-               return 1;
+    if (e->left.type == EXPR_EXPR) {
+       if (expr_traverse_leaves_in(e->left.data.expn, d, func))
+           return 1;
+    } else {
+       if (func(&e->left, d))
+           return 1;
     }
 
-    switch (e->right.type) {
-       case EXPR_SYM:
-           if (expr_traverse_leaves_in(symrec_get_equ(e->right.data.sym), d,
-                                       func))
-               return 1;
-           break;
-       case EXPR_EXPR:
-           if (expr_traverse_leaves_in(e->right.data.expn, d, func))
-               return 1;
-           break;
-       default:
-           return func(&e->right, d);
-    }
+    if (e->right.type == EXPR_EXPR) {
+       if (expr_traverse_leaves_in(e->right.data.expn, d, func))
+           return 1;
+    } else
+       return func(&e->right, d);
 
     return 0;
 }
index f4ac1394899ff0ef61ad5e95d21c1e22fd874bf1..49521ee413ee6268d8657dd9b5f789eff945deac 100644 (file)
@@ -83,8 +83,8 @@ struct expr {
 
 static int expr_traverse_nodes_post(expr *e, void *d,
                                    int (*func) (expr *e, void *d));
-static int expr_traverse_leaves_in(const expr *e, void *d,
-                                  int (*func) (const ExprItem *ei, void *d));
+static int expr_traverse_leaves_in(expr *e, void *d,
+                                  int (*func) (ExprItem *ei, void *d));
 
 /* allocate a new expression node, with children as defined.
  * If it's a unary operator, put the element on the right */
@@ -162,6 +162,51 @@ ExprReg(unsigned char reg, unsigned char size)
     return e;
 }
 
+static void
+expr_copy_side(ExprItem *dest, const ExprItem *ei)
+{
+    dest->type = ei->type;
+    switch (ei->type) {
+       case EXPR_SYM:
+           dest->data.sym = ei->data.sym;
+           break;
+       case EXPR_EXPR:
+           dest->data.expn = expr_copy(ei->data.expn);
+           break;
+       case EXPR_INT:
+           dest->data.intn = intnum_copy(ei->data.intn);
+           break;
+       case EXPR_FLOAT:
+           dest->data.flt = floatnum_copy(ei->data.flt);
+           break;
+       case EXPR_REG:
+           dest->data.reg.num = ei->data.reg.num;
+           dest->data.reg.size = ei->data.reg.size;
+           break;
+       default:
+           break;
+    }
+}
+
+expr *
+expr_copy(const expr *e)
+{
+    expr *n;
+    
+    if (!e)
+       return 0;
+
+    n = xmalloc(sizeof(expr));
+
+    expr_copy_side(&n->left, &e->left);
+    expr_copy_side(&n->right, &e->right);
+    n->op = e->op;
+    n->filename = xstrdup(e->filename);
+    n->line = e->line;
+
+    return n;
+}
+
 static
 int expr_delete_each(expr *e, void *d)
 {
@@ -197,13 +242,13 @@ expr_delete(expr *e)
 }
 
 static int
-expr_contains_float_callback(const ExprItem *ei, void *d)
+expr_contains_float_callback(ExprItem *ei, void *d)
 {
     return (ei->type == EXPR_FLOAT);
 }
 
 int
-expr_contains_float(const expr *e)
+expr_contains_float(expr *e)
 {
     return expr_traverse_leaves_in(e, NULL, expr_contains_float_callback);
 }
@@ -300,7 +345,7 @@ expr_checkea_invalid16_callback(expr *e, void *d)
 }
 
 static int
-expr_checkea_getregsize_callback(const ExprItem *ei, void *d)
+expr_checkea_getregsize_callback(ExprItem *ei, void *d)
 {
     unsigned char *addrsize = (unsigned char *)d;
 
@@ -490,6 +535,26 @@ expr_checkea(expr **e, unsigned char *addrsize, unsigned char bits,
     return 1;
 }
 
+static int
+expr_expand_equ_callback(ExprItem *ei, void *d)
+{
+    const expr *equ_expr;
+    if (ei->type == EXPR_SYM) {
+       equ_expr = symrec_get_equ(ei->data.sym);
+       if (equ_expr) {
+           ei->type = EXPR_EXPR;
+           ei->data.expn = expr_copy(equ_expr);
+       }
+    }
+    return 0;
+}
+
+void
+expr_expand_equ(expr *e)
+{
+    expr_traverse_leaves_in(e, NULL, expr_expand_equ_callback);
+}
+
 /* Traverse over expression tree, calling func for each operation AFTER the
  * two branches (if expressions) have been traversed (eg, postorder
  * traversal).  The data pointer d is passed to each func call.
@@ -522,40 +587,25 @@ expr_traverse_nodes_post(expr *e, void *d, int (*func) (expr *e, void *d))
  * Stops early (and returns 1) if func returns 1.  Otherwise returns 0.
  */
 static int
-expr_traverse_leaves_in(const expr *e, void *d,
-                       int (*func) (const ExprItem *ei, void *d))
+expr_traverse_leaves_in(expr *e, void *d,
+                       int (*func) (ExprItem *ei, void *d))
 {
     if (!e)
        return 0;
 
-    switch (e->left.type) {
-       case EXPR_SYM:
-           if (expr_traverse_leaves_in(symrec_get_equ(e->left.data.sym), d,
-                                       func))
-               return 1;
-           break;
-       case EXPR_EXPR:
-           if (expr_traverse_leaves_in(e->left.data.expn, d, func))
-               return 1;
-           break;
-       default:
-           if (func(&e->left, d))
-               return 1;
+    if (e->left.type == EXPR_EXPR) {
+       if (expr_traverse_leaves_in(e->left.data.expn, d, func))
+           return 1;
+    } else {
+       if (func(&e->left, d))
+           return 1;
     }
 
-    switch (e->right.type) {
-       case EXPR_SYM:
-           if (expr_traverse_leaves_in(symrec_get_equ(e->right.data.sym), d,
-                                       func))
-               return 1;
-           break;
-       case EXPR_EXPR:
-           if (expr_traverse_leaves_in(e->right.data.expn, d, func))
-               return 1;
-           break;
-       default:
-           return func(&e->right, d);
-    }
+    if (e->right.type == EXPR_EXPR) {
+       if (expr_traverse_leaves_in(e->right.data.expn, d, func))
+           return 1;
+    } else
+       return func(&e->right, d);
 
     return 0;
 }
index f4ac1394899ff0ef61ad5e95d21c1e22fd874bf1..49521ee413ee6268d8657dd9b5f789eff945deac 100644 (file)
@@ -83,8 +83,8 @@ struct expr {
 
 static int expr_traverse_nodes_post(expr *e, void *d,
                                    int (*func) (expr *e, void *d));
-static int expr_traverse_leaves_in(const expr *e, void *d,
-                                  int (*func) (const ExprItem *ei, void *d));
+static int expr_traverse_leaves_in(expr *e, void *d,
+                                  int (*func) (ExprItem *ei, void *d));
 
 /* allocate a new expression node, with children as defined.
  * If it's a unary operator, put the element on the right */
@@ -162,6 +162,51 @@ ExprReg(unsigned char reg, unsigned char size)
     return e;
 }
 
+static void
+expr_copy_side(ExprItem *dest, const ExprItem *ei)
+{
+    dest->type = ei->type;
+    switch (ei->type) {
+       case EXPR_SYM:
+           dest->data.sym = ei->data.sym;
+           break;
+       case EXPR_EXPR:
+           dest->data.expn = expr_copy(ei->data.expn);
+           break;
+       case EXPR_INT:
+           dest->data.intn = intnum_copy(ei->data.intn);
+           break;
+       case EXPR_FLOAT:
+           dest->data.flt = floatnum_copy(ei->data.flt);
+           break;
+       case EXPR_REG:
+           dest->data.reg.num = ei->data.reg.num;
+           dest->data.reg.size = ei->data.reg.size;
+           break;
+       default:
+           break;
+    }
+}
+
+expr *
+expr_copy(const expr *e)
+{
+    expr *n;
+    
+    if (!e)
+       return 0;
+
+    n = xmalloc(sizeof(expr));
+
+    expr_copy_side(&n->left, &e->left);
+    expr_copy_side(&n->right, &e->right);
+    n->op = e->op;
+    n->filename = xstrdup(e->filename);
+    n->line = e->line;
+
+    return n;
+}
+
 static
 int expr_delete_each(expr *e, void *d)
 {
@@ -197,13 +242,13 @@ expr_delete(expr *e)
 }
 
 static int
-expr_contains_float_callback(const ExprItem *ei, void *d)
+expr_contains_float_callback(ExprItem *ei, void *d)
 {
     return (ei->type == EXPR_FLOAT);
 }
 
 int
-expr_contains_float(const expr *e)
+expr_contains_float(expr *e)
 {
     return expr_traverse_leaves_in(e, NULL, expr_contains_float_callback);
 }
@@ -300,7 +345,7 @@ expr_checkea_invalid16_callback(expr *e, void *d)
 }
 
 static int
-expr_checkea_getregsize_callback(const ExprItem *ei, void *d)
+expr_checkea_getregsize_callback(ExprItem *ei, void *d)
 {
     unsigned char *addrsize = (unsigned char *)d;
 
@@ -490,6 +535,26 @@ expr_checkea(expr **e, unsigned char *addrsize, unsigned char bits,
     return 1;
 }
 
+static int
+expr_expand_equ_callback(ExprItem *ei, void *d)
+{
+    const expr *equ_expr;
+    if (ei->type == EXPR_SYM) {
+       equ_expr = symrec_get_equ(ei->data.sym);
+       if (equ_expr) {
+           ei->type = EXPR_EXPR;
+           ei->data.expn = expr_copy(equ_expr);
+       }
+    }
+    return 0;
+}
+
+void
+expr_expand_equ(expr *e)
+{
+    expr_traverse_leaves_in(e, NULL, expr_expand_equ_callback);
+}
+
 /* Traverse over expression tree, calling func for each operation AFTER the
  * two branches (if expressions) have been traversed (eg, postorder
  * traversal).  The data pointer d is passed to each func call.
@@ -522,40 +587,25 @@ expr_traverse_nodes_post(expr *e, void *d, int (*func) (expr *e, void *d))
  * Stops early (and returns 1) if func returns 1.  Otherwise returns 0.
  */
 static int
-expr_traverse_leaves_in(const expr *e, void *d,
-                       int (*func) (const ExprItem *ei, void *d))
+expr_traverse_leaves_in(expr *e, void *d,
+                       int (*func) (ExprItem *ei, void *d))
 {
     if (!e)
        return 0;
 
-    switch (e->left.type) {
-       case EXPR_SYM:
-           if (expr_traverse_leaves_in(symrec_get_equ(e->left.data.sym), d,
-                                       func))
-               return 1;
-           break;
-       case EXPR_EXPR:
-           if (expr_traverse_leaves_in(e->left.data.expn, d, func))
-               return 1;
-           break;
-       default:
-           if (func(&e->left, d))
-               return 1;
+    if (e->left.type == EXPR_EXPR) {
+       if (expr_traverse_leaves_in(e->left.data.expn, d, func))
+           return 1;
+    } else {
+       if (func(&e->left, d))
+           return 1;
     }
 
-    switch (e->right.type) {
-       case EXPR_SYM:
-           if (expr_traverse_leaves_in(symrec_get_equ(e->right.data.sym), d,
-                                       func))
-               return 1;
-           break;
-       case EXPR_EXPR:
-           if (expr_traverse_leaves_in(e->right.data.expn, d, func))
-               return 1;
-           break;
-       default:
-           return func(&e->right, d);
-    }
+    if (e->right.type == EXPR_EXPR) {
+       if (expr_traverse_leaves_in(e->right.data.expn, d, func))
+           return 1;
+    } else
+       return func(&e->right, d);
 
     return 0;
 }
index 5ce86f7228fb59f8f48e15bec5aef908d28bd656..18de13916bda0a45c2a919330c15ffd5ba57ee63 100644 (file)
@@ -89,9 +89,12 @@ ExprItem *ExprReg(unsigned char reg, unsigned char size);
 #define expr_new_ident(r) \
     expr_new ((ExprItem *)NULL, EXPR_IDENT, (r))
 
+/* allocates and makes an exact duplicate of e */
+expr *expr_copy(const expr *e);
+
 void expr_delete(expr *e);
 
-int expr_contains_float(const expr *);
+int expr_contains_float(expr *);
 
 int expr_checkea(expr **e, unsigned char *addrsize, unsigned char bits,
                 unsigned char *displen, unsigned char *modrm,
@@ -99,6 +102,11 @@ int expr_checkea(expr **e, unsigned char *addrsize, unsigned char bits,
                 unsigned char *sib, unsigned char *v_sib,
                 unsigned char *n_sib);
 
+/* Expands all (symrec) equ's in the expression into full expression
+ * instances.
+ */
+void expr_expand_equ(expr *e);
+
 /* Simplifies the expression e as much as possible, eliminating extraneous
  * branches and simplifying integer-only subexpressions.
  */
index 103e569ec9f3faae968e4f5bdd1dacc9fb179a5d..2c1075f18360e538aed46e9fcdce71a4be021dd7 100644 (file)
@@ -477,6 +477,19 @@ floatnum_new(const char *str)
     return flt;
 }
 
+floatnum *
+floatnum_copy(const floatnum *flt)
+{
+    floatnum *f = xmalloc(sizeof(floatnum));
+
+    f->mantissa = BitVector_Clone(flt->mantissa);
+    f->exponent = flt->exponent;
+    f->sign = flt->sign;
+    f->flags = flt->flags;
+
+    return f;
+}
+
 void
 floatnum_delete(floatnum *flt)
 {
index 1e1389514e8d53c8e4a293c33c0e323e54ef0e5b..cf265b2a7c83252220fe432f6c3900517e744322 100644 (file)
@@ -60,6 +60,7 @@ typedef struct floatnum floatnum;
 #endif
 
 floatnum *floatnum_new(const char *str);
+floatnum *floatnum_copy(const floatnum *flt);
 void floatnum_delete(floatnum *flt);
 
 /* calculation function: acc = acc op operand */
index 0826a7aebb738bc6251857f82cc76f3e052c2509..1d6c9fb46acbfcc068f3a2ca4a0b561986af38bb 100644 (file)
@@ -195,6 +195,25 @@ intnum_new_int(unsigned long i)
     return intn;
 }
 
+intnum *
+intnum_copy(const intnum *intn)
+{
+    intnum *n = xmalloc(sizeof(intnum));
+
+    switch (intn->type) {
+       case INTNUM_UL:
+           n->val.ul = intn->val.ul;
+           break;
+       case INTNUM_BV:
+           n->val.bv = BitVector_Clone(intn->val.bv);
+           break;
+    }
+    n->type = intn->type;
+    n->origsize = intn->origsize;
+
+    return n;
+}
+
 void
 intnum_delete(intnum *intn)
 {
index 38f3248e2aff129e8c164ec26de3886c5bdee90e..5aec73891120367573c1a262797e91b94f87d82d 100644 (file)
@@ -64,6 +64,7 @@ intnum *intnum_new_hex(char *str);
 /* convert character constant to integer value, using NASM rules */
 intnum *intnum_new_charconst_nasm(const char *str);
 intnum *intnum_new_int(unsigned long i);
+intnum *intnum_copy(const intnum *intn);
 void intnum_delete(intnum *intn);
 
 /* calculation function: acc = acc op operand */