]> granicus.if.org Git - yasm/commitdiff
Make output endian-tolerant by making intnum and floatnum output functions for
authorPeter Johnson <peter@tortall.net>
Sun, 6 Oct 2002 19:43:51 +0000 (19:43 -0000)
committerPeter Johnson <peter@tortall.net>
Sun, 6 Oct 2002 19:43:51 +0000 (19:43 -0000)
arch.  This will also simplify other objfmt expr output functions.  Change
file functions to use bits instead of byte/short/long, and create both little
and big endian versions.  This name change caused changes in several other
files.

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

22 files changed:
libyasm/arch.h
libyasm/bytecode.c
libyasm/file.c
libyasm/file.h
libyasm/floatnum.c
libyasm/intnum.c
modules/arch/x86/x86arch.c
modules/arch/x86/x86arch.h
modules/arch/x86/x86bc.c
modules/arch/x86/x86expr.c
modules/objfmts/bin/bin-objfmt.c
src/arch.h
src/arch/x86/x86arch.c
src/arch/x86/x86arch.h
src/arch/x86/x86bc.c
src/arch/x86/x86expr.c
src/bytecode.c
src/file.c
src/file.h
src/floatnum.c
src/intnum.c
src/objfmts/bin/bin-objfmt.c

index e5a8b1670a81afc7656e5b27208b8864ddd41b93..6d5132c9bad7104303548c0fabc6cfc80e448258 100644 (file)
@@ -141,6 +141,17 @@ struct arch {
                           output_expr_func output_expr);
     } bc;
 
+    /* Functions to output floats and integers, architecture-specific because
+     * of endianness.  Returns nonzero on error, otherwise updates bufp by
+     * valsize (bytes saved to bufp).  For intnums, rel indicates a relative
+     * displacement, and bc is the containing bytecode to compute it from.
+     */
+    int (*floatnum_tobytes) (const floatnum *flt, unsigned char **bufp,
+                            unsigned long valsize, const expr *e);
+    int (*intnum_tobytes) (const intnum *intn, unsigned char **bufp,
+                          unsigned long valsize, const expr *e,
+                          const bytecode *bc, int rel);
+
     /* Gets the equivalent register size in bytes.  Returns 0 if there is no
      * suitable equivalent size.
      */
index 461888053bce59accd4439a267119fc7d4733d9a..04d8649aefdb7c4b9b90e50c664cf3b889b446e9 100644 (file)
@@ -668,7 +668,7 @@ bc_tobytes_data(bytecode_data *bc_data, unsigned char **bufp,
                if (slen > 0) {
                    slen = bc_data->size-slen;
                    for (i=0; i<slen; i++)
-                       WRITE_BYTE(*bufp, 0);
+                       WRITE_8(*bufp, 0);
                }
                break;
        }
index a6649dc1056f2c86d3ada47e1a81ab9ae7428ebe..77f1aa9e310bdddc28920fafe49c3655261049bd 100644 (file)
@@ -75,7 +75,7 @@ replace_extension(const char *orig, /*@null@*/ const char *ext,
 }
 
 size_t
-fwrite_short(unsigned short val, FILE *f)
+fwrite_16_l(unsigned short val, FILE *f)
 {
     if (fputc(val & 0xFF, f) == EOF)
        return 0;
@@ -85,7 +85,7 @@ fwrite_short(unsigned short val, FILE *f)
 }
 
 size_t
-fwrite_long(unsigned long val, FILE *f)
+fwrite_32_l(unsigned long val, FILE *f)
 {
     if (fputc((int)(val & 0xFF), f) == EOF)
        return 0;
@@ -97,3 +97,27 @@ fwrite_long(unsigned long val, FILE *f)
        return 0;
     return 1;
 }
+
+size_t
+fwrite_16_b(unsigned short val, FILE *f)
+{
+    if (fputc((val >> 8) & 0xFF, f) == EOF)
+       return 0;
+    if (fputc(val & 0xFF, f) == EOF)
+       return 0;
+    return 1;
+}
+
+size_t
+fwrite_32_b(unsigned long val, FILE *f)
+{
+    if (fputc((int)((val >> 24) & 0xFF), f) == EOF)
+       return 0;
+    if (fputc((int)((val >> 16) & 0xFF), f) == EOF)
+       return 0;
+    if (fputc((int)((val >> 8) & 0xFF), f) == EOF)
+       return 0;
+    if (fputc((int)(val & 0xFF), f) == EOF)
+       return 0;
+    return 1;
+}
index 2c597620f63798c5b2fae89b3bd145ad24ae22db..3940747874bde8d1ad5116ad56461556e4698a1c 100644 (file)
@@ -1,5 +1,5 @@
 /* $IdPath$
- * Little-endian file functions header file.
+ * Big and little endian file functions header file.
  *
  *  Copyright (C) 2001  Peter Johnson
  *
 
 /* These functions only work properly if p is an (unsigned char *) */
 
-#define WRITE_BYTE(ptr, val)                   \
+#define WRITE_8(ptr, val)                      \
        *((ptr)++) = (unsigned char)((val) & 0xFF)
 
