Home | History | Annotate | Download | only in x86
      1 /*
      2  * x86 bytecode utility functions
      3  *
      4  *  Copyright (C) 2001-2007  Peter Johnson
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
     16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
     19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25  * POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 #include <util.h>
     28 
     29 #include <libyasm.h>
     30 
     31 #include "x86arch.h"
     32 
     33 
     34 /* Bytecode callback function prototypes */
     35 
     36 static void x86_bc_insn_destroy(void *contents);
     37 static void x86_bc_insn_print(const void *contents, FILE *f,
     38                               int indent_level);
     39 static int x86_bc_insn_calc_len(yasm_bytecode *bc,
     40                                 yasm_bc_add_span_func add_span,
     41                                 void *add_span_data);
     42 static int x86_bc_insn_expand(yasm_bytecode *bc, int span, long old_val,
     43                               long new_val, /*@out@*/ long *neg_thres,
     44                               /*@out@*/ long *pos_thres);
     45 static int x86_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp,
     46                                unsigned char *bufstart,
     47                                void *d, yasm_output_value_func output_value,
     48                                /*@null@*/ yasm_output_reloc_func output_reloc);
     49 
     50 static void x86_bc_jmp_destroy(void *contents);
     51 static void x86_bc_jmp_print(const void *contents, FILE *f, int indent_level);
     52 static int x86_bc_jmp_calc_len(yasm_bytecode *bc,
     53                                yasm_bc_add_span_func add_span,
     54                                void *add_span_data);
     55 static int x86_bc_jmp_expand(yasm_bytecode *bc, int span, long old_val,
     56                              long new_val, /*@out@*/ long *neg_thres,
     57                              /*@out@*/ long *pos_thres);
     58 static int x86_bc_jmp_tobytes(yasm_bytecode *bc, unsigned char **bufp,
     59                               unsigned char *bufstart,
     60                               void *d, yasm_output_value_func output_value,
     61                               /*@null@*/ yasm_output_reloc_func output_reloc);
     62 
     63 static void x86_bc_jmpfar_destroy(void *contents);
     64 static void x86_bc_jmpfar_print(const void *contents, FILE *f,
     65                                 int indent_level);
     66 static int x86_bc_jmpfar_calc_len(yasm_bytecode *bc,
     67                                   yasm_bc_add_span_func add_span,
     68                                   void *add_span_data);
     69 static int x86_bc_jmpfar_tobytes
     70     (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
     71      yasm_output_value_func output_value,
     72      /*@null@*/ yasm_output_reloc_func output_reloc);
     73 
     74 /* Bytecode callback structures */
     75 
     76 static const yasm_bytecode_callback x86_bc_callback_insn = {
     77     x86_bc_insn_destroy,
     78     x86_bc_insn_print,
     79     yasm_bc_finalize_common,
     80     NULL,
     81     x86_bc_insn_calc_len,
     82     x86_bc_insn_expand,
     83     x86_bc_insn_tobytes,
     84     0
     85 };
     86 
     87 static const yasm_bytecode_callback x86_bc_callback_jmp = {
     88     x86_bc_jmp_destroy,
     89     x86_bc_jmp_print,
     90     yasm_bc_finalize_common,
     91     NULL,
     92     x86_bc_jmp_calc_len,
     93     x86_bc_jmp_expand,
     94     x86_bc_jmp_tobytes,
     95     0
     96 };
     97 
     98 static const yasm_bytecode_callback x86_bc_callback_jmpfar = {
     99     x86_bc_jmpfar_destroy,
    100     x86_bc_jmpfar_print,
    101     yasm_bc_finalize_common,
    102     NULL,
    103     x86_bc_jmpfar_calc_len,
    104     yasm_bc_expand_common,
    105     x86_bc_jmpfar_tobytes,
    106     0
    107 };
    108 
    109 int
    110 yasm_x86__set_rex_from_reg(unsigned char *rex, unsigned char *low3,
    111                            uintptr_t reg, unsigned int bits,
    112                            x86_rex_bit_pos rexbit)
    113 {
    114     *low3 = (unsigned char)(reg&7);
    115 
    116     if (bits == 64) {
    117         x86_expritem_reg_size size = (x86_expritem_reg_size)(reg & ~0xFUL);
    118 
    119         if (size == X86_REG8X || (reg & 0xF) >= 8) {
    120             /* Check to make sure we can set it */
    121             if (*rex == 0xff) {
    122                 yasm_error_set(YASM_ERROR_TYPE,
    123                     N_("cannot use A/B/C/DH with instruction needing REX"));
    124                 return 1;
    125             }
    126             *rex |= 0x40 | (((reg & 8) >> 3) << rexbit);
    127         } else if (size == X86_REG8 && (reg & 7) >= 4) {
    128             /* AH/BH/CH/DH, so no REX allowed */
    129             if (*rex != 0 && *rex != 0xff) {
    130                 yasm_error_set(YASM_ERROR_TYPE,
    131                     N_("cannot use A/B/C/DH with instruction needing REX"));
    132                 return 1;
    133             }
    134             *rex = 0xff;    /* Flag so we can NEVER set it (see above) */
    135         }
    136     }
    137 
    138     return 0;
    139 }
    140 
    141 void
    142 yasm_x86__bc_transform_insn(yasm_bytecode *bc, x86_insn *insn)
    143 {
    144     yasm_bc_transform(bc, &x86_bc_callback_insn, insn);
    145 }
    146 
    147 void
    148 yasm_x86__bc_transform_jmp(yasm_bytecode *bc, x86_jmp *jmp)
    149 {
    150     yasm_bc_transform(bc, &x86_bc_callback_jmp, jmp);
    151 }
    152 
    153 void
    154 yasm_x86__bc_transform_jmpfar(yasm_bytecode *bc, x86_jmpfar *jmpfar)
    155 {
    156     yasm_bc_transform(bc, &x86_bc_callback_jmpfar, jmpfar);
    157 }
    158 
    159 void
    160 yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare,
    161                   yasm_bytecode *precbc)
    162 {
    163     if (yasm_value_finalize(&x86_ea->ea.disp, precbc))
    164         yasm_error_set(YASM_ERROR_TOO_COMPLEX,
    165                        N_("effective address too complex"));
    166     x86_ea->modrm &= 0xC7;                  /* zero spare/reg bits */
    167     x86_ea->modrm |= (spare << 3) & 0x38;   /* plug in provided bits */
    168 }
    169 
    170 void
    171 yasm_x86__ea_set_disponly(x86_effaddr *x86_ea)
    172 {
    173     x86_ea->valid_modrm = 0;
    174     x86_ea->need_modrm = 0;
    175     x86_ea->valid_sib = 0;
    176     x86_ea->need_sib = 0;
    177 }
    178 
    179 static x86_effaddr *
    180 ea_create(void)
    181 {
    182     x86_effaddr *x86_ea = yasm_xmalloc(sizeof(x86_effaddr));
    183 
    184     yasm_value_initialize(&x86_ea->ea.disp, NULL, 0);
    185     x86_ea->ea.need_nonzero_len = 0;
    186     x86_ea->ea.need_disp = 0;
    187     x86_ea->ea.nosplit = 0;
    188     x86_ea->ea.strong = 0;
    189     x86_ea->ea.segreg = 0;
    190     x86_ea->ea.pc_rel = 0;
    191     x86_ea->ea.not_pc_rel = 0;
    192     x86_ea->ea.data_len = 0;
    193     x86_ea->vsib_mode = 0;
    194     x86_ea->modrm = 0;
    195     x86_ea->valid_modrm = 0;
    196     x86_ea->need_modrm = 0;
    197     x86_ea->sib = 0;
    198     x86_ea->valid_sib = 0;
    199     x86_ea->need_sib = 0;
    200 
    201     return x86_ea;
    202 }
    203 
    204 x86_effaddr *
    205 yasm_x86__ea_create_reg(x86_effaddr *x86_ea, unsigned long reg,
    206                         unsigned char *rex, unsigned int bits)
    207 {
    208     unsigned char rm;
    209 
    210     if (yasm_x86__set_rex_from_reg(rex, &rm, reg, bits, X86_REX_B))
    211         return NULL;
    212 
    213     if (!x86_ea)
    214         x86_ea = ea_create();
    215     x86_ea->modrm = 0xC0 | rm;  /* Mod=11, R/M=Reg, Reg=0 */
    216     x86_ea->valid_modrm = 1;
    217     x86_ea->need_modrm = 1;
    218 
    219     return x86_ea;
    220 }
    221 
    222 yasm_effaddr *
    223 yasm_x86__ea_create_expr(yasm_arch *arch, yasm_expr *e)
    224 {
    225     yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
    226     x86_effaddr *x86_ea;
    227 
    228     x86_ea = ea_create();
    229 
    230     if (arch_x86->parser == X86_PARSER_GAS) {
    231         /* Need to change foo+rip into foo wrt rip (even in .intel_syntax mode).
    232          * Note this assumes a particular ordering coming from the parser
    233          * to work (it's not very smart)!
    234          */
    235         if (e->op == YASM_EXPR_ADD && e->terms[0].type == YASM_EXPR_REG
    236             && e->terms[0].data.reg == X86_RIP) {
    237             /* replace register with 0 */
    238             e->terms[0].type = YASM_EXPR_INT;
    239             e->terms[0].data.intn = yasm_intnum_create_uint(0);
    240             /* build new wrt expression */
    241             e = yasm_expr_create(YASM_EXPR_WRT, yasm_expr_expr(e),
    242                                  yasm_expr_reg(X86_RIP), e->line);
    243         }
    244     }
    245     yasm_value_initialize(&x86_ea->ea.disp, e, 0);
    246     x86_ea->ea.need_disp = 1;
    247     x86_ea->need_modrm = 1;
    248     /* We won't know whether we need an SIB until we know more about expr and
    249      * the BITS/address override setting.
    250      */
    251     x86_ea->need_sib = 0xff;
    252 
    253     x86_ea->ea.data_len = 0;
    254 
    255     return (yasm_effaddr *)x86_ea;
    256 }
    257 
    258 /*@-compmempass@*/
    259 x86_effaddr *
    260 yasm_x86__ea_create_imm(x86_effaddr *x86_ea, yasm_expr *imm,
    261                         unsigned int im_len)
    262 {
    263     if (!x86_ea)
    264         x86_ea = ea_create();
    265     yasm_value_initialize(&x86_ea->ea.disp, imm, im_len);
    266     x86_ea->ea.need_disp = 1;
    267 
    268     return x86_ea;
    269 }
    270 /*@=compmempass@*/
    271 
    272 void
    273 yasm_x86__bc_apply_prefixes(x86_common *common, unsigned char *rex,
    274                             unsigned int def_opersize_64,
    275                             unsigned int num_prefixes, uintptr_t *prefixes)
    276 {
    277     unsigned int i;
    278     int first = 1;
    279 
    280     for (i=0; i<num_prefixes; i++) {
    281         switch ((x86_parse_insn_prefix)(prefixes[i] & 0xff00)) {
    282             case X86_LOCKREP:
    283                 if (common->lockrep_pre != 0)
    284                     yasm_warn_set(YASM_WARN_GENERAL,
    285                         N_("multiple LOCK or REP prefixes, using leftmost"));
    286                 common->lockrep_pre = (unsigned char)prefixes[i] & 0xff;
    287                 break;
    288             case X86_ADDRSIZE:
    289                 common->addrsize = (unsigned char)prefixes[i] & 0xff;
    290                 break;
    291             case X86_OPERSIZE:
    292                 common->opersize = (unsigned char)prefixes[i] & 0xff;
    293                 if (common->mode_bits == 64 && common->opersize == 64 &&
    294                     def_opersize_64 != 64) {
    295                     if (!rex)
    296                         yasm_warn_set(YASM_WARN_GENERAL,
    297                                       N_("ignoring REX prefix on jump"));
    298                     else if (*rex == 0xff)
    299                         yasm_warn_set(YASM_WARN_GENERAL,
    300                             N_("REX prefix not allowed on this instruction, ignoring"));
    301                     else
    302                         *rex = 0x48;
    303                 }
    304                 break;
    305             case X86_SEGREG:
    306                 /* This is a hack.. we should really be putting this in the
    307                  * the effective address!
    308                  */
    309                 common->lockrep_pre = (unsigned char)prefixes[i] & 0xff;
    310                 break;
    311             case X86_REX:
    312                 if (!rex)
    313                     yasm_warn_set(YASM_WARN_GENERAL,
    314                                   N_("ignoring REX prefix on jump"));
    315                 else if (*rex == 0xff)
    316                     yasm_warn_set(YASM_WARN_GENERAL,
    317                         N_("REX prefix not allowed on this instruction, ignoring"));
    318                 else {
    319                     if (*rex != 0) {
    320                         if (first)
    321                             yasm_warn_set(YASM_WARN_GENERAL,
    322                                 N_("overriding generated REX prefix"));
    323                         else
    324                             yasm_warn_set(YASM_WARN_GENERAL,
    325                                 N_("multiple REX prefixes, using leftmost"));
    326                     }
    327                     /* Here we assume that we can't get this prefix in non
    328                      * 64 bit mode due to checks in parse_check_prefix().
    329                      */
    330                     common->mode_bits = 64;
    331                     *rex = (unsigned char)prefixes[i] & 0xff;
    332                 }
    333                 first = 0;
    334                 break;
    335         }
    336     }
    337 }
    338 
    339 static void
    340 x86_bc_insn_destroy(void *contents)
    341 {
    342     x86_insn *insn = (x86_insn *)contents;
    343     if (insn->x86_ea)
    344         yasm_x86__ea_destroy((yasm_effaddr *)insn->x86_ea);
    345     if (insn->imm) {
    346         yasm_value_delete(insn->imm);
    347         yasm_xfree(insn->imm);
    348     }
    349     yasm_xfree(contents);
    350 }
    351 
    352 static void
    353 x86_bc_jmp_destroy(void *contents)
    354 {
    355     x86_jmp *jmp = (x86_jmp *)contents;
    356     yasm_value_delete(&jmp->target);
    357     yasm_xfree(contents);
    358 }
    359 
    360 static void
    361 x86_bc_jmpfar_destroy(void *contents)
    362 {
    363     x86_jmpfar *jmpfar = (x86_jmpfar *)contents;
    364     yasm_value_delete(&jmpfar->segment);
    365     yasm_value_delete(&jmpfar->offset);
    366     yasm_xfree(contents);
    367 }
    368 
    369 void
    370 yasm_x86__ea_destroy(yasm_effaddr *ea)
    371 {
    372     yasm_value_delete(&ea->disp);
    373     yasm_xfree(ea);
    374 }
    375 
    376 void
    377 yasm_x86__ea_print(const yasm_effaddr *ea, FILE *f, int indent_level)
    378 {
    379     const x86_effaddr *x86_ea = (const x86_effaddr *)ea;
    380     fprintf(f, "%*sDisp:\n", indent_level, "");
    381     yasm_value_print(&ea->disp, f, indent_level+1);
    382     fprintf(f, "%*sNoSplit=%u\n", indent_level, "", (unsigned int)ea->nosplit);
    383     fprintf(f, "%*sSegmentOv=%02x\n", indent_level, "",
    384             (unsigned int)x86_ea->ea.segreg);
    385     fprintf(f, "%*sVSIBMode=%u\n", indent_level, "",
    386             (unsigned int)x86_ea->vsib_mode);
    387     fprintf(f, "%*sModRM=%03o ValidRM=%u NeedRM=%u\n", indent_level, "",
    388             (unsigned int)x86_ea->modrm, (unsigned int)x86_ea->valid_modrm,
    389             (unsigned int)x86_ea->need_modrm);
    390     fprintf(f, "%*sSIB=%03o ValidSIB=%u NeedSIB=%u\n", indent_level, "",
    391             (unsigned int)x86_ea->sib, (unsigned int)x86_ea->valid_sib,
    392             (unsigned int)x86_ea->need_sib);
    393 }
    394 
    395 static void
    396 x86_common_print(const x86_common *common, FILE *f, int indent_level)
    397 {
    398     fprintf(f, "%*sAddrSize=%u OperSize=%u LockRepPre=%02x BITS=%u\n",
    399             indent_level, "",
    400             (unsigned int)common->addrsize,
    401             (unsigned int)common->opersize,
    402             (unsigned int)common->lockrep_pre,
    403             (unsigned int)common->mode_bits);
    404 }
    405 
    406 static void
    407 x86_opcode_print(const x86_opcode *opcode, FILE *f, int indent_level)
    408 {
    409     fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n", indent_level, "",
    410             (unsigned int)opcode->opcode[0],
    411             (unsigned int)opcode->opcode[1],
    412             (unsigned int)opcode->opcode[2],
    413             (unsigned int)opcode->len);
    414 }
    415 
    416 static void
    417 x86_bc_insn_print(const void *contents, FILE *f, int indent_level)
    418 {
    419     const x86_insn *insn = (const x86_insn *)contents;
    420 
    421     fprintf(f, "%*s_Instruction_\n", indent_level, "");
    422     fprintf(f, "%*sEffective Address:", indent_level, "");
    423     if (insn->x86_ea) {
    424         fprintf(f, "\n");
    425         yasm_x86__ea_print((yasm_effaddr *)insn->x86_ea, f, indent_level+1);
    426     } else
    427         fprintf(f, " (nil)\n");
    428     fprintf(f, "%*sImmediate Value:", indent_level, "");
    429     if (!insn->imm)
    430         fprintf(f, " (nil)\n");
    431     else {
    432         indent_level++;
    433         fprintf(f, "\n");
    434         yasm_value_print(insn->imm, f, indent_level);
    435         indent_level--;
    436     }
    437     x86_opcode_print(&insn->opcode, f, indent_level);
    438     x86_common_print(&insn->common, f, indent_level);
    439     fprintf(f, "%*sSpPre=%02x REX=%03o PostOp=%u\n", indent_level, "",
    440             (unsigned int)insn->special_prefix,
    441             (unsigned int)insn->rex,
    442             (unsigned int)insn->postop);
    443 }
    444 
    445 static void
    446 x86_bc_jmp_print(const void *contents, FILE *f, int indent_level)
    447 {
    448     const x86_jmp *jmp = (const x86_jmp *)contents;
    449 
    450     fprintf(f, "%*s_Jump_\n", indent_level, "");
    451     fprintf(f, "%*sTarget:\n", indent_level, "");
    452     yasm_value_print(&jmp->target, f, indent_level+1);
    453     /* FIXME
    454     fprintf(f, "%*sOrigin=\n", indent_level, "");
    455     yasm_symrec_print(jmp->origin, f, indent_level+1);
    456     */
    457     fprintf(f, "\n%*sShort Form:\n", indent_level, "");
    458     if (jmp->shortop.len == 0)
    459         fprintf(f, "%*sNone\n", indent_level+1, "");
    460     else
    461         x86_opcode_print(&jmp->shortop, f, indent_level+1);
    462     fprintf(f, "%*sNear Form:\n", indent_level, "");
    463     if (jmp->nearop.len == 0)
    464         fprintf(f, "%*sNone\n", indent_level+1, "");
    465     else
    466         x86_opcode_print(&jmp->nearop, f, indent_level+1);
    467     fprintf(f, "%*sOpSel=", indent_level, "");
    468     switch (jmp->op_sel) {
    469         case JMP_NONE:
    470             fprintf(f, "None");
    471             break;
    472         case JMP_SHORT:
    473             fprintf(f, "Short");
    474             break;
    475         case JMP_NEAR:
    476             fprintf(f, "Near");
    477             break;
    478         case JMP_SHORT_FORCED:
    479             fprintf(f, "Forced Short");
    480             break;
    481         case JMP_NEAR_FORCED:
    482             fprintf(f, "Forced Near");
    483             break;
    484         default:
    485             fprintf(f, "UNKNOWN!!");
    486             break;
    487     }
    488     x86_common_print(&jmp->common, f, indent_level);
    489 }
    490 
    491 static void
    492 x86_bc_jmpfar_print(const void *contents, FILE *f, int indent_level)
    493 {
    494     const x86_jmpfar *jmpfar = (const x86_jmpfar *)contents;
    495 
    496     fprintf(f, "%*s_Far_Jump_\n", indent_level, "");
    497     fprintf(f, "%*sSegment:\n", indent_level, "");
    498     yasm_value_print(&jmpfar->segment, f, indent_level+1);
    499     fprintf(f, "%*sOffset:\n", indent_level, "");
    500     yasm_value_print(&jmpfar->offset, f, indent_level+1);
    501     x86_opcode_print(&jmpfar->opcode, f, indent_level);
    502     x86_common_print(&jmpfar->common, f, indent_level);
    503 }
    504 
    505 static unsigned int
    506 x86_common_calc_len(const x86_common *common)
    507 {
    508     unsigned int len = 0;
    509 
    510     if (common->addrsize != 0 && common->addrsize != common->mode_bits)
    511         len++;
    512     if (common->opersize != 0 &&
    513         ((common->mode_bits != 64 && common->opersize != common->mode_bits) ||
    514          (common->mode_bits == 64 && common->opersize == 16)))
    515         len++;
    516     if (common->lockrep_pre != 0)
    517         len++;
    518 
    519     return len;
    520 }
    521 
    522 static int
    523 x86_bc_insn_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
    524                      void *add_span_data)
    525 {
    526     x86_insn *insn = (x86_insn *)bc->contents;
    527     x86_effaddr *x86_ea = insn->x86_ea;
    528     yasm_value *imm = insn->imm;
    529 
    530     if (x86_ea) {
    531         /* Check validity of effective address and calc R/M bits of
    532          * Mod/RM byte and SIB byte.  We won't know the Mod field
    533          * of the Mod/RM byte until we know more about the
    534          * displacement.
    535          */
    536         if (yasm_x86__expr_checkea(x86_ea, &insn->common.addrsize,
    537                 insn->common.mode_bits, insn->postop == X86_POSTOP_ADDRESS16,
    538                 &insn->rex, bc))
    539             /* failed, don't bother checking rest of insn */
    540             return -1;
    541 
    542         if (x86_ea->ea.disp.size == 0 && x86_ea->ea.need_nonzero_len) {
    543             /* Handle unknown case, default to byte-sized and set as
    544              * critical expression.
    545              */
    546             x86_ea->ea.disp.size = 8;
    547             add_span(add_span_data, bc, 1, &x86_ea->ea.disp, -128, 127);
    548         }
    549         bc->len += x86_ea->ea.disp.size/8;
    550 
    551         /* Handle address16 postop case */
    552         if (insn->postop == X86_POSTOP_ADDRESS16)
    553             insn->common.addrsize = 0;
    554 
    555         /* Compute length of ea and add to total */
    556         bc->len += x86_ea->need_modrm + (x86_ea->need_sib ? 1:0);
    557         bc->len += (x86_ea->ea.segreg != 0) ? 1 : 0;
    558     }
    559 
    560     if (imm) {
    561         unsigned int immlen = imm->size;
    562 
    563         /* TODO: check imm->len vs. sized len from expr? */
    564 
    565         /* Handle signext_imm8 postop special-casing */
    566         if (insn->postop == X86_POSTOP_SIGNEXT_IMM8) {
    567             /*@null@*/ /*@only@*/ yasm_intnum *num;
    568             num = yasm_value_get_intnum(imm, NULL, 0);
    569 
    570             if (!num) {
    571                 /* Unknown; default to byte form and set as critical
    572                  * expression.
    573                  */
    574                 immlen = 8;
    575                 add_span(add_span_data, bc, 2, imm, -128, 127);
    576             } else {
    577                 if (yasm_intnum_in_range(num, -128, 127)) {
    578                     /* We can use the sign-extended byte form: shorten
    579                      * the immediate length to 1 and make the byte form
    580                      * permanent.
    581                      */
    582                     imm->size = 8;
    583                     imm->sign = 1;
    584                     immlen = 8;
    585                 } else {
    586                     /* We can't.  Copy over the word-sized opcode. */
    587                     insn->opcode.opcode[0] =
    588                         insn->opcode.opcode[insn->opcode.len];
    589                     insn->opcode.len = 1;
    590                 }
    591                 insn->postop = X86_POSTOP_NONE;
    592                 yasm_intnum_destroy(num);
    593             }
    594         }
    595 
    596         bc->len += immlen/8;
    597     }
    598 
    599     /* VEX and XOP prefixes never have REX (it's embedded in the opcode).
    600      * For VEX, we can come into this function with the three byte form,
    601      * so we need to see if we can optimize to the two byte form.
    602      * We can't do it earlier, as we don't know all of the REX byte until now.
    603      */
    604     if (insn->special_prefix == 0xC4) {
    605         /* See if we can shorten the VEX prefix to its two byte form.
    606          * In order to do this, REX.X, REX.B, and REX.W/VEX.W must all be 0,
    607          * and the VEX mmmmm field must be 1.
    608          */
    609         if ((insn->opcode.opcode[0] & 0x1F) == 1 &&
    610             (insn->opcode.opcode[1] & 0x80) == 0 &&
    611             (insn->rex == 0xff || (insn->rex & 0x0B) == 0)) {
    612             insn->opcode.opcode[0] = insn->opcode.opcode[1];
    613             insn->opcode.opcode[1] = insn->opcode.opcode[2];
    614             insn->opcode.opcode[2] = 0; /* sanity */
    615             insn->opcode.len = 2;
    616             insn->special_prefix = 0xC5;    /* mark as two-byte VEX */
    617         }
    618     } else if (insn->rex != 0xff && insn->rex != 0 &&
    619                insn->special_prefix != 0xC5 && insn->special_prefix != 0x8F)
    620         bc->len++;
    621 
    622     bc->len += insn->opcode.len;
    623     bc->len += x86_common_calc_len(&insn->common);
    624     bc->len += (insn->special_prefix != 0) ? 1:0;
    625     return 0;
    626 }
    627 
    628 static int
    629 x86_bc_insn_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
    630                    /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres)
    631 {
    632     x86_insn *insn = (x86_insn *)bc->contents;
    633     x86_effaddr *x86_ea = insn->x86_ea;
    634     yasm_effaddr *ea = &x86_ea->ea;
    635     yasm_value *imm = insn->imm;
    636 
    637     if (ea && span == 1) {
    638         /* Change displacement length into word-sized */
    639         if (ea->disp.size == 8) {
    640             ea->disp.size = (insn->common.addrsize == 16) ? 16 : 32;
    641             x86_ea->modrm &= ~0300;
    642             x86_ea->modrm |= 0200;
    643             bc->len--;
    644             bc->len += ea->disp.size/8;
    645         }
    646     }
    647 
    648     if (imm && span == 2) {
    649         if (insn->postop == X86_POSTOP_SIGNEXT_IMM8) {
    650             /* Update bc->len for new opcode and immediate size */
    651             bc->len -= insn->opcode.len;
    652             bc->len += imm->size/8;
    653 
    654             /* Change to the word-sized opcode */
    655             insn->opcode.opcode[0] = insn->opcode.opcode[insn->opcode.len];
    656             insn->opcode.len = 1;
    657             insn->postop = X86_POSTOP_NONE;
    658         }
    659     }
    660 
    661     return 0;
    662 }
    663 
    664 static int
    665 x86_bc_jmp_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
    666                     void *add_span_data)
    667 {
    668     x86_jmp *jmp = (x86_jmp *)bc->contents;
    669     yasm_bytecode *target_prevbc;
    670     unsigned char opersize;
    671 
    672     /* As opersize may be 0, figure out its "real" value. */
    673     opersize = (jmp->common.opersize == 0) ?
    674         jmp->common.mode_bits : jmp->common.opersize;
    675 
    676     bc->len += x86_common_calc_len(&jmp->common);
    677 
    678     if (jmp->op_sel == JMP_NEAR_FORCED || jmp->shortop.len == 0) {
    679         if (jmp->nearop.len == 0) {
    680             yasm_error_set(YASM_ERROR_TYPE, N_("near jump does not exist"));
    681             return -1;
    682         }
    683 
    684         /* Near jump, no spans needed */
    685         if (jmp->shortop.len == 0)
    686             jmp->op_sel = JMP_NEAR;
    687         bc->len += jmp->nearop.len;
    688         bc->len += (opersize == 16) ? 2 : 4;
    689         return 0;
    690     }
    691 
    692     if (jmp->op_sel == JMP_SHORT_FORCED || jmp->nearop.len == 0) {
    693         if (jmp->shortop.len == 0) {
    694             yasm_error_set(YASM_ERROR_TYPE, N_("short jump does not exist"));
    695             return -1;
    696         }
    697 
    698         /* We want to be sure to error if we exceed short length, so
    699          * put it in as a dependent expression (falling through).
    700          */
    701     }
    702 
    703     if (jmp->target.rel
    704         && (!yasm_symrec_get_label(jmp->target.rel, &target_prevbc)
    705             || target_prevbc->section != bc->section)) {
    706         /* External or out of segment, so we can't check distance.
    707          * Allowing short jumps depends on the objfmt supporting
    708          * 8-bit relocs.  While most don't, some might, so allow it here.
    709          * Otherwise default to word-sized.
    710          * The objfmt will error if not supported.
    711          */
    712         if (jmp->op_sel == JMP_SHORT_FORCED || jmp->nearop.len == 0) {
    713             if (jmp->op_sel == JMP_NONE)
    714                 jmp->op_sel = JMP_SHORT;
    715             bc->len += jmp->shortop.len + 1;
    716         } else {
    717             jmp->op_sel = JMP_NEAR;
    718             bc->len += jmp->nearop.len;
    719             bc->len += (opersize == 16) ? 2 : 4;
    720         }
    721         return 0;
    722     }
    723 
    724     /* Default to short jump and generate span */
    725     if (jmp->op_sel == JMP_NONE)
    726         jmp->op_sel = JMP_SHORT;
    727     bc->len += jmp->shortop.len + 1;
    728     add_span(add_span_data, bc, 1, &jmp->target, -128+(long)bc->len,
    729              127+(long)bc->len);
    730     return 0;
    731 }
    732 
    733 static int
    734 x86_bc_jmp_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
    735                   /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres)
    736 {
    737     x86_jmp *jmp = (x86_jmp *)bc->contents;
    738     unsigned char opersize;
    739 
    740     if (span != 1)
    741         yasm_internal_error(N_("unrecognized span id"));
    742 
    743     /* As opersize may be 0, figure out its "real" value. */
    744     opersize = (jmp->common.opersize == 0) ?
    745         jmp->common.mode_bits : jmp->common.opersize;
    746 
    747     if (jmp->op_sel == JMP_SHORT_FORCED || jmp->nearop.len == 0) {
    748         yasm_error_set(YASM_ERROR_VALUE, N_("short jump out of range"));
    749         return -1;
    750     }
    751 
    752     if (jmp->op_sel == JMP_NEAR)
    753         yasm_internal_error(N_("trying to expand an already-near jump"));
    754 
    755     /* Upgrade to a near jump */
    756     jmp->op_sel = JMP_NEAR;
    757     bc->len -= jmp->shortop.len + 1;
    758     bc->len += jmp->nearop.len;
    759     bc->len += (opersize == 16) ? 2 : 4;
    760 
    761     return 0;
    762 }
    763 
    764 static int
    765 x86_bc_jmpfar_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
    766                        void *add_span_data)
    767 {
    768     x86_jmpfar *jmpfar = (x86_jmpfar *)bc->contents;
    769     unsigned char opersize;
    770 
    771     opersize = (jmpfar->common.opersize == 0) ?
    772         jmpfar->common.mode_bits : jmpfar->common.opersize;
    773 
    774     bc->len += jmpfar->opcode.len;
    775     bc->len += 2;       /* segment */
    776     bc->len += (opersize == 16) ? 2 : 4;
    777     bc->len += x86_common_calc_len(&jmpfar->common);
    778 
    779     return 0;
    780 }
    781 
    782 static void
    783 x86_common_tobytes(const x86_common *common, unsigned char **bufp,
    784                    unsigned int segreg)
    785 {
    786     if (segreg != 0)
    787         YASM_WRITE_8(*bufp, (unsigned char)segreg);
    788     if (common->addrsize != 0 && common->addrsize != common->mode_bits)
    789         YASM_WRITE_8(*bufp, 0x67);
    790     if (common->opersize != 0 &&
    791         ((common->mode_bits != 64 && common->opersize != common->mode_bits) ||
    792          (common->mode_bits == 64 && common->opersize == 16)))
    793         YASM_WRITE_8(*bufp, 0x66);
    794     if (common->lockrep_pre != 0)
    795         YASM_WRITE_8(*bufp, common->lockrep_pre);
    796 }
    797 
    798 static void
    799 x86_opcode_tobytes(const x86_opcode *opcode, unsigned char **bufp)
    800 {
    801     unsigned int i;
    802     for (i=0; i<opcode->len; i++)
    803         YASM_WRITE_8(*bufp, opcode->opcode[i]);
    804 }
    805 
    806 static int
    807 x86_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp,
    808                     unsigned char *bufstart, void *d,
    809                     yasm_output_value_func output_value,
    810                     /*@unused@*/ yasm_output_reloc_func output_reloc)
    811 {
    812     x86_insn *insn = (x86_insn *)bc->contents;
    813     /*@null@*/ x86_effaddr *x86_ea = (x86_effaddr *)insn->x86_ea;
    814     yasm_value *imm = insn->imm;
    815 
    816     /* Prefixes */
    817     x86_common_tobytes(&insn->common, bufp,
    818                        x86_ea ? (unsigned int)(x86_ea->ea.segreg>>8) : 0);
    819     if (insn->special_prefix != 0)
    820         YASM_WRITE_8(*bufp, insn->special_prefix);
    821     if (insn->special_prefix == 0xC4 || insn->special_prefix == 0x8F) {
    822         /* 3-byte VEX/XOP; merge in 1s complement of REX.R, REX.X, REX.B */
    823         insn->opcode.opcode[0] &= 0x1F;
    824         if (insn->rex != 0xff)
    825             insn->opcode.opcode[0] |= ((~insn->rex) & 0x07) << 5;
    826         /* merge REX.W via ORing; there should never be a case in which REX.W
    827          * is important when VEX.W is already set by the instruction.
    828          */
    829         if (insn->rex != 0xff && (insn->rex & 0x8) != 0)
    830             insn->opcode.opcode[1] |= 0x80;
    831     } else if (insn->special_prefix == 0xC5) {
    832         /* 2-byte VEX; merge in 1s complement of REX.R */
    833         insn->opcode.opcode[0] &= 0x7F;
    834         if (insn->rex != 0xff && (insn->rex & 0x4) == 0)
    835             insn->opcode.opcode[0] |= 0x80;
    836         /* No other REX bits should be set */
    837         if (insn->rex != 0xff && (insn->rex & 0xB) != 0)
    838             yasm_internal_error(N_("x86: REX.WXB set, but 2-byte VEX"));
    839     } else if (insn->rex != 0xff && insn->rex != 0) {
    840         if (insn->common.mode_bits != 64)
    841             yasm_internal_error(N_("x86: got a REX prefix in non-64-bit mode"));
    842         YASM_WRITE_8(*bufp, insn->rex);
    843     }
    844 
    845     /* Opcode */
    846     x86_opcode_tobytes(&insn->opcode, bufp);
    847 
    848     /* Effective address: ModR/M (if required), SIB (if required), and
    849      * displacement (if required).
    850      */
    851     if (x86_ea) {
    852         if (x86_ea->need_modrm) {
    853             if (!x86_ea->valid_modrm)
    854                 yasm_internal_error(N_("invalid Mod/RM in x86 tobytes_insn"));
    855             YASM_WRITE_8(*bufp, x86_ea->modrm);
    856         }
    857 
    858         if (x86_ea->need_sib) {
    859             if (!x86_ea->valid_sib)
    860                 yasm_internal_error(N_("invalid SIB in x86 tobytes_insn"));
    861             YASM_WRITE_8(*bufp, x86_ea->sib);
    862         }
    863 
    864         if (x86_ea->ea.need_disp) {
    865             unsigned int disp_len = x86_ea->ea.disp.size/8;
    866 
    867             if (x86_ea->ea.disp.ip_rel) {
    868                 /* Adjust relative displacement to end of bytecode */
    869                 /*@only@*/ yasm_intnum *delta;
    870                 delta = yasm_intnum_create_int(-(long)bc->len);
    871                 if (!x86_ea->ea.disp.abs)
    872                     x86_ea->ea.disp.abs =
    873                         yasm_expr_create_ident(yasm_expr_int(delta), bc->line);
    874                 else
    875                     x86_ea->ea.disp.abs =
    876                         yasm_expr_create(YASM_EXPR_ADD,
    877                                          yasm_expr_expr(x86_ea->ea.disp.abs),
    878                                          yasm_expr_int(delta), bc->line);
    879             }
    880             if (output_value(&x86_ea->ea.disp, *bufp, disp_len,
    881                              (unsigned long)(*bufp-bufstart), bc, 1, d))
    882                 return 1;
    883             *bufp += disp_len;
    884         }
    885     }
    886 
    887     /* Immediate (if required) */
    888     if (imm) {
    889         unsigned int imm_len;
    890         if (insn->postop == X86_POSTOP_SIGNEXT_IMM8) {
    891             /* If we got here with this postop still set, we need to force
    892              * imm size to 8 here.
    893              */
    894             imm->size = 8;
    895             imm->sign = 1;
    896             imm_len = 1;
    897         } else
    898             imm_len = imm->size/8;
    899         if (output_value(imm, *bufp, imm_len, (unsigned long)(*bufp-bufstart),
    900                          bc, 1, d))
    901             return 1;
    902         *bufp += imm_len;
    903     }
    904 
    905     return 0;
    906 }
    907 
    908 static int
    909 x86_bc_jmp_tobytes(yasm_bytecode *bc, unsigned char **bufp,
    910                    unsigned char *bufstart, void *d,
    911                    yasm_output_value_func output_value,
    912                    /*@unused@*/ yasm_output_reloc_func output_reloc)
    913 {
    914     x86_jmp *jmp = (x86_jmp *)bc->contents;
    915     unsigned char opersize;
    916     unsigned int i;
    917     /*@only@*/ yasm_intnum *delta;
    918 
    919     /* Prefixes */
    920     x86_common_tobytes(&jmp->common, bufp, 0);
    921 
    922     /* As opersize may be 0, figure out its "real" value. */
    923     opersize = (jmp->common.opersize == 0) ?
    924         jmp->common.mode_bits : jmp->common.opersize;
    925 
    926     /* Check here again to see if forms are actually legal. */
    927     switch (jmp->op_sel) {
    928         case JMP_SHORT_FORCED:
    929         case JMP_SHORT:
    930             /* 1 byte relative displacement */
    931             if (jmp->shortop.len == 0)
    932                 yasm_internal_error(N_("short jump does not exist"));
    933 
    934             /* Opcode */
    935             x86_opcode_tobytes(&jmp->shortop, bufp);
    936 
    937             /* Adjust relative displacement to end of bytecode */
    938             delta = yasm_intnum_create_int(-(long)bc->len);
    939             if (!jmp->target.abs)
    940                 jmp->target.abs = yasm_expr_create_ident(yasm_expr_int(delta),
    941                                                          bc->line);
    942             else
    943                 jmp->target.abs =
    944                     yasm_expr_create(YASM_EXPR_ADD,
    945                                      yasm_expr_expr(jmp->target.abs),
    946                                      yasm_expr_int(delta), bc->line);
    947 
    948             jmp->target.size = 8;
    949             jmp->target.sign = 1;
    950             if (output_value(&jmp->target, *bufp, 1,
    951                              (unsigned long)(*bufp-bufstart), bc, 1, d))
    952                 return 1;
    953             *bufp += 1;
    954             break;
    955         case JMP_NEAR_FORCED:
    956         case JMP_NEAR:
    957             /* 2/4 byte relative displacement (depending on operand size) */
    958             if (jmp->nearop.len == 0) {
    959                 yasm_error_set(YASM_ERROR_TYPE,
    960                                N_("near jump does not exist"));
    961                 return 1;
    962             }
    963 
    964             /* Opcode */
    965             x86_opcode_tobytes(&jmp->nearop, bufp);
    966 
    967             i = (opersize == 16) ? 2 : 4;
    968 
    969             /* Adjust relative displacement to end of bytecode */
    970             delta = yasm_intnum_create_int(-(long)bc->len);
    971             if (!jmp->target.abs)
    972                 jmp->target.abs = yasm_expr_create_ident(yasm_expr_int(delta),
    973                                                          bc->line);
    974             else
    975                 jmp->target.abs =
    976                     yasm_expr_create(YASM_EXPR_ADD,
    977                                      yasm_expr_expr(jmp->target.abs),
    978                                      yasm_expr_int(delta), bc->line);
    979 
    980             jmp->target.size = i*8;
    981             jmp->target.sign = 1;
    982             if (output_value(&jmp->target, *bufp, i,
    983                              (unsigned long)(*bufp-bufstart), bc, 1, d))
    984                 return 1;
    985             *bufp += i;
    986             break;
    987         case JMP_NONE:
    988             yasm_internal_error(N_("jump op_sel cannot be JMP_NONE in tobytes"));
    989         default:
    990             yasm_internal_error(N_("unrecognized relative jump op_sel"));
    991     }
    992     return 0;
    993 }
    994 
    995 static int
    996 x86_bc_jmpfar_tobytes(yasm_bytecode *bc, unsigned char **bufp,
    997                       unsigned char *bufstart, void *d,
    998                       yasm_output_value_func output_value,
    999                       /*@unused@*/ yasm_output_reloc_func output_reloc)
   1000 {
   1001     x86_jmpfar *jmpfar = (x86_jmpfar *)bc->contents;
   1002     unsigned int i;
   1003     unsigned char opersize;
   1004 
   1005     x86_common_tobytes(&jmpfar->common, bufp, 0);
   1006     x86_opcode_tobytes(&jmpfar->opcode, bufp);
   1007 
   1008     /* As opersize may be 0, figure out its "real" value. */
   1009     opersize = (jmpfar->common.opersize == 0) ?
   1010         jmpfar->common.mode_bits : jmpfar->common.opersize;
   1011 
   1012     /* Absolute displacement: segment and offset */
   1013     i = (opersize == 16) ? 2 : 4;
   1014     jmpfar->offset.size = i*8;
   1015     if (output_value(&jmpfar->offset, *bufp, i,
   1016                      (unsigned long)(*bufp-bufstart), bc, 1, d))
   1017         return 1;
   1018     *bufp += i;
   1019     jmpfar->segment.size = 16;
   1020     if (output_value(&jmpfar->segment, *bufp, 2,
   1021                      (unsigned long)(*bufp-bufstart), bc, 1, d))
   1022         return 1;
   1023     *bufp += 2;
   1024 
   1025     return 0;
   1026 }
   1027 
   1028 int
   1029 yasm_x86__intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn,
   1030                          unsigned char *buf, size_t destsize, size_t valsize,
   1031                          int shift, const yasm_bytecode *bc, int warn)
   1032 {
   1033     /* Write value out. */
   1034     yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn);
   1035     return 0;
   1036 }
   1037