]> granicus.if.org Git - yasm/commitdiff
Add first version of post-parsing bytecode finalization. Lots of work still
authorPeter Johnson <peter@tortall.net>
Mon, 15 Oct 2001 04:42:47 +0000 (04:42 -0000)
committerPeter Johnson <peter@tortall.net>
Mon, 15 Oct 2001 04:42:47 +0000 (04:42 -0000)
to be done at the bytecode and expression level.

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

frontends/yasm/yasm.c
libyasm/bytecode.c
libyasm/bytecode.h
libyasm/section.c
libyasm/section.h
src/bytecode.c
src/bytecode.h
src/main.c
src/section.c
src/section.h

index 6cad2ab297c7ff13530c99511277d709af5bbee7..f08c483f118228e3387f58bc977adb1e1d085b7a 100644 (file)
@@ -135,6 +135,11 @@ main(int argc, char *argv[])
     printf("\n***Symbol Table***\n");
     symrec_foreach((int (*) (symrec *))symrec_print);
 
+    sections_parser_finalize(sections);
+
+    printf("Post-parser-finalization:\n");
+    sections_print(sections);
+
     if (in_filename)
        free(in_filename);
     return EXIT_SUCCESS;
index 346c82fc8cd07525667ebeff6afa170a58adf474..3bac66a8d45375780e2869f8eab148497a6c10f4 100644 (file)
@@ -113,7 +113,7 @@ struct bytecode {
            unsigned char opcode[3];    /* opcode */
            unsigned char opcode_len;
 
-           unsigned char addrsize;     /* 0 indicates no override */
+           unsigned char addrsize;     /* 0 or =mode_bits => no override */
            unsigned char opersize;     /* 0 indicates no override */
            unsigned char lockrep_pre;  /* 0 indicates no prefix */
 
@@ -144,7 +144,7 @@ struct bytecode {
            /* The *FORCED forms are specified in the source as such */
            jmprel_opcode_sel op_sel;
 
-           unsigned char addrsize;     /* 0 indicates no override */
+           unsigned char addrsize;     /* 0 or =mode_bits => no override */
            unsigned char opersize;     /* 0 indicates no override */
            unsigned char lockrep_pre;  /* 0 indicates no prefix */
        } jmprel;
@@ -536,7 +536,7 @@ bytecode_get_offset(section *sect, bytecode *bc, unsigned long *ret_val)
 }
 
 void