-#define WRITE_SHORT(ptr, val)                  \
+#define WRITE_16_L(ptr, val)                   \
        do {                                    \
            *((ptr)++) = (unsigned char)((val) & 0xFF);         \
            *((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF);  \
        } while (0)
 
-#define WRITE_LONG(ptr, val)                   \
+#define WRITE_32_L(ptr, val)                   \
        do {                                    \
            *((ptr)++) = (unsigned char)((val) & 0xFF);         \
            *((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF);  \
            *((ptr)++) = (unsigned char)(((val) >> 24) & 0xFF); \
        } while (0)
 
+#define WRITE_16_B(ptr, val)                   \
+       do {                                    \
+           *((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF);  \
+           *((ptr)++) = (unsigned char)((val) & 0xFF);         \
+       } while (0)
+
+#define WRITE_32_B(ptr, val)                   \
+       do {                                    \
+           *((ptr)++) = (unsigned char)(((val) >> 24) & 0xFF); \
+           *((ptr)++) = (unsigned char)(((val) >> 16) & 0xFF); \
+           *((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF);  \
+           *((ptr)++) = (unsigned char)((val) & 0xFF);         \
+       } while (0)
+
+
 /* Non-incrementing versions of the above. */
 
-#define SAVE_BYTE(ptr, val)                    \
+#define SAVE_8(ptr, val)                       \
        *(ptr) = (unsigned char)((val) & 0xFF)
 
-#define SAVE_SHORT(ptr, val)                   \
+#define SAVE_16_L(ptr, val)                    \
        do {                                    \
            *(ptr) = (unsigned char)((val) & 0xFF);             \
            *((ptr)+1) = (unsigned char)(((val) >> 8) & 0xFF);  \
        } while (0)
 
-#define SAVE_LONG(ptr, val)                    \
+#define SAVE_32_L(ptr, val)                    \
        do {                                    \
            *(ptr) = (unsigned char)((val) & 0xFF);             \
            *((ptr)+1) = (unsigned char)(((val) >> 8) & 0xFF);  \
            *((ptr)+3) = (unsigned char)(((val) >> 24) & 0xFF); \
        } while (0)
 
+#define SAVE_16_B(ptr, val)                    \
+       do {                                    \
+           *(ptr) = (unsigned char)(((val) >> 8) & 0xFF);      \
+           *((ptr)+1) = (unsigned char)((val) & 0xFF);         \
+       } while (0)
+
+#define SAVE_32_B(ptr, val)                    \
+       do {                                    \
+           *(ptr) = (unsigned char)(((val) >> 24) & 0xFF);     \
+           *((ptr)+1) = (unsigned char)(((val) >> 16) & 0xFF); \
+           *((ptr)+2) = (unsigned char)(((val) >> 8) & 0xFF);  \
+           *((ptr)+3) = (unsigned char)((val) & 0xFF);         \
+       } while (0)
+
 /* Direct-to-file versions of the above.  Using the above macros and a single
  * fwrite() will probably be faster than calling these functions many times.
  * These functions return 1 if the write was successful, 0 if not (so their
  * return values can be used like the return value from fwrite()).
  */
 
-size_t fwrite_short(unsigned short val, FILE *f);
-size_t fwrite_long(unsigned long val, FILE *f);
+size_t fwrite_16_l(unsigned short val, FILE *f);
+size_t fwrite_32_l(unsigned long val, FILE *f);
+size_t fwrite_16_b(unsigned short val, FILE *f);
+size_t fwrite_32_b(unsigned long val, FILE *f);
 
 /* Read/Load versions.  val is the variable to receive the data. */
 
-#define READ_BYTE(val, ptr)                    \
+#define READ_8(val, ptr)                       \
        (val) = *((ptr)++) & 0xFF
 
-#define READ_SHORT(val, ptr)                   \
+#define READ_16_L(val, ptr)                    \
        do {                                    \
            (val) = *((ptr)++) & 0xFF;          \
            (val) |= (*((ptr)++) & 0xFF) << 8;  \
        } while (0)
 
-#define READ_LONG(val, ptr)                    \
+#define READ_32_L(val, ptr)                    \
        do {                                    \
            (val) = *((ptr)++) & 0xFF;          \
            (val) |= (*((ptr)++) & 0xFF) << 8;  \
@@ -97,18 +128,32 @@ size_t fwrite_long(unsigned long val, FILE *f);
            (val) |= (*((ptr)++) & 0xFF) << 24; \
        } while (0)
 
+#define READ_16_B(val, ptr)                    \
+       do {                                    \
+           (val) = (*((ptr)++) & 0xFF) << 8;   \
+           (val) |= *((ptr)++) & 0xFF;         \
+       } while (0)
+
+#define READ_32_B(val, ptr)                    \
+       do {                                    \
+           (val) = (*((ptr)++) & 0xFF) << 24;  \
+           (val) |= (*((ptr)++) & 0xFF) << 16; \
+           (val) |= (*((ptr)++) & 0xFF) << 8;  \
+           (val) |= *((ptr)++) & 0xFF;         \
+       } while (0)
+
 /* Non-incrementing versions of the above. */
 
-#define LOAD_BYTE(val, ptr)                    \
+#define LOAD_8(val, ptr)                       \
        (val) = *(ptr) & 0xFF
 
-#define LOAD_SHORT(val, ptr)                   \
+#define LOAD_16_L(val, ptr)                    \
        do {                                    \
            (val) = *(ptr) & 0xFF;              \
            (val) |= (*((ptr)+1) & 0xFF) << 8;  \
        } while (0)
 
-#define LOAD_LONG(val, ptr)                    \
+#define LOAD_32_L(val, ptr)                    \
        do {                                    \
            (val) = (unsigned long)(*(ptr) & 0xFF);                 \
            (val) |= (unsigned long)((*((ptr)+1) & 0xFF) << 8);     \
@@ -116,4 +161,18 @@ size_t fwrite_long(unsigned long val, FILE *f);
            (val) |= (unsigned long)((*((ptr)+3) & 0xFF) << 24);    \
        } while (0)
 
+#define LOAD_16_B(val, ptr)                    \
+       do {                                    \
+           (val) = (*(ptr) & 0xFF) << 8;       \
+           (val) |= *((ptr)+1) & 0xFF;         \
+       } while (0)
+
+#define LOAD_32_B(val, ptr)                    \
+       do {                                    \
+           (val) = (unsigned long)((*(ptr) & 0xFF) << 24);         \
+           (val) |= (unsigned long)((*((ptr)+1) & 0xFF) << 16);    \
+           (val) |= (unsigned long)((*((ptr)+2) & 0xFF) << 8);     \
+           (val) |= (unsigned long)(*((ptr)+3) & 0xFF);            \
+       } while (0)
+
 #endif
index 9f4e936b41274ede3ba7ecc72b25300f5619ff1a..6f98dc262f2d17e8a2cd3fb3981b97b66214fc68 100644 (file)
@@ -529,7 +529,7 @@ floatnum_get_int(const floatnum *flt, unsigned long *ret_val)
        return 1;
     }
 
-    LOAD_LONG(*ret_val, &t[0]);
+    LOAD_32_L(*ret_val, &t[0]);
     return 0;
 }
 
index 99d4786282431094981d7cad8dc99a8160918f4c..38c572218568173833e025d250331adf1ea27e4e 100644 (file)
@@ -551,7 +551,7 @@ intnum_get_sized(const intnum *intn, unsigned char *ptr, size_t size)
        case INTNUM_UL:
            ul = intn->val.ul;
            while (size-- > 0) {
-               WRITE_BYTE(ptr, ul);
+               WRITE_8(ptr, ul);
                if (ul != 0)
                    ul >>= 8;
            }
index de8ef8e2e49b635afd9515e9422567c5b4037851..e4b91255ca9abed53f25f44a865b03129d0380bf 100644 (file)
 #include "util.h"
 /*@unused@*/ RCSID("$IdPath$");
 
+#include "file.h"
+
 #include "globals.h"
 #include "errwarn.h"
 #include "intnum.h"
+#include "floatnum.h"
 #include "expr.h"
 
 #include "bytecode.h"
@@ -177,6 +180,8 @@ arch x86_arch = {
        x86_bc_resolve,
        x86_bc_tobytes
     },
+    x86_floatnum_tobytes,
+    x86_intnum_tobytes,
     x86_get_reg_size,
     x86_reg_print,
     x86_segreg_print,
index 9f10c9d07409836447f9070b26d109851a109c4d..5223e42c160e6191bd1be03e6873e83ba3890f8a 100644 (file)
@@ -220,6 +220,12 @@ void x86_handle_seg_prefix(bytecode *bc, unsigned long segreg);
 
 void x86_handle_seg_override(effaddr *ea, unsigned long segreg);
 
+int x86_floatnum_tobytes(const floatnum *flt, unsigned char **bufp,
+                        unsigned long valsize, const expr *e);
+int x86_intnum_tobytes(const intnum *intn, unsigned char **bufp,
+                      unsigned long valsize, const expr *e,
+                      const bytecode *bc, int rel);
+
 unsigned int x86_get_reg_size(unsigned long reg);
 
 void x86_reg_print(FILE *f, unsigned long reg);
index f5dc6a4b3356e1bdbe0124ec01a002d81e89d6af..b7f8851f86963b5e232c9b0b932725946694464a 100644 (file)
@@ -726,17 +726,17 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp, const section *sect,
 
     /* Prefixes */
     if (insn->lockrep_pre != 0)
-       WRITE_BYTE(*bufp, insn->lockrep_pre);
+       WRITE_8(*bufp, insn->lockrep_pre);
     if (ea && ead->segment != 0)
-       WRITE_BYTE(*bufp, ead->segment);
+       WRITE_8(*bufp, ead->segment);
     if (insn->opersize != 0 && insn->opersize != insn->mode_bits)
-       WRITE_BYTE(*bufp, 0x66);
+       WRITE_8(*bufp, 0x66);
     if (insn->addrsize != 0 && insn->addrsize != insn->mode_bits)
-       WRITE_BYTE(*bufp, 0x67);
+       WRITE_8(*bufp, 0x67);
 
     /* Opcode */
     for (i=0; i<insn->opcode_len; i++)
-       WRITE_BYTE(*bufp, insn->opcode[i]);
+       WRITE_8(*bufp, insn->opcode[i]);
 
     /* Effective address: ModR/M (if required), SIB (if required), and
      * displacement (if required).
@@ -745,13 +745,13 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp, const section *sect,
        if (ead->need_modrm) {
            if (!ead->valid_modrm)
                InternalError(_("invalid Mod/RM in x86 tobytes_insn"));
-           WRITE_BYTE(*bufp, ead->modrm);
+           WRITE_8(*bufp, ead->modrm);
        }
 
        if (ead->need_sib) {
            if (!ead->valid_sib)
                InternalError(_("invalid SIB in x86 tobytes_insn"));
-           WRITE_BYTE(*bufp, ead->sib);
+           WRITE_8(*bufp, ead->sib);
        }
 
        if (ea->disp) {
@@ -780,7 +780,7 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp, const section *sect,
                 * write out 0 value.
                 */
                for (i=0; i<ea->len; i++)
-                   WRITE_BYTE(*bufp, 0);
+                   WRITE_8(*bufp, 0);
            }
        }
     }
