From: Michael Urman Date: Fri, 6 Jul 2001 06:25:53 +0000 (-0000) Subject: Integrate expression handling into memory address expressions. X-Git-Tag: v0.1.0~394 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c4d985f1ad8f078dba8cf20a65899701728d5acf;p=yasm Integrate expression handling into memory address expressions. Consequently change Imm->EA, and update DebugPrintBC (fix segvs too) svn path=/trunk/yasm/; revision=117 --- diff --git a/include/bytecode.h b/include/bytecode.h index 47deb2c0..d7c89f59 100644 --- a/include/bytecode.h +++ b/include/bytecode.h @@ -1,4 +1,4 @@ -/* $Id: bytecode.h,v 1.11 2001/07/05 08:59:29 mu Exp $ +/* $Id: bytecode.h,v 1.12 2001/07/06 06:25:53 mu Exp $ * Bytecode utility functions header file * * Copyright (C) 2001 Peter Johnson @@ -23,7 +23,7 @@ #define YASM_BYTECODE_H typedef struct effaddr_s { - unsigned long disp; /* address displacement */ + struct expr_s *disp; /* address displacement */ unsigned char len; /* length of disp (in bytes), 0 if none */ unsigned char segment; /* segment override, 0 if none */ @@ -86,6 +86,7 @@ typedef struct bytecode_s { effaddr *ConvertIntToEA(effaddr *ptr, unsigned long int_val); effaddr *ConvertRegToEA(effaddr *ptr, unsigned long reg); effaddr *ConvertImmToEA(effaddr *ptr, immval *im_ptr, unsigned char im_len); +effaddr *ConvertExprToEA(effaddr *ptr, struct expr_s *expr_ptr); immval *ConvertIntToImm(immval *ptr, unsigned long int_val); immval *ConvertExprToImm(immval *ptr, struct expr_s *expr_ptr); diff --git a/libyasm/bytecode.c b/libyasm/bytecode.c index cec7f61d..a180aed1 100644 --- a/libyasm/bytecode.c +++ b/libyasm/bytecode.c @@ -1,4 +1,4 @@ -/* $Id: bytecode.c,v 1.10 2001/07/05 09:32:58 mu Exp $ +/* $Id: bytecode.c,v 1.11 2001/07/06 06:25:53 mu Exp $ * Bytecode utility functions * * Copyright (C) 2001 Peter Johnson @@ -41,7 +41,8 @@ effaddr *ConvertIntToEA(effaddr *ptr, unsigned long int_val) ptr->valid_sib = 0; ptr->need_sib = 0; - ptr->disp = int_val; + /* FIXME: this will leak expr's if static is used */ + ptr->disp = expr_new_ident(EXPR_NUM, ExprNum(int_val)); if((int_val & 0xFF) == int_val) ptr->len = 1; @@ -69,14 +70,29 @@ effaddr *ConvertRegToEA(effaddr *ptr, unsigned long reg) return ptr; } +effaddr *ConvertExprToEA(effaddr *ptr, expr *expr_ptr) +{ + if(!ptr) + ptr = &eff_static; + + ptr->segment = 0; + + ptr->valid_modrm = 0; + ptr->need_modrm = 1; + ptr->valid_sib = 0; + ptr->need_sib = 0; + + ptr->disp = expr_ptr; + + return ptr; +} + effaddr *ConvertImmToEA(effaddr *ptr, immval *im_ptr, unsigned char im_len) { - int gotexprval; if(!ptr) ptr = &eff_static; - /* FIXME: warn when gotexprval is 0, and/or die */ - gotexprval = expr_get_value (im_ptr->val, &ptr->disp); + ptr->disp = im_ptr->val; if(im_ptr->len > im_len) Warning(WARN_VALUE_EXCEEDS_BOUNDS, (char *)NULL, "word"); ptr->len = im_len; @@ -245,7 +261,13 @@ void DebugPrintBC(bytecode *bc) case BC_INSN: printf("_Instruction_\n"); printf("Effective Address:\n"); - printf(" Disp=%lx Len=%u SegmentOv=%2x\n", bc->data.insn.ea.disp, + printf(" Disp="); + if (!bc->data.insn.ea.disp) + printf("(nil)"); + else + expr_print(bc->data.insn.ea.disp); + printf("\n"); + printf (" Len=%u SegmentOv=%2x\n", (unsigned int)bc->data.insn.ea.len, (unsigned int)bc->data.insn.ea.segment); printf(" ModRM=%2x ValidRM=%u NeedRM=%u\n", @@ -258,7 +280,10 @@ void DebugPrintBC(bytecode *bc) (unsigned int)bc->data.insn.ea.need_sib); printf("Immediate/Relative Value:\n"); printf(" Val="); - expr_print(bc->data.insn.imm.val); + if (!bc->data.insn.imm.val) + printf("(nil)"); + else + expr_print(bc->data.insn.imm.val); printf("\n"); printf(" Len=%u, IsRel=%u, IsNeg=%u\n", (unsigned int)bc->data.insn.imm.len, diff --git a/libyasm/bytecode.h b/libyasm/bytecode.h index 47deb2c0..d7c89f59 100644 --- a/libyasm/bytecode.h +++ b/libyasm/bytecode.h @@ -1,4 +1,4 @@ -/* $Id: bytecode.h,v 1.11 2001/07/05 08:59:29 mu Exp $ +/* $Id: bytecode.h,v 1.12 2001/07/06 06:25:53 mu Exp $ * Bytecode utility functions header file * * Copyright (C) 2001 Peter Johnson @@ -23,7 +23,7 @@ #define YASM_BYTECODE_H typedef struct effaddr_s { - unsigned long disp; /* address displacement */ + struct expr_s *disp; /* address displacement */ unsigned char len; /* length of disp (in bytes), 0 if none */ unsigned char segment; /* segment override, 0 if none */ @@ -86,6 +86,7 @@ typedef struct bytecode_s { effaddr *ConvertIntToEA(effaddr *ptr, unsigned long int_val); effaddr *ConvertRegToEA(effaddr *ptr, unsigned long reg); effaddr *ConvertImmToEA(effaddr *ptr, immval *im_ptr, unsigned char im_len); +effaddr *ConvertExprToEA(effaddr *ptr, struct expr_s *expr_ptr); immval *ConvertIntToImm(immval *ptr, unsigned long int_val); immval *ConvertExprToImm(immval *ptr, struct expr_s *expr_ptr); diff --git a/modules/parsers/nasm/bison.y.in b/modules/parsers/nasm/bison.y.in index 0c155b22..911a6c41 100644 --- a/modules/parsers/nasm/bison.y.in +++ b/modules/parsers/nasm/bison.y.in @@ -1,4 +1,4 @@ -/* $Id: bison.y.in,v 1.18 2001/07/05 09:50:51 peter Exp $ +/* $Id: bison.y.in,v 1.19 2001/07/06 06:25:53 mu Exp $ * Main bison parser * * Copyright (C) 2001 Peter Johnson, Michael Urman @@ -86,8 +86,8 @@ extern void yyerror(char *); %type rm8x rm16x rm32x /*rm64x rm128x*/ %type rm8 rm16 rm32 rm64 rm128 %type imm imm8x imm16x imm32x imm8 imm16 imm32 -%type immexp -%type immlabel +%type expr +%type explabel %type label_id %left '|' @@ -183,8 +183,7 @@ segreg: REG_ES ; /* memory addresses */ -/* TODO: formula expansion */ -memexp: INTNUM { (void)ConvertIntToEA(&$$, $1); } +memexp: expr { expr_simplify ($1); ConvertExprToEA (&$$, $1); } ; memaddr: memexp { $$ = $1; $$.segment = 0; } @@ -279,37 +278,7 @@ rm128: XMMREG { (void)ConvertRegToEA(&$$, $1); } ; /* immediate values */ -/* TODO: formula expansion */ -immexp: /*INTNUM { (void)ConvertIntToImm(&$$, $1); } */ - INTNUM { $$ = expr_new_ident (EXPR_NUM, ExprNum($1)); } - | immlabel { $$ = expr_new_ident (EXPR_SYM, ExprSym(sym_use_get ($1.name, SYM_LABEL))); } - /*| immexp '||' immexp { $$ = expr_new_tree ($1, EXPR_LOR, $3); }*/ - | immexp '|' immexp { $$ = expr_new_tree ($1, EXPR_OR, $3); } - | immexp '^' immexp { $$ = expr_new_tree ($1, EXPR_XOR, $3); } - /*| immexp '&&' immexp { $$ = expr_new_tree ($1, EXPR_LAND, $3); }*/ - | immexp '&' immexp { $$ = expr_new_tree ($1, EXPR_AND, $3); } - /*| immexp '==' immexp { $$ = expr_new_tree ($1, EXPR_EQUALS, $3); }*/ - /*| immexp '>' immexp { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/ - /*| immexp '<' immexp { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/ - /*| immexp '>=' immexp { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/ - /*| immexp '<=' immexp { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/ - /*| immexp '!=' immexp { $$ = expr_new_tree ($1, EXPR_NE, $3); }*/ - | immexp LEFT_OP immexp { $$ = expr_new_tree ($1, EXPR_SHL, $3); } - | immexp RIGHT_OP immexp { $$ = expr_new_tree ($1, EXPR_SHR, $3); } - | immexp '+' immexp { $$ = expr_new_tree ($1, EXPR_ADD, $3); } - | immexp '-' immexp { $$ = expr_new_tree ($1, EXPR_SUB, $3); } - | immexp '*' immexp { $$ = expr_new_tree ($1, EXPR_MUL, $3); } - | immexp '/' immexp { $$ = expr_new_tree ($1, EXPR_DIV, $3); } - | immexp '%' immexp { $$ = expr_new_tree ($1, EXPR_MOD, $3); } - | '-' immexp { $$ = expr_new_branch (EXPR_NEG, $2); } - /*| '!' immexp { $$ = expr_new_branch (EXPR_LNOT, $2); }*/ - | '~' immexp { $$ = expr_new_branch (EXPR_NOT, $2); } - | '(' immexp ')' { $$ = $2; } -; - -immlabel: ID | SPECIAL_ID | LOCAL_ID ; - -imm: immexp { expr_simplify ($1); ConvertExprToImm (&$$, $1); } +imm: expr { expr_simplify ($1); ConvertExprToImm (&$$, $1); } ; /* explicit immediates */ @@ -331,6 +300,36 @@ imm32: imm | imm32x ; +/* expression trees */ +expr: + INTNUM { $$ = expr_new_ident (EXPR_NUM, ExprNum($1)); } + | explabel { $$ = expr_new_ident (EXPR_SYM, ExprSym(sym_use_get ($1.name, SYM_LABEL))); } + /*| expr '||' expr { $$ = expr_new_tree ($1, EXPR_LOR, $3); }*/ + | expr '|' expr { $$ = expr_new_tree ($1, EXPR_OR, $3); } + | expr '^' expr { $$ = expr_new_tree ($1, EXPR_XOR, $3); } + /*| expr '&&' expr { $$ = expr_new_tree ($1, EXPR_LAND, $3); }*/ + | expr '&' expr { $$ = expr_new_tree ($1, EXPR_AND, $3); } + /*| expr '==' expr { $$ = expr_new_tree ($1, EXPR_EQUALS, $3); }*/ + /*| expr '>' expr { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/ + /*| expr '<' expr { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/ + /*| expr '>=' expr { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/ + /*| expr '<=' expr { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/ + /*| expr '!=' expr { $$ = expr_new_tree ($1, EXPR_NE, $3); }*/ + | expr LEFT_OP expr { $$ = expr_new_tree ($1, EXPR_SHL, $3); } + | expr RIGHT_OP expr { $$ = expr_new_tree ($1, EXPR_SHR, $3); } + | expr '+' expr { $$ = expr_new_tree ($1, EXPR_ADD, $3); } + | expr '-' expr { $$ = expr_new_tree ($1, EXPR_SUB, $3); } + | expr '*' expr { $$ = expr_new_tree ($1, EXPR_MUL, $3); } + | expr '/' expr { $$ = expr_new_tree ($1, EXPR_DIV, $3); } + | expr '%' expr { $$ = expr_new_tree ($1, EXPR_MOD, $3); } + | '-' expr { $$ = expr_new_branch (EXPR_NEG, $2); } + /*| '!' expr { $$ = expr_new_branch (EXPR_LNOT, $2); }*/ + | '~' expr { $$ = expr_new_branch (EXPR_NOT, $2); } + | '(' expr ')' { $$ = $2; } +; + +explabel: ID | SPECIAL_ID | LOCAL_ID ; + instr: instrbase | OPERSIZE instr { $$ = $2; SetInsnOperSizeOverride(&$$, $1); } | ADDRSIZE instr { $$ = $2; SetInsnAddrSizeOverride(&$$, $1); } diff --git a/modules/parsers/nasm/nasm-bison.y b/modules/parsers/nasm/nasm-bison.y index f3132d3a..97609a3a 100644 --- a/modules/parsers/nasm/nasm-bison.y +++ b/modules/parsers/nasm/nasm-bison.y @@ -1,4 +1,4 @@ -/* $Id: nasm-bison.y,v 1.18 2001/07/05 09:50:51 peter Exp $ +/* $Id: nasm-bison.y,v 1.19 2001/07/06 06:25:53 mu Exp $ * Main bison parser * * Copyright (C) 2001 Peter Johnson, Michael Urman @@ -86,8 +86,8 @@ extern void yyerror(char *); %type rm8x rm16x rm32x /*rm64x rm128x*/ %type rm8 rm16 rm32 rm64 rm128 %type imm imm8x imm16x imm32x imm8 imm16 imm32 -%type immexp -%type immlabel +%type expr +%type explabel %type label_id %left '|' @@ -183,8 +183,7 @@ segreg: REG_ES ; /* memory addresses */ -/* TODO: formula expansion */ -memexp: INTNUM { (void)ConvertIntToEA(&$$, $1); } +memexp: expr { expr_simplify ($1); ConvertExprToEA (&$$, $1); } ; memaddr: memexp { $$ = $1; $$.segment = 0; } @@ -279,37 +278,7 @@ rm128: XMMREG { (void)ConvertRegToEA(&$$, $1); } ; /* immediate values */ -/* TODO: formula expansion */ -immexp: /*INTNUM { (void)ConvertIntToImm(&$$, $1); } */ - INTNUM { $$ = expr_new_ident (EXPR_NUM, ExprNum($1)); } - | immlabel { $$ = expr_new_ident (EXPR_SYM, ExprSym(sym_use_get ($1.name, SYM_LABEL))); } - /*| immexp '||' immexp { $$ = expr_new_tree ($1, EXPR_LOR, $3); }*/ - | immexp '|' immexp { $$ = expr_new_tree ($1, EXPR_OR, $3); } - | immexp '^' immexp { $$ = expr_new_tree ($1, EXPR_XOR, $3); } - /*| immexp '&&' immexp { $$ = expr_new_tree ($1, EXPR_LAND, $3); }*/ - | immexp '&' immexp { $$ = expr_new_tree ($1, EXPR_AND, $3); } - /*| immexp '==' immexp { $$ = expr_new_tree ($1, EXPR_EQUALS, $3); }*/ - /*| immexp '>' immexp { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/ - /*| immexp '<' immexp { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/ - /*| immexp '>=' immexp { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/ - /*| immexp '<=' immexp { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/ - /*| immexp '!=' immexp { $$ = expr_new_tree ($1, EXPR_NE, $3); }*/ - | immexp LEFT_OP immexp { $$ = expr_new_tree ($1, EXPR_SHL, $3); } - | immexp RIGHT_OP immexp { $$ = expr_new_tree ($1, EXPR_SHR, $3); } - | immexp '+' immexp { $$ = expr_new_tree ($1, EXPR_ADD, $3); } - | immexp '-' immexp { $$ = expr_new_tree ($1, EXPR_SUB, $3); } - | immexp '*' immexp { $$ = expr_new_tree ($1, EXPR_MUL, $3); } - | immexp '/' immexp { $$ = expr_new_tree ($1, EXPR_DIV, $3); } - | immexp '%' immexp { $$ = expr_new_tree ($1, EXPR_MOD, $3); } - | '-' immexp { $$ = expr_new_branch (EXPR_NEG, $2); } - /*| '!' immexp { $$ = expr_new_branch (EXPR_LNOT, $2); }*/ - | '~' immexp { $$ = expr_new_branch (EXPR_NOT, $2); } - | '(' immexp ')' { $$ = $2; } -; - -immlabel: ID | SPECIAL_ID | LOCAL_ID ; - -imm: immexp { expr_simplify ($1); ConvertExprToImm (&$$, $1); } +imm: expr { expr_simplify ($1); ConvertExprToImm (&$$, $1); } ; /* explicit immediates */ @@ -331,6 +300,36 @@ imm32: imm | imm32x ; +/* expression trees */ +expr: + INTNUM { $$ = expr_new_ident (EXPR_NUM, ExprNum($1)); } + | explabel { $$ = expr_new_ident (EXPR_SYM, ExprSym(sym_use_get ($1.name, SYM_LABEL))); } + /*| expr '||' expr { $$ = expr_new_tree ($1, EXPR_LOR, $3); }*/ + | expr '|' expr { $$ = expr_new_tree ($1, EXPR_OR, $3); } + | expr '^' expr { $$ = expr_new_tree ($1, EXPR_XOR, $3); } + /*| expr '&&' expr { $$ = expr_new_tree ($1, EXPR_LAND, $3); }*/ + | expr '&' expr { $$ = expr_new_tree ($1, EXPR_AND, $3); } + /*| expr '==' expr { $$ = expr_new_tree ($1, EXPR_EQUALS, $3); }*/ + /*| expr '>' expr { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/ + /*| expr '<' expr { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/ + /*| expr '>=' expr { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/ + /*| expr '<=' expr { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/ + /*| expr '!=' expr { $$ = expr_new_tree ($1, EXPR_NE, $3); }*/ + | expr LEFT_OP expr { $$ = expr_new_tree ($1, EXPR_SHL, $3); } + | expr RIGHT_OP expr { $$ = expr_new_tree ($1, EXPR_SHR, $3); } + | expr '+' expr { $$ = expr_new_tree ($1, EXPR_ADD, $3); } + | expr '-' expr { $$ = expr_new_tree ($1, EXPR_SUB, $3); } + | expr '*' expr { $$ = expr_new_tree ($1, EXPR_MUL, $3); } + | expr '/' expr { $$ = expr_new_tree ($1, EXPR_DIV, $3); } + | expr '%' expr { $$ = expr_new_tree ($1, EXPR_MOD, $3); } + | '-' expr { $$ = expr_new_branch (EXPR_NEG, $2); } + /*| '!' expr { $$ = expr_new_branch (EXPR_LNOT, $2); }*/ + | '~' expr { $$ = expr_new_branch (EXPR_NOT, $2); } + | '(' expr ')' { $$ = $2; } +; + +explabel: ID | SPECIAL_ID | LOCAL_ID ; + instr: instrbase | OPERSIZE instr { $$ = $2; SetInsnOperSizeOverride(&$$, $1); } | ADDRSIZE instr { $$ = $2; SetInsnAddrSizeOverride(&$$, $1); } diff --git a/src/bison.y.in b/src/bison.y.in index 0c155b22..911a6c41 100644 --- a/src/bison.y.in +++ b/src/bison.y.in @@ -1,4 +1,4 @@ -/* $Id: bison.y.in,v 1.18 2001/07/05 09:50:51 peter Exp $ +/* $Id: bison.y.in,v 1.19 2001/07/06 06:25:53 mu Exp $ * Main bison parser * * Copyright (C) 2001 Peter Johnson, Michael Urman @@ -86,8 +86,8 @@ extern void yyerror(char *); %type rm8x rm16x rm32x /*rm64x rm128x*/ %type rm8 rm16 rm32 rm64 rm128 %type imm imm8x imm16x imm32x imm8 imm16 imm32 -%type immexp -%type immlabel +%type expr +%type explabel %type label_id %left '|' @@ -183,8 +183,7 @@ segreg: REG_ES ; /* memory addresses */ -/* TODO: formula expansion */ -memexp: INTNUM { (void)ConvertIntToEA(&$$, $1); } +memexp: expr { expr_simplify ($1); ConvertExprToEA (&$$, $1); } ; memaddr: memexp { $$ = $1; $$.segment = 0; } @@ -279,37 +278,7 @@ rm128: XMMREG { (void)ConvertRegToEA(&$$, $1); } ; /* immediate values */ -/* TODO: formula expansion */ -immexp: /*INTNUM { (void)ConvertIntToImm(&$$, $1); } */ - INTNUM { $$ = expr_new_ident (EXPR_NUM, ExprNum($1)); } - | immlabel { $$ = expr_new_ident (EXPR_SYM, ExprSym(sym_use_get ($1.name, SYM_LABEL))); } - /*| immexp '||' immexp { $$ = expr_new_tree ($1, EXPR_LOR, $3); }*/ - | immexp '|' immexp { $$ = expr_new_tree ($1, EXPR_OR, $3); } - | immexp '^' immexp { $$ = expr_new_tree ($1, EXPR_XOR, $3); } - /*| immexp '&&' immexp { $$ = expr_new_tree ($1, EXPR_LAND, $3); }*/ - | immexp '&' immexp { $$ = expr_new_tree ($1, EXPR_AND, $3); } - /*| immexp '==' immexp { $$ = expr_new_tree ($1, EXPR_EQUALS, $3); }*/ - /*| immexp '>' immexp { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/ - /*| immexp '<' immexp { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/ - /*| immexp '>=' immexp { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/ - /*| immexp '<=' immexp { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/ - /*| immexp '!=' immexp { $$ = expr_new_tree ($1, EXPR_NE, $3); }*/ - | immexp LEFT_OP immexp { $$ = expr_new_tree ($1, EXPR_SHL, $3); } - | immexp RIGHT_OP immexp { $$ = expr_new_tree ($1, EXPR_SHR, $3); } - | immexp '+' immexp { $$ = expr_new_tree ($1, EXPR_ADD, $3); } - | immexp '-' immexp { $$ = expr_new_tree ($1, EXPR_SUB, $3); } - | immexp '*' immexp { $$ = expr_new_tree ($1, EXPR_MUL, $3); } - | immexp '/' immexp { $$ = expr_new_tree ($1, EXPR_DIV, $3); } - | immexp '%' immexp { $$ = expr_new_tree ($1, EXPR_MOD, $3); } - | '-' immexp { $$ = expr_new_branch (EXPR_NEG, $2); } - /*| '!' immexp { $$ = expr_new_branch (EXPR_LNOT, $2); }*/ - | '~' immexp { $$ = expr_new_branch (EXPR_NOT, $2); } - | '(' immexp ')' { $$ = $2; } -; - -immlabel: ID | SPECIAL_ID | LOCAL_ID ; - -imm: immexp { expr_simplify ($1); ConvertExprToImm (&$$, $1); } +imm: expr { expr_simplify ($1); ConvertExprToImm (&$$, $1); } ; /* explicit immediates */ @@ -331,6 +300,36 @@ imm32: imm | imm32x ; +/* expression trees */ +expr: + INTNUM { $$ = expr_new_ident (EXPR_NUM, ExprNum($1)); } + | explabel { $$ = expr_new_ident (EXPR_SYM, ExprSym(sym_use_get ($1.name, SYM_LABEL))); } + /*| expr '||' expr { $$ = expr_new_tree ($1, EXPR_LOR, $3); }*/ + | expr '|' expr { $$ = expr_new_tree ($1, EXPR_OR, $3); } + | expr '^' expr { $$ = expr_new_tree ($1, EXPR_XOR, $3); } + /*| expr '&&' expr { $$ = expr_new_tree ($1, EXPR_LAND, $3); }*/ + | expr '&' expr { $$ = expr_new_tree ($1, EXPR_AND, $3); } + /*| expr '==' expr { $$ = expr_new_tree ($1, EXPR_EQUALS, $3); }*/ + /*| expr '>' expr { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/ + /*| expr '<' expr { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/ + /*| expr '>=' expr { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/ + /*| expr '<=' expr { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/ + /*| expr '!=' expr { $$ = expr_new_tree ($1, EXPR_NE, $3); }*/ + | expr LEFT_OP expr { $$ = expr_new_tree ($1, EXPR_SHL, $3); } + | expr RIGHT_OP expr { $$ = expr_new_tree ($1, EXPR_SHR, $3); } + | expr '+' expr { $$ = expr_new_tree ($1, EXPR_ADD, $3); } + | expr '-' expr { $$ = expr_new_tree ($1, EXPR_SUB, $3); } + | expr '*' expr { $$ = expr_new_tree ($1, EXPR_MUL, $3); } + | expr '/' expr { $$ = expr_new_tree ($1, EXPR_DIV, $3); } + | expr '%' expr { $$ = expr_new_tree ($1, EXPR_MOD, $3); } + | '-' expr { $$ = expr_new_branch (EXPR_NEG, $2); } + /*| '!' expr { $$ = expr_new_branch (EXPR_LNOT, $2); }*/ + | '~' expr { $$ = expr_new_branch (EXPR_NOT, $2); } + | '(' expr ')' { $$ = $2; } +; + +explabel: ID | SPECIAL_ID | LOCAL_ID ; + instr: instrbase | OPERSIZE instr { $$ = $2; SetInsnOperSizeOverride(&$$, $1); } | ADDRSIZE instr { $$ = $2; SetInsnAddrSizeOverride(&$$, $1); } diff --git a/src/bytecode.c b/src/bytecode.c index cec7f61d..a180aed1 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -1,4 +1,4 @@ -/* $Id: bytecode.c,v 1.10 2001/07/05 09:32:58 mu Exp $ +/* $Id: bytecode.c,v 1.11 2001/07/06 06:25:53 mu Exp $ * Bytecode utility functions * * Copyright (C) 2001 Peter Johnson @@ -41,7 +41,8 @@ effaddr *ConvertIntToEA(effaddr *ptr, unsigned long int_val) ptr->valid_sib = 0; ptr->need_sib = 0; - ptr->disp = int_val; + /* FIXME: this will leak expr's if static is used */ + ptr->disp = expr_new_ident(EXPR_NUM, ExprNum(int_val)); if((int_val & 0xFF) == int_val) ptr->len = 1; @@ -69,14 +70,29 @@ effaddr *ConvertRegToEA(effaddr *ptr, unsigned long reg) return ptr; } +effaddr *ConvertExprToEA(effaddr *ptr, expr *expr_ptr) +{ + if(!ptr) + ptr = &eff_static; + + ptr->segment = 0; + + ptr->valid_modrm = 0; + ptr->need_modrm = 1; + ptr->valid_sib = 0; + ptr->need_sib = 0; + + ptr->disp = expr_ptr; + + return ptr; +} + effaddr *ConvertImmToEA(effaddr *ptr, immval *im_ptr, unsigned char im_len) { - int gotexprval; if(!ptr) ptr = &eff_static; - /* FIXME: warn when gotexprval is 0, and/or die */ - gotexprval = expr_get_value (im_ptr->val, &ptr->disp); + ptr->disp = im_ptr->val; if(im_ptr->len > im_len) Warning(WARN_VALUE_EXCEEDS_BOUNDS, (char *)NULL, "word"); ptr->len = im_len; @@ -245,7 +261,13 @@ void DebugPrintBC(bytecode *bc) case BC_INSN: printf("_Instruction_\n"); printf("Effective Address:\n"); - printf(" Disp=%lx Len=%u SegmentOv=%2x\n", bc->data.insn.ea.disp, + printf(" Disp="); + if (!bc->data.insn.ea.disp) + printf("(nil)"); + else + expr_print(bc->data.insn.ea.disp); + printf("\n"); + printf (" Len=%u SegmentOv=%2x\n", (unsigned int)bc->data.insn.ea.len, (unsigned int)bc->data.insn.ea.segment); printf(" ModRM=%2x ValidRM=%u NeedRM=%u\n", @@ -258,7 +280,10 @@ void DebugPrintBC(bytecode *bc) (unsigned int)bc->data.insn.ea.need_sib); printf("Immediate/Relative Value:\n"); printf(" Val="); - expr_print(bc->data.insn.imm.val); + if (!bc->data.insn.imm.val) + printf("(nil)"); + else + expr_print(bc->data.insn.imm.val); printf("\n"); printf(" Len=%u, IsRel=%u, IsNeg=%u\n", (unsigned int)bc->data.insn.imm.len, diff --git a/src/bytecode.h b/src/bytecode.h index 47deb2c0..d7c89f59 100644 --- a/src/bytecode.h +++ b/src/bytecode.h @@ -1,4 +1,4 @@ -/* $Id: bytecode.h,v 1.11 2001/07/05 08:59:29 mu Exp $ +/* $Id: bytecode.h,v 1.12 2001/07/06 06:25:53 mu Exp $ * Bytecode utility functions header file * * Copyright (C) 2001 Peter Johnson @@ -23,7 +23,7 @@ #define YASM_BYTECODE_H typedef struct effaddr_s { - unsigned long disp; /* address displacement */ + struct expr_s *disp; /* address displacement */ unsigned char len; /* length of disp (in bytes), 0 if none */ unsigned char segment; /* segment override, 0 if none */ @@ -86,6 +86,7 @@ typedef struct bytecode_s { effaddr *ConvertIntToEA(effaddr *ptr, unsigned long int_val); effaddr *ConvertRegToEA(effaddr *ptr, unsigned long reg); effaddr *ConvertImmToEA(effaddr *ptr, immval *im_ptr, unsigned char im_len); +effaddr *ConvertExprToEA(effaddr *ptr, struct expr_s *expr_ptr); immval *ConvertIntToImm(immval *ptr, unsigned long int_val); immval *ConvertExprToImm(immval *ptr, struct expr_s *expr_ptr); diff --git a/src/parsers/nasm/bison.y.in b/src/parsers/nasm/bison.y.in index 0c155b22..911a6c41 100644 --- a/src/parsers/nasm/bison.y.in +++ b/src/parsers/nasm/bison.y.in @@ -1,4 +1,4 @@ -/* $Id: bison.y.in,v 1.18 2001/07/05 09:50:51 peter Exp $ +/* $Id: bison.y.in,v 1.19 2001/07/06 06:25:53 mu Exp $ * Main bison parser * * Copyright (C) 2001 Peter Johnson, Michael Urman @@ -86,8 +86,8 @@ extern void yyerror(char *); %type rm8x rm16x rm32x /*rm64x rm128x*/ %type rm8 rm16 rm32 rm64 rm128 %type imm imm8x imm16x imm32x imm8 imm16 imm32 -%type immexp -%type immlabel +%type expr +%type explabel %type label_id %left '|' @@ -183,8 +183,7 @@ segreg: REG_ES ; /* memory addresses */ -/* TODO: formula expansion */ -memexp: INTNUM { (void)ConvertIntToEA(&$$, $1); } +memexp: expr { expr_simplify ($1); ConvertExprToEA (&$$, $1); } ; memaddr: memexp { $$ = $1; $$.segment = 0; } @@ -279,37 +278,7 @@ rm128: XMMREG { (void)ConvertRegToEA(&$$, $1); } ; /* immediate values */ -/* TODO: formula expansion */ -immexp: /*INTNUM { (void)ConvertIntToImm(&$$, $1); } */ - INTNUM { $$ = expr_new_ident (EXPR_NUM, ExprNum($1)); } - | immlabel { $$ = expr_new_ident (EXPR_SYM, ExprSym(sym_use_get ($1.name, SYM_LABEL))); } - /*| immexp '||' immexp { $$ = expr_new_tree ($1, EXPR_LOR, $3); }*/ - | immexp '|' immexp { $$ = expr_new_tree ($1, EXPR_OR, $3); } - | immexp '^' immexp { $$ = expr_new_tree ($1, EXPR_XOR, $3); } - /*| immexp '&&' immexp { $$ = expr_new_tree ($1, EXPR_LAND, $3); }*/ - | immexp '&' immexp { $$ = expr_new_tree ($1, EXPR_AND, $3); } - /*| immexp '==' immexp { $$ = expr_new_tree ($1, EXPR_EQUALS, $3); }*/ - /*| immexp '>' immexp { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/ - /*| immexp '<' immexp { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/ - /*| immexp '>=' immexp { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/ - /*| immexp '<=' immexp { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/ - /*| immexp '!=' immexp { $$ = expr_new_tree ($1, EXPR_NE, $3); }*/ - | immexp LEFT_OP immexp { $$ = expr_new_tree ($1, EXPR_SHL, $3); } - | immexp RIGHT_OP immexp { $$ = expr_new_tree ($1, EXPR_SHR, $3); } - | immexp '+' immexp { $$ = expr_new_tree ($1, EXPR_ADD, $3); } - | immexp '-' immexp { $$ = expr_new_tree ($1, EXPR_SUB, $3); } - | immexp '*' immexp { $$ = expr_new_tree ($1, EXPR_MUL, $3); } - | immexp '/' immexp { $$ = expr_new_tree ($1, EXPR_DIV, $3); } - | immexp '%' immexp { $$ = expr_new_tree ($1, EXPR_MOD, $3); } - | '-' immexp { $$ = expr_new_branch (EXPR_NEG, $2); } - /*| '!' immexp { $$ = expr_new_branch (EXPR_LNOT, $2); }*/ - | '~' immexp { $$ = expr_new_branch (EXPR_NOT, $2); } - | '(' immexp ')' { $$ = $2; } -; - -immlabel: ID | SPECIAL_ID | LOCAL_ID ; - -imm: immexp { expr_simplify ($1); ConvertExprToImm (&$$, $1); } +imm: expr { expr_simplify ($1); ConvertExprToImm (&$$, $1); } ; /* explicit immediates */ @@ -331,6 +300,36 @@ imm32: imm | imm32x ; +/* expression trees */ +expr: + INTNUM { $$ = expr_new_ident (EXPR_NUM, ExprNum($1)); } + | explabel { $$ = expr_new_ident (EXPR_SYM, ExprSym(sym_use_get ($1.name, SYM_LABEL))); } + /*| expr '||' expr { $$ = expr_new_tree ($1, EXPR_LOR, $3); }*/ + | expr '|' expr { $$ = expr_new_tree ($1, EXPR_OR, $3); } + | expr '^' expr { $$ = expr_new_tree ($1, EXPR_XOR, $3); } + /*| expr '&&' expr { $$ = expr_new_tree ($1, EXPR_LAND, $3); }*/ + | expr '&' expr { $$ = expr_new_tree ($1, EXPR_AND, $3); } + /*| expr '==' expr { $$ = expr_new_tree ($1, EXPR_EQUALS, $3); }*/ + /*| expr '>' expr { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/ + /*| expr '<' expr { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/ + /*| expr '>=' expr { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/ + /*| expr '<=' expr { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/ + /*| expr '!=' expr { $$ = expr_new_tree ($1, EXPR_NE, $3); }*/ + | expr LEFT_OP expr { $$ = expr_new_tree ($1, EXPR_SHL, $3); } + | expr RIGHT_OP expr { $$ = expr_new_tree ($1, EXPR_SHR, $3); } + | expr '+' expr { $$ = expr_new_tree ($1, EXPR_ADD, $3); } + | expr '-' expr { $$ = expr_new_tree ($1, EXPR_SUB, $3); } + | expr '*' expr { $$ = expr_new_tree ($1, EXPR_MUL, $3); } + | expr '/' expr { $$ = expr_new_tree ($1, EXPR_DIV, $3); } + | expr '%' expr { $$ = expr_new_tree ($1, EXPR_MOD, $3); } + | '-' expr { $$ = expr_new_branch (EXPR_NEG, $2); } + /*| '!' expr { $$ = expr_new_branch (EXPR_LNOT, $2); }*/ + | '~' expr { $$ = expr_new_branch (EXPR_NOT, $2); } + | '(' expr ')' { $$ = $2; } +; + +explabel: ID | SPECIAL_ID | LOCAL_ID ; + instr: instrbase | OPERSIZE instr { $$ = $2; SetInsnOperSizeOverride(&$$, $1); } | ADDRSIZE instr { $$ = $2; SetInsnAddrSizeOverride(&$$, $1); } diff --git a/src/parsers/nasm/nasm-bison.y b/src/parsers/nasm/nasm-bison.y index f3132d3a..97609a3a 100644 --- a/src/parsers/nasm/nasm-bison.y +++ b/src/parsers/nasm/nasm-bison.y @@ -1,4 +1,4 @@ -/* $Id: nasm-bison.y,v 1.18 2001/07/05 09:50:51 peter Exp $ +/* $Id: nasm-bison.y,v 1.19 2001/07/06 06:25:53 mu Exp $ * Main bison parser * * Copyright (C) 2001 Peter Johnson, Michael Urman @@ -86,8 +86,8 @@ extern void yyerror(char *); %type rm8x rm16x rm32x /*rm64x rm128x*/ %type rm8 rm16 rm32 rm64 rm128 %type imm imm8x imm16x imm32x imm8 imm16 imm32 -%type immexp -%type immlabel +%type expr +%type explabel %type label_id %left '|' @@ -183,8 +183,7 @@ segreg: REG_ES ; /* memory addresses */ -/* TODO: formula expansion */ -memexp: INTNUM { (void)ConvertIntToEA(&$$, $1); } +memexp: expr { expr_simplify ($1); ConvertExprToEA (&$$, $1); } ; memaddr: memexp { $$ = $1; $$.segment = 0; } @@ -279,37 +278,7 @@ rm128: XMMREG { (void)ConvertRegToEA(&$$, $1); } ; /* immediate values */ -/* TODO: formula expansion */ -immexp: /*INTNUM { (void)ConvertIntToImm(&$$, $1); } */ - INTNUM { $$ = expr_new_ident (EXPR_NUM, ExprNum($1)); } - | immlabel { $$ = expr_new_ident (EXPR_SYM, ExprSym(sym_use_get ($1.name, SYM_LABEL))); } - /*| immexp '||' immexp { $$ = expr_new_tree ($1, EXPR_LOR, $3); }*/ - | immexp '|' immexp { $$ = expr_new_tree ($1, EXPR_OR, $3); } - | immexp '^' immexp { $$ = expr_new_tree ($1, EXPR_XOR, $3); } - /*| immexp '&&' immexp { $$ = expr_new_tree ($1, EXPR_LAND, $3); }*/ - | immexp '&' immexp { $$ = expr_new_tree ($1, EXPR_AND, $3); } - /*| immexp '==' immexp { $$ = expr_new_tree ($1, EXPR_EQUALS, $3); }*/ - /*| immexp '>' immexp { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/ - /*| immexp '<' immexp { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/ - /*| immexp '>=' immexp { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/ - /*| immexp '<=' immexp { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/ - /*| immexp '!=' immexp { $$ = expr_new_tree ($1, EXPR_NE, $3); }*/ - | immexp LEFT_OP immexp { $$ = expr_new_tree ($1, EXPR_SHL, $3); } - | immexp RIGHT_OP immexp { $$ = expr_new_tree ($1, EXPR_SHR, $3); } - | immexp '+' immexp { $$ = expr_new_tree ($1, EXPR_ADD, $3); } - | immexp '-' immexp { $$ = expr_new_tree ($1, EXPR_SUB, $3); } - | immexp '*' immexp { $$ = expr_new_tree ($1, EXPR_MUL, $3); } - | immexp '/' immexp { $$ = expr_new_tree ($1, EXPR_DIV, $3); } - | immexp '%' immexp { $$ = expr_new_tree ($1, EXPR_MOD, $3); } - | '-' immexp { $$ = expr_new_branch (EXPR_NEG, $2); } - /*| '!' immexp { $$ = expr_new_branch (EXPR_LNOT, $2); }*/ - | '~' immexp { $$ = expr_new_branch (EXPR_NOT, $2); } - | '(' immexp ')' { $$ = $2; } -; - -immlabel: ID | SPECIAL_ID | LOCAL_ID ; - -imm: immexp { expr_simplify ($1); ConvertExprToImm (&$$, $1); } +imm: expr { expr_simplify ($1); ConvertExprToImm (&$$, $1); } ; /* explicit immediates */ @@ -331,6 +300,36 @@ imm32: imm | imm32x ; +/* expression trees */ +expr: + INTNUM { $$ = expr_new_ident (EXPR_NUM, ExprNum($1)); } + | explabel { $$ = expr_new_ident (EXPR_SYM, ExprSym(sym_use_get ($1.name, SYM_LABEL))); } + /*| expr '||' expr { $$ = expr_new_tree ($1, EXPR_LOR, $3); }*/ + | expr '|' expr { $$ = expr_new_tree ($1, EXPR_OR, $3); } + | expr '^' expr { $$ = expr_new_tree ($1, EXPR_XOR, $3); } + /*| expr '&&' expr { $$ = expr_new_tree ($1, EXPR_LAND, $3); }*/ + | expr '&' expr { $$ = expr_new_tree ($1, EXPR_AND, $3); } + /*| expr '==' expr { $$ = expr_new_tree ($1, EXPR_EQUALS, $3); }*/ + /*| expr '>' expr { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/ + /*| expr '<' expr { $$ = expr_new_tree ($1, EXPR_GT, $3); }*/ + /*| expr '>=' expr { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/ + /*| expr '<=' expr { $$ = expr_new_tree ($1, EXPR_GE, $3); }*/ + /*| expr '!=' expr { $$ = expr_new_tree ($1, EXPR_NE, $3); }*/ + | expr LEFT_OP expr { $$ = expr_new_tree ($1, EXPR_SHL, $3); } + | expr RIGHT_OP expr { $$ = expr_new_tree ($1, EXPR_SHR, $3); } + | expr '+' expr { $$ = expr_new_tree ($1, EXPR_ADD, $3); } + | expr '-' expr { $$ = expr_new_tree ($1, EXPR_SUB, $3); } + | expr '*' expr { $$ = expr_new_tree ($1, EXPR_MUL, $3); } + | expr '/' expr { $$ = expr_new_tree ($1, EXPR_DIV, $3); } + | expr '%' expr { $$ = expr_new_tree ($1, EXPR_MOD, $3); } + | '-' expr { $$ = expr_new_branch (EXPR_NEG, $2); } + /*| '!' expr { $$ = expr_new_branch (EXPR_LNOT, $2); }*/ + | '~' expr { $$ = expr_new_branch (EXPR_NOT, $2); } + | '(' expr ')' { $$ = $2; } +; + +explabel: ID | SPECIAL_ID | LOCAL_ID ; + instr: instrbase | OPERSIZE instr { $$ = $2; SetInsnOperSizeOverride(&$$, $1); } | ADDRSIZE instr { $$ = $2; SetInsnAddrSizeOverride(&$$, $1); }