-bytecode_print(bytecode *bc)
+bytecode_print(const bytecode *bc)
 {
     switch (bc->type) {
        case BC_EMPTY:
@@ -569,7 +569,7 @@ bytecode_print(bytecode *bc)
            printf("Immediate Value:\n");
            printf(" Val=");
            if (!bc->data.insn.imm)
-               printf("(nil)");
+               printf("(nil)\n");
            else {
                expr_print(bc->data.insn.imm->val);
                printf("\n");
@@ -667,6 +667,48 @@ bytecode_print(bytecode *bc)
     printf("Offset=%lx BITS=%u\n", bc->offset, bc->mode_bits);
 }
 
+static void
+bytecode_parser_finalize_insn(bytecode *bc)
+{
+    effaddr *ea = bc->data.insn.ea;
+
+    if (ea) {
+       if ((ea->disp) && ((!ea->valid_sib && ea->need_sib) ||
+                          (!ea->valid_modrm && ea->need_modrm))) {
+           /* First simplify expression to minimize check cost */
+           expr_simplify(ea->disp);
+
+           /* Check validity of effective address and calc R/M bits of
+            * Mod/RM byte and SIB byte.  We won't know the Mod field
+            * of the Mod/RM byte until we know more about the
+            * displacement.
+            */
+           if (!expr_checkea(&ea->disp, &bc->data.insn.addrsize,
+                             bc->mode_bits, &ea->len, &ea->modrm,
+                             &ea->valid_modrm, &ea->need_modrm, &ea->sib,
+                             &ea->valid_sib, &ea->need_sib))
+               return;     /* failed, don't bother checking rest of insn */
+       }
+    }
+}
+
+void
+bytecode_parser_finalize(bytecode *bc)
+{
+    switch (bc->type) {
+       case BC_EMPTY:
+           /* FIXME: delete it (probably in bytecodes_ level, not here */
+           InternalError(__LINE__, __FILE__,
+                         _("got empty bytecode in parser_finalize"));
+           break;
+       case BC_INSN:
+           bytecode_parser_finalize_insn(bc);
+           break;
+       default:
+           break;
+    }
+}
+
 bytecode *
 bytecodes_append(bytecodehead *headp, bytecode *bc)
 {
@@ -692,6 +734,15 @@ bytecodes_print(const bytecodehead *headp)
     }
 }
 
+void
+bytecodes_parser_finalize(bytecodehead *headp)
+{
+    bytecode *cur;
+
+    STAILQ_FOREACH(cur, headp, link)
+       bytecode_parser_finalize(cur);
+}
+
 dataval *
 dataval_new_expr(expr *expn)
 {
@@ -725,7 +776,7 @@ datavals_append(datavalhead *headp, dataval *dv)
 }
 
 void
-dataval_print(datavalhead *head)
+dataval_print(const datavalhead *head)
 {
     dataval *cur;
 
index 4b49f2e2ab5ac1e7a87a88b900e7a8807a32bae8..5f4958380006ad713ded566b32b687a765ebde01 100644 (file)
@@ -118,7 +118,9 @@ bytecode *bytecode_new_reserve(expr *numitems, unsigned long itemsize);
  */
 int bytecode_get_offset(section *sect, bytecode *bc, unsigned long *ret_val);
 
-void bytecode_print(bytecode *bc);
+void bytecode_print(const bytecode *bc);
+
+void bytecode_parser_finalize(bytecode *bc);
 
 /* void bytecodes_initialize(bytecodehead *headp); */
 #define        bytecodes_initialize(headp)     STAILQ_INIT(headp)
@@ -133,6 +135,8 @@ bytecode *bytecodes_append(bytecodehead *headp, bytecode *bc);
 
 void bytecodes_print(const bytecodehead *headp);
 
+void bytecodes_parser_finalize(bytecodehead *headp);
+
 dataval *dataval_new_expr(expr *expn);
 dataval *dataval_new_float(floatnum *flt);
 dataval *dataval_new_string(char *str_val);
@@ -148,6 +152,6 @@ dataval *dataval_new_string(char *str_val);
  */
 dataval *datavals_append(datavalhead *headp, dataval *dv);
 
-void dataval_print(datavalhead *head);
+void dataval_print(const datavalhead *head);
 
 #endif
index d9db4be3f6c13c04614840a2728e704a06964f9f..2b90ec530ba23eff01c4ffec98d5009f64954ba0 100644 (file)
@@ -125,7 +125,7 @@ sections_switch(sectionhead *headp, objfmt *of, const char *name)
 }
 
 void
-sections_print(sectionhead *headp)
+sections_print(const sectionhead *headp)
 {
     section *cur;
     
@@ -133,6 +133,15 @@ sections_print(sectionhead *headp)
        section_print(cur);
 }
 
+void
+sections_parser_finalize(sectionhead *headp)
+{
+    section *cur;
+    
+    STAILQ_FOREACH(cur, headp, link)
+       bytecodes_parser_finalize(&cur->bc);
+}
+
 bytecodehead *
 section_get_bytecodes(section *sect)
 {
index 93aa3de4bf5e8824fe4bbdc355d4a124ee90eda8..19438df32d857c04ae223c564516b4b8d857b896 100644 (file)
@@ -36,7 +36,9 @@ section *sections_initialize(sectionhead *headp, struct objfmt_s *of);
 section *sections_switch(sectionhead *headp, struct objfmt_s *of,
                         const char *name);
 
-void sections_print(sectionhead *headp);
+void sections_print(const sectionhead *headp);
+
+void sections_parser_finalize(sectionhead *headp);
 
 bytecodehead *section_get_bytecodes(section *sect);
 
index 346c82fc8cd07525667ebeff6afa170a58adf474..3bac66a8d45375780e2869f8eab148497a6c10f4 100644 (file)
@@ -113,7 +113,7 @@ struct bytecode {
            unsigned char opcode[3];    /* opcode */
            unsigned char opcode_len;
 
-           unsigned char addrsize;     /* 0 indicates no override */
+           unsigned char addrsize;     /* 0 or =mode_bits => no override */
            unsigned char opersize;     /* 0 indicates no override */
            unsigned char lockrep_pre;  /* 0 indicates no prefix */
 
@@ -144,7 +144,7 @@ struct bytecode {
            /* The *FORCED forms are specified in the source as such */
            jmprel_opcode_sel op_sel;
 
-           unsigned char addrsize;     /* 0 indicates no override */
+           unsigned char addrsize;     /* 0 or =mode_bits => no override */
            unsigned char opersize;     /* 0 indicates no override */
            unsigned char lockrep_pre;  /* 0 indicates no prefix */
        } jmprel;
@@ -536,7 +536,7 @@ bytecode_get_offset(section *sect, bytecode *bc, unsigned long *ret_val)
 }
 
 void
-bytecode_print(bytecode *bc)
+bytecode_print(const bytecode *bc)
 {
     switch (bc->type) {
        case BC_EMPTY:
@@ -569,7 +569,7 @@ bytecode_print(bytecode *bc)
            printf("Immediate Value:\n");
            printf(" Val=");
            if (!bc->data.insn.imm)
-               printf("(nil)");
+               printf("(nil)\n");
            else {
                expr_print(bc->data.insn.imm->val);
                printf("\n");
@@ -667,6 +667,48 @@ bytecode_print(bytecode *bc)
     printf("Offset=%lx BITS=%u\n", bc->offset, bc->mode_bits);
 }
 
+static void
+bytecode_parser_finalize_insn(bytecode *bc)
+{
+    effaddr *ea = bc->data.insn.ea;
+
+    if (ea) {
+       if ((ea->disp) && ((!ea->valid_sib && ea->need_sib) ||
+                          (!ea->valid_modrm && ea->need_modrm))) {
+           /* First simplify expression to minimize check cost */
+           expr_simplify(ea->disp);
+
+           /* Check validity of effective address and calc R/M bits of
+            * Mod/RM byte and SIB byte.  We won't know the Mod field
+            * of the Mod/RM byte until we know more about the
+            * displacement.
+            */
+           if (!expr_checkea(&ea->disp, &bc->data.insn.addrsize,
+                             bc->mode_bits, &ea->len, &ea->modrm,
+                             &ea->valid_modrm, &ea->need_modrm, &ea->sib,
+                             &ea->valid_sib, &ea->need_sib))
+               return;     /* failed, don't bother checking rest of insn */
+       }
+    }
+}
+
+void
+bytecode_parser_finalize(bytecode *bc)
+{
+    switch (bc->type) {
+       case BC_EMPTY:
+           /* FIXME: delete it (probably in bytecodes_ level, not here */
+           InternalError(__LINE__, __FILE__,
+                         _("got empty bytecode in parser_finalize"));
+           break;
+       case BC_INSN:
+           bytecode_parser_finalize_insn(bc);
+           break;
+       default:
+           break;
+    }
+}
+
 bytecode *
 bytecodes_append(bytecodehead *headp, bytecode *bc)
 {
@@ -692,6 +734,15 @@ bytecodes_print(const bytecodehead *headp)
     }
 }
 
+void
+bytecodes_parser_finalize(bytecodehead *headp)
+{
+    bytecode *cur;
+
+    STAILQ_FOREACH(cur, headp, link)
+       bytecode_parser_finalize(cur);
+}
+
 dataval *
 dataval_new_expr(expr *expn)
 {
@@ -725,7 +776,7 @@ datavals_append(datavalhead *headp, dataval *dv)
 }
 
 void
-dataval_print(datavalhead *head)
+dataval_print(const datavalhead *head)
 {
     dataval *cur;
 
index 4b49f2e2ab5ac1e7a87a88b900e7a8807a32bae8..5f4958380006ad713ded566b32b687a765ebde01 100644 (file)
@@ -118,7 +118,9 @@ bytecode *bytecode_new_reserve(expr *numitems, unsigned long itemsize);
  */
 int bytecode_get_offset(section *sect, bytecode *bc, unsigned long *ret_val);
 
-void bytecode_print(bytecode *bc);
+void bytecode_print(const bytecode *bc);
+
+void bytecode_parser_finalize(bytecode *bc);
 
 /* void bytecodes_initialize(bytecodehead *headp); */
 #define        bytecodes_initialize(headp)     STAILQ_INIT(headp)
@@ -133,6 +135,8 @@ bytecode *bytecodes_append(bytecodehead *headp, bytecode *bc);
 
 void bytecodes_print(const bytecodehead *headp);
 
+void bytecodes_parser_finalize(bytecodehead *headp);
+
 dataval *dataval_new_expr(expr *expn);
 dataval *dataval_new_float(floatnum *flt);
 dataval *dataval_new_string(char *str_val);
@@ -148,6 +152,6 @@ dataval *dataval_new_string(char *str_val);
  */
 dataval *datavals_append(datavalhead *headp, dataval *dv);
 
-void dataval_print(datavalhead *head);
+void dataval_print(const datavalhead *head);
 
 #endif
index 6cad2ab297c7ff13530c99511277d709af5bbee7..f08c483f118228e3387f58bc977adb1e1d085b7a 100644 (file)
@@ -135,6 +135,11 @@ main(int argc, char *argv[])
     printf("\n***Symbol Table***\n");
     symrec_foreach((int (*) (symrec *))symrec_print);
 
+    sections_parser_finalize(sections);
+
+    printf("Post-parser-finalization:\n");
+    sections_print(sections);
+
     if (in_filename)
        free(in_filename);
     return EXIT_SUCCESS;
index d9db4be3f6c13c04614840a2728e704a06964f9f..2b90ec530ba23eff01c4ffec98d5009f64954ba0 100644 (file)
@@ -125,7 +125,7 @@ sections_switch(sectionhead *headp, objfmt *of, const char *name)
 }
 
 void
-sections_print(sectionhead *headp)
+sections_print(const sectionhead *headp)
 {
     section *cur;
     
@@ -133,6 +133,15 @@ sections_print(sectionhead *headp)
        section_print(cur);
 }
 
+void
+sections_parser_finalize(sectionhead *headp)
+{
+    section *cur;
+    
+    STAILQ_FOREACH(cur, headp, link)
+       bytecodes_parser_finalize(&cur->bc);
+}
+
 bytecodehead *
 section_get_bytecodes(section *sect)
 {
index 93aa3de4bf5e8824fe4bbdc355d4a124ee90eda8..19438df32d857c04ae223c564516b4b8d857b896 100644 (file)
@@ -36,7 +36,9 @@ section *sections_initialize(sectionhead *headp, struct objfmt_s *of);
 section *sections_switch(sectionhead *headp, struct objfmt_s *of,
                         const char *name);
 
-void sections_print(sectionhead *headp);
+void sections_print(const sectionhead *headp);
+
+void sections_parser_finalize(sectionhead *headp);
 
 bytecodehead *section_get_bytecodes(section *sect);