@@ -805,12 +805,12 @@ x86_bc_tobytes_jmprel(x86_jmprel *jmprel, unsigned char **bufp,
 
     /* Prefixes */
     if (jmprel->lockrep_pre != 0)
-       WRITE_BYTE(*bufp, jmprel->lockrep_pre);
+       WRITE_8(*bufp, jmprel->lockrep_pre);
     /* FIXME: branch hints! */
     if (jmprel->opersize != 0 && jmprel->opersize != jmprel->mode_bits)
-       WRITE_BYTE(*bufp, 0x66);
+       WRITE_8(*bufp, 0x66);
     if (jmprel->addrsize != 0 && jmprel->addrsize != jmprel->mode_bits)
-       WRITE_BYTE(*bufp, 0x67);
+       WRITE_8(*bufp, 0x67);
 
     /* As opersize may be 0, figure out its "real" value. */
     opersize = (jmprel->opersize == 0) ? jmprel->mode_bits :
@@ -826,7 +826,7 @@ x86_bc_tobytes_jmprel(x86_jmprel *jmprel, unsigned char **bufp,
 
            /* Opcode */
            for (i=0; i<jmprel->shortop.opcode_len; i++)
-               WRITE_BYTE(*bufp, jmprel->shortop.opcode[i]);
+               WRITE_8(*bufp, jmprel->shortop.opcode[i]);
 
            /* Relative displacement */
            if (output_expr(&jmprel->target, bufp, 1, sect, bc, 1, d))
@@ -842,7 +842,7 @@ x86_bc_tobytes_jmprel(x86_jmprel *jmprel, unsigned char **bufp,
 
            /* Opcode */
            for (i=0; i<jmprel->nearop.opcode_len; i++)
-               WRITE_BYTE(*bufp, jmprel->nearop.opcode[i]);
+               WRITE_8(*bufp, jmprel->nearop.opcode[i]);
 
            /* Relative displacement */
            if (output_expr(&jmprel->target, bufp,
@@ -876,3 +876,32 @@ x86_bc_tobytes(bytecode *bc, unsigned char **bufp, const section *sect,
     return 0;
 }
 
+int
+x86_intnum_tobytes(const intnum *intn, unsigned char **bufp,
+                  unsigned long valsize, const expr *e, const bytecode *bc,
+                  int rel)
+{
+    if (rel) {
+       long val;
+       if (valsize != 1 && valsize != 2 && valsize != 4)
+           InternalError(_("tried to do PC-relative offset from invalid sized value"));
+       val = intnum_get_uint(intn);
+       val -= bc->len;
+       switch (valsize) {
+           case 1:
+               WRITE_8(*bufp, val);
+               break;
+           case 2:
+               WRITE_16_L(*bufp, val);
+               break;
+           case 4:
+               WRITE_32_L(*bufp, val);
+               break;
+       }
+    } else {
+       /* Write value out. */
+       intnum_get_sized(intn, *bufp, (size_t)valsize);
+       *bufp += valsize;
+    }
+    return 0;
+}
index 9855a087b4778f431c0749a7ee68907a456a0cd7..fdcc6c38f38b203550908908c24a73707e42ab04 100644 (file)
@@ -771,3 +771,27 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
     }
     return 1;
 }
+
+int
+x86_floatnum_tobytes(const floatnum *flt, unsigned char **bufp,
+                    unsigned long valsize, const expr *e)
+{
+    int fltret;
+
+    if (!floatnum_check_size(flt, (size_t)valsize)) {
+       ErrorAt(e->line, _("invalid floating point constant size"));
+       return 1;
+    }
+
+    fltret = floatnum_get_sized(flt, *bufp, (size_t)valsize);
+    if (fltret < 0) {
+       ErrorAt(e->line, _("underflow in floating point expression"));
+       return 1;
+    }
+    if (fltret > 0) {
+       ErrorAt(e->line, _("overflow in floating point expression"));
+       return 1;
+    }
+    *bufp += valsize;
+    return 0;
+}
index f408adb80d57275cee1c69fb222e51c28c171f08..bf4823d15b145d74a42a86d4dca46827de55d1f8 100644 (file)
@@ -37,6 +37,7 @@
 #include "expr-int.h"
 #include "bc-int.h"
 
+#include "arch.h"
 #include "objfmt.h"
 
 
@@ -106,7 +107,7 @@ bin_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize,
                       /*@observer@*/ const bytecode *bc, int rel,
                       /*@unused@*/ /*@null@*/ void *d)
 {
-    /*@dependent@*/ /*@null@*/ const intnum *num;
+    /*@dependent@*/ /*@null@*/ const intnum *intn;
     /*@dependent@*/ /*@null@*/ const floatnum *flt;
 
     assert(info != NULL);
@@ -120,54 +121,13 @@ bin_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize,
 
     /* Handle floating point expressions */
     flt = expr_get_floatnum(ep);
-    if (flt) {
-       int fltret;
-
-       if (!floatnum_check_size(flt, (size_t)valsize)) {
-           ErrorAt((*ep)->line, _("invalid floating point constant size"));
-           return 1;
-       }
-
-       fltret = floatnum_get_sized(flt, *bufp, (size_t)valsize);
-       if (fltret < 0) {
-           ErrorAt((*ep)->line, _("underflow in floating point expression"));
-           return 1;
-       }
-       if (fltret > 0) {
-           ErrorAt((*ep)->line, _("overflow in floating point expression"));
-           return 1;
-       }
-       *bufp += valsize;
-       return 0;
-    }
+    if (flt)
+       return cur_arch->floatnum_tobytes(flt, bufp, valsize, *ep);
 
     /* Handle integer expressions */
-    num = expr_get_intnum(ep, NULL);
-    if (num) {
-       if (rel) {
-           long val;
-           if (valsize != 1 && valsize != 2 && valsize != 4)
-               InternalError(_("tried to do PC-relative offset from invalid sized value"));
-           val = intnum_get_uint(num);
-           val -= bc->len;
-           switch (valsize) {
-               case 1:
-                   WRITE_BYTE(*bufp, val);
-                   break;
-               case 2:
-                   WRITE_SHORT(*bufp, val);
-                   break;
-               case 4:
-                   WRITE_LONG(*bufp, val);
-                   break;
-           }
-       } else {
-           /* Write value out. */
-           intnum_get_sized(num, *bufp, (size_t)valsize);
-           *bufp += valsize;
-       }
-       return 0;
-    }
+    intn = expr_get_intnum(ep, NULL);
+    if (intn)
+       return cur_arch->intnum_tobytes(intn, bufp, valsize, *ep, bc, rel);
 
     /* Check for complex float expressions */
     if (expr_contains(*ep, EXPR_FLOAT)) {
index e5a8b1670a81afc7656e5b27208b8864ddd41b93..6d5132c9bad7104303548c0fabc6cfc80e448258 100644 (file)
@@ -141,6 +141,17 @@ struct arch {
                           output_expr_func output_expr);
     } bc;
 
+    /* Functions to output floats and integers, architecture-specific because
+     * of endianness.  Returns nonzero on error, otherwise updates bufp by
+     * valsize (bytes saved to bufp).  For intnums, rel indicates a relative
+     * displacement, and bc is the containing bytecode to compute it from.
+     */
+    int (*floatnum_tobytes) (const floatnum *flt, unsigned char **bufp,
+                            unsigned long valsize, const expr *e);
+    int (*intnum_tobytes) (const intnum *intn, unsigned char **bufp,
+                          unsigned long valsize, const expr *e,
+                          const bytecode *bc, int rel);
+
     /* Gets the equivalent register size in bytes.  Returns 0 if there is no
      * suitable equivalent size.
      */
index de8ef8e2e49b635afd9515e9422567c5b4037851..e4b91255ca9abed53f25f44a865b03129d0380bf 100644 (file)
 #include "util.h"
 /*@unused@*/ RCSID("$IdPath$");
 
+#include "file.h"
+
 #include "globals.h"
 #include "errwarn.h"
 #include "intnum.h"
+#include "floatnum.h"
 #include "expr.h"
 
 #include "bytecode.h"
@@ -177,6 +180,8 @@ arch x86_arch = {
        x86_bc_resolve,
        x86_bc_tobytes
     },
+    x86_floatnum_tobytes,
+    x86_intnum_tobytes,
     x86_get_reg_size,
     x86_reg_print,
     x86_segreg_print,
index 9f10c9d07409836447f9070b26d109851a109c4d..5223e42c160e6191bd1be03e6873e83ba3890f8a 100644 (file)
@@ -220,6 +220,12 @@ void x86_handle_seg_prefix(bytecode *bc, unsigned long segreg);
 
 void x86_handle_seg_override(effaddr *ea, unsigned long segreg);
 
+int x86_floatnum_tobytes(const floatnum *flt, unsigned char **bufp,
+                        unsigned long valsize, const expr *e);
+int x86_intnum_tobytes(const intnum *intn, unsigned char **bufp,
+                      unsigned long valsize, const expr *e,
+                      const bytecode *bc, int rel);
+
 unsigned int x86_get_reg_size(unsigned long reg);
 
 void x86_reg_print(FILE *f, unsigned long reg);
index f5dc6a4b3356e1bdbe0124ec01a002d81e89d6af..b7f8851f86963b5e232c9b0b932725946694464a 100644 (file)
@@ -726,17 +726,17 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp, const section *sect,
 
     /* Prefixes */
     if (insn->lockrep_pre != 0)
-       WRITE_BYTE(*bufp, insn->lockrep_pre);
+       WRITE_8(*bufp, insn->lockrep_pre);
     if (ea && ead->segment != 0)
-       WRITE_BYTE(*bufp, ead->segment);
+       WRITE_8(*bufp, ead->segment);
     if (insn->opersize != 0 && insn->opersize != insn->mode_bits)
-       WRITE_BYTE(*bufp, 0x66);
+       WRITE_8(*bufp, 0x66);
     if (insn->addrsize != 0 && insn->addrsize != insn->mode_bits)
-       WRITE_BYTE(*bufp, 0x67);
+       WRITE_8(*bufp, 0x67);
 
     /* Opcode */
     for (i=0; i<insn->opcode_len; i++)
-       WRITE_BYTE(*bufp, insn->opcode[i]);
+       WRITE_8(*bufp, insn->opcode[i]);
 
     /* Effective address: ModR/M (if required), SIB (if required), and
      * displacement (if required).
@@ -745,13 +745,13 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp, const section *sect,
        if (ead->need_modrm) {
            if (!ead->valid_modrm)
                InternalError(_("invalid Mod/RM in x86 tobytes_insn"));
-           WRITE_BYTE(*bufp, ead->modrm);
+           WRITE_8(*bufp, ead->modrm);
        }
 
        if (ead->need_sib) {
            if (!ead->valid_sib)
                InternalError(_("invalid SIB in x86 tobytes_insn"));
-           WRITE_BYTE(*bufp, ead->sib);
+           WRITE_8(*bufp, ead->sib);
        }
 
        if (ea->disp) {
@@ -780,7 +780,7 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp, const section *sect,
                 * write out 0 value.
                 */
                for (i=0; i<ea->len; i++)
-                   WRITE_BYTE(*bufp, 0);
+                   WRITE_8(*bufp, 0);
            }
        }
     }
