From: Peter Johnson Date: Fri, 12 Oct 2001 02:34:30 +0000 (-0000) Subject: Add expr_contains_float() and symrec_get_equ() functions. These are the first X-Git-Tag: v0.1.0~252 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8149291ecadcf242602d714b5172fd3ebe2b445d;p=yasm Add expr_contains_float() and symrec_get_equ() functions. These are the first of many functions like this which will be needed for advanced validity checking in the finalization of the parser stage. Fix yacc grammar to not use the (incorrect) expr_no_fltstr, and change memexp to memexpr and its handling to prepare for memory expressions. svn path=/trunk/yasm/; revision=278 --- diff --git a/libyasm/expr.c b/libyasm/expr.c index 252065f7..077a45ab 100644 --- a/libyasm/expr.c +++ b/libyasm/expr.c @@ -142,6 +142,42 @@ ExprFloat(floatnum *f) return e; } +int +expr_contains_float(const expr *e) +{ + if (!e) + return 0; + + switch (e->left.type) { + case EXPR_SYM: + if (expr_contains_float(symrec_get_equ(e->left.data.sym))) + return 1; + break; + case EXPR_EXPR: + if (expr_contains_float(e->left.data.expn)) + return 1; + break; + case EXPR_FLOAT: + return 1; + case EXPR_INT: + case EXPR_NONE: + break; + } + + switch (e->right.type) { + case EXPR_SYM: + return expr_contains_float(symrec_get_equ(e->right.data.sym)); + case EXPR_EXPR: + return expr_contains_float(e->right.data.expn); + case EXPR_FLOAT: + return 1; + case EXPR_INT: + case EXPR_NONE: + break; + } + return 0; +} + /* get rid of unnecessary branches if possible. report. */ int expr_simplify(expr *e) diff --git a/libyasm/expr.h b/libyasm/expr.h index 8adad2db..17b0a11a 100644 --- a/libyasm/expr.h +++ b/libyasm/expr.h @@ -88,6 +88,8 @@ ExprItem *ExprFloat(floatnum *); #define expr_new_ident(r) \ expr_new ((ExprItem *)NULL, EXPR_IDENT, (r)) +int expr_contains_float(const expr *); + int expr_simplify(expr *); void expr_print(expr *); diff --git a/libyasm/symrec.c b/libyasm/symrec.c index d18f352e..1f800b2c 100644 --- a/libyasm/symrec.c +++ b/libyasm/symrec.c @@ -229,6 +229,14 @@ symrec_get_name(const symrec *sym) return sym->name; } +const expr * +symrec_get_equ(const symrec *sym) +{ + if (sym->type == SYM_EQU) + return sym->value.expn; + return (const expr *)NULL; +} + void symrec_print(const symrec *sym) { diff --git a/libyasm/symrec.h b/libyasm/symrec.h index 2f136021..de22e6fc 100644 --- a/libyasm/symrec.h +++ b/libyasm/symrec.h @@ -67,6 +67,8 @@ int symrec_get_int_value(const symrec *sym, unsigned long *ret_val, const char *symrec_get_name(const symrec *sym); +const expr *symrec_get_equ(const symrec *sym); + int symrec_foreach(int (*func) (symrec *sym)); void symrec_print(const symrec *sym); diff --git a/modules/arch/x86/expr.c b/modules/arch/x86/expr.c index 252065f7..077a45ab 100644 --- a/modules/arch/x86/expr.c +++ b/modules/arch/x86/expr.c @@ -142,6 +142,42 @@ ExprFloat(floatnum *f) return e; } +int +expr_contains_float(const expr *e) +{ + if (!e) + return 0; + + switch (e->left.type) { + case EXPR_SYM: + if (expr_contains_float(symrec_get_equ(e->left.data.sym))) + return 1; + break; + case EXPR_EXPR: + if (expr_contains_float(e->left.data.expn)) + return 1; + break; + case EXPR_FLOAT: + return 1; + case EXPR_INT: + case EXPR_NONE: + break; + } + + switch (e->right.type) { + case EXPR_SYM: + return expr_contains_float(symrec_get_equ(e->right.data.sym)); + case EXPR_EXPR: + return expr_contains_float(e->right.data.expn); + case EXPR_FLOAT: + return 1; + case EXPR_INT: + case EXPR_NONE: + break; + } + return 0; +} + /* get rid of unnecessary branches if possible. report. */ int expr_simplify(expr *e) diff --git a/modules/arch/x86/x86expr.c b/modules/arch/x86/x86expr.c index 252065f7..077a45ab 100644 --- a/modules/arch/x86/x86expr.c +++ b/modules/arch/x86/x86expr.c @@ -142,6 +142,42 @@ ExprFloat(floatnum *f) return e; } +int +expr_contains_float(const expr *e) +{ + if (!e) + return 0; + + switch (e->left.type) { + case EXPR_SYM: + if (expr_contains_float(symrec_get_equ(e->left.data.sym))) + return 1; + break; + case EXPR_EXPR: + if (expr_contains_float(e->left.data.expn)) + return 1; + break; + case EXPR_FLOAT: + return 1; + case EXPR_INT: + case EXPR_NONE: + break; + } + + switch (e->right.type) { + case EXPR_SYM: + return expr_contains_float(symrec_get_equ(e->right.data.sym)); + case EXPR_EXPR: + return expr_contains_float(e->right.data.expn); + case EXPR_FLOAT: + return 1; + case EXPR_INT: + case EXPR_NONE: + break; + } + return 0; +} + /* get rid of unnecessary branches if possible. report. */ int expr_simplify(expr *e) diff --git a/modules/parsers/nasm/bison.y.in b/modules/parsers/nasm/bison.y.in index d246fe04..32ebf299 100644 --- a/modules/parsers/nasm/bison.y.in +++ b/modules/parsers/nasm/bison.y.in @@ -111,13 +111,13 @@ static bytecode *nasm_parser_temp_bc; %type line lineexp exp instr instrbase %type fpureg reg32 reg16 reg8 segreg -%type mem memaddr memexp memfar +%type mem memaddr memfar %type mem8x mem16x mem32x mem64x mem80x mem128x %type mem8 mem16 mem32 mem64 mem80 mem128 mem1632 %type rm8x rm16x rm32x /*rm64x rm128x*/ %type rm8 rm16 rm32 rm64 rm128 %type imm imm8x imm16x imm32x imm8 imm16 imm32 -%type expr expr_no_string expr_no_fltstr +%type expr expr_no_string memexpr %type explabel %type label_id %type target @@ -154,10 +154,10 @@ line: '\n' { $$ = (bytecode *)NULL; } ; lineexp: exp - | TIMES expr_no_fltstr exp { $$ = $3; SetBCMultiple($$, $2); } + | TIMES expr exp { $$ = $3; SetBCMultiple($$, $2); } | label { $$ = (bytecode *)NULL; } | label exp { $$ = $2; } - | label TIMES expr_no_fltstr exp { $$ = $4; SetBCMultiple($$, $3); } + | label TIMES expr exp { $$ = $4; SetBCMultiple($$, $3); } | label_id EQU expr { symrec_define_equ($1, $3); $$ = (bytecode *)NULL; @@ -166,7 +166,7 @@ lineexp: exp exp: instr | DECLARE_DATA datavals { $$ = bytecode_new_data(&$2, $1); } - | RESERVE_SPACE expr_no_fltstr { $$ = bytecode_new_reserve($2, $1); } + | RESERVE_SPACE expr { $$ = bytecode_new_reserve($2, $1); } ; datavals: dataval { @@ -265,10 +265,10 @@ segreg: REG_ES ; /* memory addresses */ -memexp: expr { $$ = effaddr_new_expr($1); } +memexpr: expr ; -memaddr: memexp { $$ = $1; SetEASegment($$, 0); } +memaddr: memexpr { $$ = effaddr_new_expr($1); SetEASegment($$, 0); } | REG_CS ':' memaddr { $$ = $3; SetEASegment($$, 0x2E); } | REG_SS ':' memaddr { $$ = $3; SetEASegment($$, 0x36); } | REG_DS ':' memaddr { $$ = $3; SetEASegment($$, 0x3E); } @@ -387,17 +387,14 @@ imm32: imm ; /* jump targets */ -target: expr_no_fltstr { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); } +target: expr { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); } | SHORT target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_SHORT_FORCED); } | NEAR target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_NEAR_FORCED); } ; /* expression trees */ -expr_no_string: expr_no_fltstr +expr_no_string: INTNUM { $$ = expr_new_ident(ExprInt($1)); } | FLTNUM { $$ = expr_new_ident(ExprFloat($1)); } -; - -expr_no_fltstr: INTNUM { $$ = expr_new_ident(ExprInt($1)); } | explabel { $$ = expr_new_ident(ExprSym($1)); } /*| expr '||' expr { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/ | expr '|' expr { $$ = expr_new_tree($1, EXPR_OR, $3); } diff --git a/modules/parsers/nasm/nasm-bison.y b/modules/parsers/nasm/nasm-bison.y index d246fe04..32ebf299 100644 --- a/modules/parsers/nasm/nasm-bison.y +++ b/modules/parsers/nasm/nasm-bison.y @@ -111,13 +111,13 @@ static bytecode *nasm_parser_temp_bc; %type line lineexp exp instr instrbase %type fpureg reg32 reg16 reg8 segreg -%type mem memaddr memexp memfar +%type mem memaddr memfar %type mem8x mem16x mem32x mem64x mem80x mem128x %type mem8 mem16 mem32 mem64 mem80 mem128 mem1632 %type rm8x rm16x rm32x /*rm64x rm128x*/ %type rm8 rm16 rm32 rm64 rm128 %type imm imm8x imm16x imm32x imm8 imm16 imm32 -%type expr expr_no_string expr_no_fltstr +%type expr expr_no_string memexpr %type explabel %type label_id %type target @@ -154,10 +154,10 @@ line: '\n' { $$ = (bytecode *)NULL; } ; lineexp: exp - | TIMES expr_no_fltstr exp { $$ = $3; SetBCMultiple($$, $2); } + | TIMES expr exp { $$ = $3; SetBCMultiple($$, $2); } | label { $$ = (bytecode *)NULL; } | label exp { $$ = $2; } - | label TIMES expr_no_fltstr exp { $$ = $4; SetBCMultiple($$, $3); } + | label TIMES expr exp { $$ = $4; SetBCMultiple($$, $3); } | label_id EQU expr { symrec_define_equ($1, $3); $$ = (bytecode *)NULL; @@ -166,7 +166,7 @@ lineexp: exp exp: instr | DECLARE_DATA datavals { $$ = bytecode_new_data(&$2, $1); } - | RESERVE_SPACE expr_no_fltstr { $$ = bytecode_new_reserve($2, $1); } + | RESERVE_SPACE expr { $$ = bytecode_new_reserve($2, $1); } ; datavals: dataval { @@ -265,10 +265,10 @@ segreg: REG_ES ; /* memory addresses */ -memexp: expr { $$ = effaddr_new_expr($1); } +memexpr: expr ; -memaddr: memexp { $$ = $1; SetEASegment($$, 0); } +memaddr: memexpr { $$ = effaddr_new_expr($1); SetEASegment($$, 0); } | REG_CS ':' memaddr { $$ = $3; SetEASegment($$, 0x2E); } | REG_SS ':' memaddr { $$ = $3; SetEASegment($$, 0x36); } | REG_DS ':' memaddr { $$ = $3; SetEASegment($$, 0x3E); } @@ -387,17 +387,14 @@ imm32: imm ; /* jump targets */ -target: expr_no_fltstr { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); } +target: expr { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); } | SHORT target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_SHORT_FORCED); } | NEAR target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_NEAR_FORCED); } ; /* expression trees */ -expr_no_string: expr_no_fltstr +expr_no_string: INTNUM { $$ = expr_new_ident(ExprInt($1)); } | FLTNUM { $$ = expr_new_ident(ExprFloat($1)); } -; - -expr_no_fltstr: INTNUM { $$ = expr_new_ident(ExprInt($1)); } | explabel { $$ = expr_new_ident(ExprSym($1)); } /*| expr '||' expr { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/ | expr '|' expr { $$ = expr_new_tree($1, EXPR_OR, $3); } diff --git a/src/arch/x86/expr.c b/src/arch/x86/expr.c index 252065f7..077a45ab 100644 --- a/src/arch/x86/expr.c +++ b/src/arch/x86/expr.c @@ -142,6 +142,42 @@ ExprFloat(floatnum *f) return e; } +int +expr_contains_float(const expr *e) +{ + if (!e) + return 0; + + switch (e->left.type) { + case EXPR_SYM: + if (expr_contains_float(symrec_get_equ(e->left.data.sym))) + return 1; + break; + case EXPR_EXPR: + if (expr_contains_float(e->left.data.expn)) + return 1; + break; + case EXPR_FLOAT: + return 1; + case EXPR_INT: + case EXPR_NONE: + break; + } + + switch (e->right.type) { + case EXPR_SYM: + return expr_contains_float(symrec_get_equ(e->right.data.sym)); + case EXPR_EXPR: + return expr_contains_float(e->right.data.expn); + case EXPR_FLOAT: + return 1; + case EXPR_INT: + case EXPR_NONE: + break; + } + return 0; +} + /* get rid of unnecessary branches if possible. report. */ int expr_simplify(expr *e) diff --git a/src/arch/x86/x86expr.c b/src/arch/x86/x86expr.c index 252065f7..077a45ab 100644 --- a/src/arch/x86/x86expr.c +++ b/src/arch/x86/x86expr.c @@ -142,6 +142,42 @@ ExprFloat(floatnum *f) return e; } +int +expr_contains_float(const expr *e) +{ + if (!e) + return 0; + + switch (e->left.type) { + case EXPR_SYM: + if (expr_contains_float(symrec_get_equ(e->left.data.sym))) + return 1; + break; + case EXPR_EXPR: + if (expr_contains_float(e->left.data.expn)) + return 1; + break; + case EXPR_FLOAT: + return 1; + case EXPR_INT: + case EXPR_NONE: + break; + } + + switch (e->right.type) { + case EXPR_SYM: + return expr_contains_float(symrec_get_equ(e->right.data.sym)); + case EXPR_EXPR: + return expr_contains_float(e->right.data.expn); + case EXPR_FLOAT: + return 1; + case EXPR_INT: + case EXPR_NONE: + break; + } + return 0; +} + /* get rid of unnecessary branches if possible. report. */ int expr_simplify(expr *e) diff --git a/src/expr.c b/src/expr.c index 252065f7..077a45ab 100644 --- a/src/expr.c +++ b/src/expr.c @@ -142,6 +142,42 @@ ExprFloat(floatnum *f) return e; } +int +expr_contains_float(const expr *e) +{ + if (!e) + return 0; + + switch (e->left.type) { + case EXPR_SYM: + if (expr_contains_float(symrec_get_equ(e->left.data.sym))) + return 1; + break; + case EXPR_EXPR: + if (expr_contains_float(e->left.data.expn)) + return 1; + break; + case EXPR_FLOAT: + return 1; + case EXPR_INT: + case EXPR_NONE: + break; + } + + switch (e->right.type) { + case EXPR_SYM: + return expr_contains_float(symrec_get_equ(e->right.data.sym)); + case EXPR_EXPR: + return expr_contains_float(e->right.data.expn); + case EXPR_FLOAT: + return 1; + case EXPR_INT: + case EXPR_NONE: + break; + } + return 0; +} + /* get rid of unnecessary branches if possible. report. */ int expr_simplify(expr *e) diff --git a/src/expr.h b/src/expr.h index 8adad2db..17b0a11a 100644 --- a/src/expr.h +++ b/src/expr.h @@ -88,6 +88,8 @@ ExprItem *ExprFloat(floatnum *); #define expr_new_ident(r) \ expr_new ((ExprItem *)NULL, EXPR_IDENT, (r)) +int expr_contains_float(const expr *); + int expr_simplify(expr *); void expr_print(expr *); diff --git a/src/parsers/nasm/bison.y.in b/src/parsers/nasm/bison.y.in index d246fe04..32ebf299 100644 --- a/src/parsers/nasm/bison.y.in +++ b/src/parsers/nasm/bison.y.in @@ -111,13 +111,13 @@ static bytecode *nasm_parser_temp_bc; %type line lineexp exp instr instrbase %type fpureg reg32 reg16 reg8 segreg -%type mem memaddr memexp memfar +%type mem memaddr memfar %type mem8x mem16x mem32x mem64x mem80x mem128x %type mem8 mem16 mem32 mem64 mem80 mem128 mem1632 %type rm8x rm16x rm32x /*rm64x rm128x*/ %type rm8 rm16 rm32 rm64 rm128 %type imm imm8x imm16x imm32x imm8 imm16 imm32 -%type expr expr_no_string expr_no_fltstr +%type expr expr_no_string memexpr %type explabel %type label_id %type target @@ -154,10 +154,10 @@ line: '\n' { $$ = (bytecode *)NULL; } ; lineexp: exp - | TIMES expr_no_fltstr exp { $$ = $3; SetBCMultiple($$, $2); } + | TIMES expr exp { $$ = $3; SetBCMultiple($$, $2); } | label { $$ = (bytecode *)NULL; } | label exp { $$ = $2; } - | label TIMES expr_no_fltstr exp { $$ = $4; SetBCMultiple($$, $3); } + | label TIMES expr exp { $$ = $4; SetBCMultiple($$, $3); } | label_id EQU expr { symrec_define_equ($1, $3); $$ = (bytecode *)NULL; @@ -166,7 +166,7 @@ lineexp: exp exp: instr | DECLARE_DATA datavals { $$ = bytecode_new_data(&$2, $1); } - | RESERVE_SPACE expr_no_fltstr { $$ = bytecode_new_reserve($2, $1); } + | RESERVE_SPACE expr { $$ = bytecode_new_reserve($2, $1); } ; datavals: dataval { @@ -265,10 +265,10 @@ segreg: REG_ES ; /* memory addresses */ -memexp: expr { $$ = effaddr_new_expr($1); } +memexpr: expr ; -memaddr: memexp { $$ = $1; SetEASegment($$, 0); } +memaddr: memexpr { $$ = effaddr_new_expr($1); SetEASegment($$, 0); } | REG_CS ':' memaddr { $$ = $3; SetEASegment($$, 0x2E); } | REG_SS ':' memaddr { $$ = $3; SetEASegment($$, 0x36); } | REG_DS ':' memaddr { $$ = $3; SetEASegment($$, 0x3E); } @@ -387,17 +387,14 @@ imm32: imm ; /* jump targets */ -target: expr_no_fltstr { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); } +target: expr { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); } | SHORT target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_SHORT_FORCED); } | NEAR target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_NEAR_FORCED); } ; /* expression trees */ -expr_no_string: expr_no_fltstr +expr_no_string: INTNUM { $$ = expr_new_ident(ExprInt($1)); } | FLTNUM { $$ = expr_new_ident(ExprFloat($1)); } -; - -expr_no_fltstr: INTNUM { $$ = expr_new_ident(ExprInt($1)); } | explabel { $$ = expr_new_ident(ExprSym($1)); } /*| expr '||' expr { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/ | expr '|' expr { $$ = expr_new_tree($1, EXPR_OR, $3); } diff --git a/src/parsers/nasm/nasm-bison.y b/src/parsers/nasm/nasm-bison.y index d246fe04..32ebf299 100644 --- a/src/parsers/nasm/nasm-bison.y +++ b/src/parsers/nasm/nasm-bison.y @@ -111,13 +111,13 @@ static bytecode *nasm_parser_temp_bc; %type line lineexp exp instr instrbase %type fpureg reg32 reg16 reg8 segreg -%type mem memaddr memexp memfar +%type mem memaddr memfar %type mem8x mem16x mem32x mem64x mem80x mem128x %type mem8 mem16 mem32 mem64 mem80 mem128 mem1632 %type rm8x rm16x rm32x /*rm64x rm128x*/ %type rm8 rm16 rm32 rm64 rm128 %type imm imm8x imm16x imm32x imm8 imm16 imm32 -%type expr expr_no_string expr_no_fltstr +%type expr expr_no_string memexpr %type explabel %type label_id %type target @@ -154,10 +154,10 @@ line: '\n' { $$ = (bytecode *)NULL; } ; lineexp: exp - | TIMES expr_no_fltstr exp { $$ = $3; SetBCMultiple($$, $2); } + | TIMES expr exp { $$ = $3; SetBCMultiple($$, $2); } | label { $$ = (bytecode *)NULL; } | label exp { $$ = $2; } - | label TIMES expr_no_fltstr exp { $$ = $4; SetBCMultiple($$, $3); } + | label TIMES expr exp { $$ = $4; SetBCMultiple($$, $3); } | label_id EQU expr { symrec_define_equ($1, $3); $$ = (bytecode *)NULL; @@ -166,7 +166,7 @@ lineexp: exp exp: instr | DECLARE_DATA datavals { $$ = bytecode_new_data(&$2, $1); } - | RESERVE_SPACE expr_no_fltstr { $$ = bytecode_new_reserve($2, $1); } + | RESERVE_SPACE expr { $$ = bytecode_new_reserve($2, $1); } ; datavals: dataval { @@ -265,10 +265,10 @@ segreg: REG_ES ; /* memory addresses */ -memexp: expr { $$ = effaddr_new_expr($1); } +memexpr: expr ; -memaddr: memexp { $$ = $1; SetEASegment($$, 0); } +memaddr: memexpr { $$ = effaddr_new_expr($1); SetEASegment($$, 0); } | REG_CS ':' memaddr { $$ = $3; SetEASegment($$, 0x2E); } | REG_SS ':' memaddr { $$ = $3; SetEASegment($$, 0x36); } | REG_DS ':' memaddr { $$ = $3; SetEASegment($$, 0x3E); } @@ -387,17 +387,14 @@ imm32: imm ; /* jump targets */ -target: expr_no_fltstr { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); } +target: expr { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); } | SHORT target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_SHORT_FORCED); } | NEAR target { $$ = $2; SetOpcodeSel(&$$.op_sel, JR_NEAR_FORCED); } ; /* expression trees */ -expr_no_string: expr_no_fltstr +expr_no_string: INTNUM { $$ = expr_new_ident(ExprInt($1)); } | FLTNUM { $$ = expr_new_ident(ExprFloat($1)); } -; - -expr_no_fltstr: INTNUM { $$ = expr_new_ident(ExprInt($1)); } | explabel { $$ = expr_new_ident(ExprSym($1)); } /*| expr '||' expr { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/ | expr '|' expr { $$ = expr_new_tree($1, EXPR_OR, $3); } diff --git a/src/symrec.c b/src/symrec.c index d18f352e..1f800b2c 100644 --- a/src/symrec.c +++ b/src/symrec.c @@ -229,6 +229,14 @@ symrec_get_name(const symrec *sym) return sym->name; } +const expr * +symrec_get_equ(const symrec *sym) +{ + if (sym->type == SYM_EQU) + return sym->value.expn; + return (const expr *)NULL; +} + void symrec_print(const symrec *sym) { diff --git a/src/symrec.h b/src/symrec.h index 2f136021..de22e6fc 100644 --- a/src/symrec.h +++ b/src/symrec.h @@ -67,6 +67,8 @@ int symrec_get_int_value(const symrec *sym, unsigned long *ret_val, const char *symrec_get_name(const symrec *sym); +const expr *symrec_get_equ(const symrec *sym); + int symrec_foreach(int (*func) (symrec *sym)); void symrec_print(const symrec *sym);