@@ -805,12 +805,12 @@ x86_bc_tobytes_jmprel(x86_jmprel *jmprel, unsigned char **bufp,
 
     /* Prefixes */
     if (jmprel->lockrep_pre != 0)
-       WRITE_BYTE(*bufp, jmprel->lockrep_pre);
+       WRITE_8(*bufp, jmprel->lockrep_pre);
     /* FIXME: branch hints! */
     if (jmprel->opersize != 0 && jmprel->opersize != jmprel->mode_bits)
-       WRITE_BYTE(*bufp, 0x66);
+       WRITE_8(*bufp, 0x66);
     if (jmprel->addrsize != 0 && jmprel->addrsize != jmprel->mode_bits)
-       WRITE_BYTE(*bufp, 0x67);
+       WRITE_8(*bufp, 0x67);
 
     /* As opersize may be 0, figure out its "real" value. */
     opersize = (jmprel->opersize == 0) ? jmprel->mode_bits :
@@ -826,7 +826,7 @@ x86_bc_tobytes_jmprel(x86_jmprel *jmprel, unsigned char **bufp,
 
            /* Opcode */
            for (i=0; i<jmprel->shortop.opcode_len; i++)
-               WRITE_BYTE(*bufp, jmprel->shortop.opcode[i]);
+               WRITE_8(*bufp, jmprel->shortop.opcode[i]);
 
            /* Relative displacement */
            if (output_expr(&jmprel->target, bufp, 1, sect, bc, 1, d))
@@ -842,7 +842,7 @@ x86_bc_tobytes_jmprel(x86_jmprel *jmprel, unsigned char **bufp,
 
            /* Opcode */
            for (i=0; i<jmprel->nearop.opcode_len; i++)
-               WRITE_BYTE(*bufp, jmprel->nearop.opcode[i]);
+               WRITE_8(*bufp, jmprel->nearop.opcode[i]);
 
            /* Relative displacement */
            if (output_expr(&jmprel->target, bufp,
@@ -876,3 +876,32 @@ x86_bc_tobytes(bytecode *bc, unsigned char **bufp, const section *sect,
     return 0;
 }
 
+int
+x86_intnum_tobytes(const intnum *intn, unsigned char **bufp,
+                  unsigned long valsize, const expr *e, const bytecode *bc,
+                  int rel)
+{
+    if (rel) {
+       long val;
+       if (valsize != 1 && valsize != 2 && valsize != 4)
+           InternalError(_("tried to do PC-relative offset from invalid sized value"));
+       val = intnum_get_uint(intn);
+       val -= bc->len;
+       switch (valsize) {
+           case 1:
+               WRITE_8(*bufp, val);
+               break;
+           case 2:
+               WRITE_16_L(*bufp, val);
+               break;
+           case 4:
+               WRITE_32_L(*bufp, val);
+               break;
+       }
+    } else {
+       /* Write value out. */
+       intnum_get_sized(intn, *bufp, (size_t)valsize);
+       *bufp += valsize;
+    }
+    return 0;
+}
index 9855a087b4778f431c0749a7ee68907a456a0cd7..fdcc6c38f38b203550908908c24a73707e42ab04 100644 (file)
@@ -771,3 +771,27 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
     }
     return 1;
 }
+
+int
+x86_floatnum_tobytes(const floatnum *flt, unsigned char **bufp,
+                    unsigned long valsize, const expr *e)
+{
+    int fltret;
+
+    if (!floatnum_check_size(flt, (size_t)valsize)) {
+       ErrorAt(e->line, _("invalid floating point constant size"));
+       return 1;
+    }
+
+    fltret = floatnum_get_sized(flt, *bufp, (size_t)valsize);
+    if (fltret < 0) {
+       ErrorAt(e->line, _("underflow in floating point expression"));
+       return 1;
+    }
+    if (fltret > 0) {
+       ErrorAt(e->line, _("overflow in floating point expression"));
+       return 1;
+    }
+    *bufp += valsize;
+    return 0;
+}
index 461888053bce59accd4439a267119fc7d4733d9a..04d8649aefdb7c4b9b90e50c664cf3b889b446e9 100644 (file)
@@ -668,7 +668,7 @@ bc_tobytes_data(bytecode_data *bc_data, unsigned char **bufp,
                if (slen > 0) {
                    slen = bc_data->size-slen;
                    for (i=0; i<slen; i++)
-                       WRITE_BYTE(*bufp, 0);
+                       WRITE_8(*bufp, 0);
                }
                break;
        }
index a6649dc1056f2c86d3ada47e1a81ab9ae7428ebe..77f1aa9e310bdddc28920fafe49c3655261049bd 100644 (file)
@@ -75,7 +75,7 @@ replace_extension(const char *orig, /*@null@*/ const char *ext,
 }
 
 size_t
-fwrite_short(unsigned short val, FILE *f)
+fwrite_16_l(unsigned short val, FILE *f)
 {
     if (fputc(val & 0xFF, f) == EOF)
        return 0;
@@ -85,7 +85,7 @@ fwrite_short(unsigned short val, FILE *f)
 }
 
 size_t
-fwrite_long(unsigned long val, FILE *f)
+fwrite_32_l(unsigned long val, FILE *f)
 {
     if (fputc((int)(val & 0xFF), f) == EOF)
        return 0;
@@ -97,3 +97,27 @@ fwrite_long(unsigned long val, FILE *f)
        return 0;
     return 1;
 }
+
+size_t
+fwrite_16_b(unsigned short val, FILE *f)
+{
+    if (fputc((val >> 8) & 0xFF, f) == EOF)
+       return 0;
+    if (fputc(val & 0xFF, f) == EOF)
+       return 0;
+    return 1;
+}
+
+size_t
+fwrite_32_b(unsigned long val, FILE *f)
+{
+    if (fputc((int)((val >> 24) & 0xFF), f) == EOF)
+       return 0;
+    if (fputc((int)((val >> 16) & 0xFF), f) == EOF)
+       return 0;
+    if (fputc((int)((val >> 8) & 0xFF), f) == EOF)
+       return 0;
+    if (fputc((int)(val & 0xFF), f) == EOF)
+       return 0;
+    return 1;
+}
index 2c597620f63798c5b2fae89b3bd145ad24ae22db..3940747874bde8d1ad5116ad56461556e4698a1c 100644 (file)
@@ -1,5 +1,5 @@
 /* $IdPath$
- * Little-endian file functions header file.
+ * Big and little endian file functions header file.
  *
  *  Copyright (C) 2001  Peter Johnson
  *
 
 /* These functions only work properly if p is an (unsigned char *) */
 
-#define WRITE_BYTE(ptr, val)                   \
+#define WRITE_8(ptr, val)                      \
        *((ptr)++) = (unsigned char)((val) & 0xFF)
 
-#define WRITE_SHORT(ptr, val)                  \
+#define WRITE_16_L(ptr, val)                   \
        do {                                    \
            *((ptr)++) = (unsigned char)((val) & 0xFF);         \
            *((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF);  \
        } while (0)
 
-#define WRITE_LONG(ptr, val)                   \
+#define WRITE_32_L(ptr, val)                   \
        do {                                    \
            *((ptr)++) = (unsigned char)((val) & 0xFF);         \
            *((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF);  \
            *((ptr)++) = (unsigned char)(((val) >> 24) & 0xFF); \
        } while (0)
 
+#define WRITE_16_B(ptr, val)                   \
+       do {                                    \
+           *((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF);  \
+           *((ptr)++) = (unsigned char)((val) & 0xFF);         \
+       } while (0)
+
+#define WRITE_32_B(ptr, val)                   \
+       do {                                    \
+           *((ptr)++) = (unsigned char)(((val) >> 24) & 0xFF); \
+           *((ptr)++) = (unsigned char)(((val) >> 16) & 0xFF); \
+           *((ptr)++) = (unsigned char)(((val) >> 8) & 0xFF);  \
+           *((ptr)++) = (unsigned char)((val) & 0xFF);         \
+       } while (0)
+
+
 /* Non-incrementing versions of the above. */
 
-#define SAVE_BYTE(ptr, val)                    \
+#define SAVE_8(ptr, val)                       \
        *(ptr) = (unsigned char)((val) & 0xFF)
 
-#define SAVE_SHORT(ptr, val)                   \
+#define SAVE_16_L(ptr, val)                    \
        do {                                    \
            *(ptr) = (unsigned char)((val) & 0xFF);             \
            *((ptr)+1) = (unsigned char)(((val) >> 8) & 0xFF);  \
        } while (0)
 
-#define SAVE_LONG(ptr, val)                    \
+#define SAVE_32_L(ptr, val)                    \
        do {                                    \
            *(ptr) = (unsigned char)((val) & 0xFF);             \
            *((ptr)+1) = (unsigned char)(((val) >> 8) & 0xFF);  \
            *((ptr)+3) = (unsigned char)(((val) >> 24) & 0xFF); \
        } while (0)
 
+#define SAVE_16_B(ptr, val)                    \
+       do {                                    \
+           *(ptr) = (unsigned char)(((val) >> 8) & 0xFF);      \
+           *((ptr)+1) = (unsigned char)((val) & 0xFF);         \
+       } while (0)
+
+#define SAVE_32_B(ptr, val)                    \
+       do {                                    \
+           *(ptr) = (unsigned char)(((val) >> 24) & 0xFF);     \
+           *((ptr)+1) = (unsigned char)(((val) >> 16) & 0xFF); \
+           *((ptr)+2) = (unsigned char)(((val) >> 8) & 0xFF);  \
+           *((ptr)+3) = (unsigned char)((val) & 0xFF);         \
+       } while (0)
+
 /* Direct-to-file versions of the above.  Using the above macros and a single
  * fwrite() will probably be faster than calling these functions many times.
  * These functions return 1 if the write was successful, 0 if not (so their
  * return values can be used like the return value from fwrite()).
  */
 
-size_t fwrite_short(unsigned short val, FILE *f);
-size_t fwrite_long(unsigned long val, FILE *f);
+size_t fwrite_16_l(unsigned short val, FILE *f);
+size_t fwrite_32_l(unsigned long val, FILE *f);
+size_t fwrite_16_b(unsigned short val, FILE *f);
+size_t fwrite_32_b(unsigned long val, FILE *f);
 
 /* Read/Load versions.  val is the variable to receive the data. */
 
-#define READ_BYTE(val, ptr)                    \
+#define READ_8(val, ptr)                       \
        (val) = *((ptr)++) & 0xFF
 
-#define READ_SHORT(val, ptr)                   \
+#define READ_16_L(val, ptr)                    \
        do {                                    \
            (val) = *((ptr)++) & 0xFF;          \
            (val) |= (*((ptr)++) & 0xFF) << 8;  \
        } while (0)
 
-#define READ_LONG(val, ptr)                    \
+#define READ_32_L(val, ptr)                    \
        do {                                    \
            (val) = *((ptr)++) & 0xFF;          \
            (val) |= (*((ptr)++) & 0xFF) << 8;  \
@@ -97,18 +128,32 @@ size_t fwrite_long(unsigned long val, FILE *f);
            (val) |= (*((ptr)++) & 0xFF) << 24; \
        } while (0)
 
+#define READ_16_B(val, ptr)                    \
+       do {                                    \
+           (val) = (*((ptr)++) & 0xFF) << 8;   \
+           (val) |= *((ptr)++) & 0xFF;         \
+       } while (0)
+
+#define READ_32_B(val, ptr)                    \
+       do {                                    \
+           (val) = (*((ptr)++) & 0xFF) << 24;  \
+           (val) |= (*((ptr)++) & 0xFF) << 16; \
+           (val) |= (*((ptr)++) & 0xFF) << 8;  \
+           (val) |= *((ptr)++) & 0xFF;         \
+       } while (0)
+
 /* Non-incrementing versions of the above. */
 
-#define LOAD_BYTE(val, ptr)                    \
+#define LOAD_8(val, ptr)                       \
        (val) = *(ptr) & 0xFF
 
-#define LOAD_SHORT(val, ptr)                   \
+#define LOAD_16_L(val, ptr)                    \
        do {                                    \
            (val) = *(ptr) & 0xFF;              \
            (val) |= (*((ptr)+1) & 0xFF) << 8;  \
        } while (0)
 
-#define LOAD_LONG(val, ptr)                    \
+#define LOAD_32_L(val, ptr)                    \
        do {                                    \
            (val) = (unsigned long)(*(ptr) & 0xFF);                 \
            (val) |= (unsigned long)((*((ptr)+1) & 0xFF) << 8);     \
@@ -116,4 +161,18 @@ size_t fwrite_long(unsigned long val, FILE *f);
            (val) |= (unsigned long)((*((ptr)+3) & 0xFF) << 24);    \
        } while (0)
 
+#define LOAD_16_B(val, ptr)                    \
+       do {                                    \
+           (val) = (*(ptr) & 0xFF) << 8;       \
+           (val) |= *((ptr)+1) & 0xFF;         \
+       } while (0)
+
+#define LOAD_32_B(val, ptr)                    \
+       do {                                    \
+           (val) = (unsigned long)((*(ptr) & 0xFF) << 24);         \
+           (val) |= (unsigned long)((*((ptr)+1) & 0xFF) << 16);    \
+           (val) |= (unsigned long)((*((ptr)+2) & 0xFF) << 8);     \
+           (val) |= (unsigned long)(*((ptr)+3) & 0xFF);            \
+       } while (0)
+
 #endif
index 9f4e936b41274ede3ba7ecc72b25300f5619ff1a..6f98dc262f2d17e8a2cd3fb3981b97b66214fc68 100644 (file)
@@ -529,7 +529,7 @@ floatnum_get_int(const floatnum *flt, unsigned long *ret_val)
        return 1;
     }
 
-    LOAD_LONG(*ret_val, &t[0]);
+    LOAD_32_L(*ret_val, &t[0]);
     return 0;
 }
 
index 99d4786282431094981d7cad8dc99a8160918f4c..38c572218568173833e025d250331adf1ea27e4e 100644 (file)
@@ -551,7 +551,7 @@ intnum_get_sized(const intnum *intn, unsigned char *ptr, size_t size)
        case INTNUM_UL:
            ul = intn->val.ul;
            while (size-- > 0) {
-               WRITE_BYTE(ptr, ul);
+               WRITE_8(ptr, ul);
                if (ul != 0)
                    ul >>= 8;
            }
index f408adb80d57275cee1c69fb222e51c28c171f08..bf4823d15b145d74a42a86d4dca46827de55d1f8 100644 (file)
@@ -37,6 +37,7 @@
 #include "expr-int.h"
 #include "bc-int.h"
 
+#include "arch.h"
 #include "objfmt.h"
 
 
@@ -106,7 +107,7 @@ bin_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize,
                       /*@observer@*/ const bytecode *bc, int rel,
                       /*@unused@*/ /*@null@*/ void *d)
 {
-    /*@dependent@*/ /*@null@*/ const intnum *num;
+    /*@dependent@*/ /*@null@*/ const intnum *intn;
     /*@dependent@*/ /*@null@*/ const floatnum *flt;
 
     assert(info != NULL);
@@ -120,54 +121,13 @@ bin_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize,
 
     /* Handle floating point expressions */
     flt = expr_get_floatnum(ep);
-    if (flt) {
-       int fltret;
-
-       if (!floatnum_check_size(flt, (size_t)valsize)) {
-           ErrorAt((*ep)->line, _("invalid floating point constant size"));
-           return 1;
-       }
-
-       fltret = floatnum_get_sized(flt, *bufp, (size_t)valsize);
-       if (fltret < 0) {
-           ErrorAt((*ep)->line, _("underflow in floating point expression"));
-           return 1;
-       }
-       if (fltret > 0) {
-           ErrorAt((*ep)->line, _("overflow in floating point expression"));
-           return 1;
-       }
-       *bufp += valsize;
-       return 0;
-    }
+    if (flt)
+       return cur_arch->floatnum_tobytes(flt, bufp, valsize, *ep);
 
     /* Handle integer expressions */
-    num = expr_get_intnum(ep, NULL);
-    if (num) {
-       if (rel) {
-           long val;
-           if (valsize != 1 && valsize != 2 && valsize != 4)
-               InternalError(_("tried to do PC-relative offset from invalid sized value"));
-           val = intnum_get_uint(num);
-           val -= bc->len;
-           switch (valsize) {
-               case 1:
-                   WRITE_BYTE(*bufp, val);
-                   break;
-               case 2:
-                   WRITE_SHORT(*bufp, val);
-                   break;
-               case 4:
-                   WRITE_LONG(*bufp, val);
-                   break;
-           }
-       } else {
-           /* Write value out. */
-           intnum_get_sized(num, *bufp, (size_t)valsize);
-           *bufp += valsize;
-       }
-       return 0;
-    }
+    intn = expr_get_intnum(ep, NULL);
+    if (intn)
+       return cur_arch->intnum_tobytes(intn, bufp, valsize, *ep, bc, rel);
 
     /* Check for complex float expressions */
     if (expr_contains(*ep, EXPR_FLOAT)) {