| OLD | NEW |
| 1 /* | 1 /* |
| 2 * x86 bytecode utility functions | 2 * x86 bytecode utility functions |
| 3 * | 3 * |
| 4 * Copyright (C) 2001-2007 Peter Johnson | 4 * Copyright (C) 2001-2007 Peter Johnson |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
| 8 * are met: | 8 * are met: |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| 11 * 2. Redistributions in binary form must reproduce the above copyright | 11 * 2. Redistributions in binary form must reproduce the above copyright |
| 12 * notice, this list of conditions and the following disclaimer in the | 12 * notice, this list of conditions and the following disclaimer in the |
| 13 * documentation and/or other materials provided with the distribution. | 13 * documentation and/or other materials provided with the distribution. |
| 14 * | 14 * |
| 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' | 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 | 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE | 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE |
| 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 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 | 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 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 | 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 25 * POSSIBILITY OF SUCH DAMAGE. | 25 * POSSIBILITY OF SUCH DAMAGE. |
| 26 */ | 26 */ |
| 27 #include <util.h> | 27 #include <util.h> |
| 28 /*@unused@*/ RCSID("$Id: x86bc.c 2279 2010-01-19 07:57:43Z peter $"); | |
| 29 | 28 |
| 30 #include <libyasm.h> | 29 #include <libyasm.h> |
| 31 | 30 |
| 32 #include "x86arch.h" | 31 #include "x86arch.h" |
| 33 | 32 |
| 34 | 33 |
| 35 /* Bytecode callback function prototypes */ | 34 /* Bytecode callback function prototypes */ |
| 36 | 35 |
| 37 static void x86_bc_insn_destroy(void *contents); | 36 static void x86_bc_insn_destroy(void *contents); |
| 38 static void x86_bc_insn_print(const void *contents, FILE *f, | 37 static void x86_bc_insn_print(const void *contents, FILE *f, |
| 39 int indent_level); | 38 int indent_level); |
| 40 static int x86_bc_insn_calc_len(yasm_bytecode *bc, | 39 static int x86_bc_insn_calc_len(yasm_bytecode *bc, |
| 41 yasm_bc_add_span_func add_span, | 40 yasm_bc_add_span_func add_span, |
| 42 void *add_span_data); | 41 void *add_span_data); |
| 43 static int x86_bc_insn_expand(yasm_bytecode *bc, int span, long old_val, | 42 static int x86_bc_insn_expand(yasm_bytecode *bc, int span, long old_val, |
| 44 long new_val, /*@out@*/ long *neg_thres, | 43 long new_val, /*@out@*/ long *neg_thres, |
| 45 /*@out@*/ long *pos_thres); | 44 /*@out@*/ long *pos_thres); |
| 46 static int x86_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, | 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, | 47 void *d, yasm_output_value_func output_value, |
| 48 /*@null@*/ yasm_output_reloc_func output_reloc); | 48 /*@null@*/ yasm_output_reloc_func output_reloc); |
| 49 | 49 |
| 50 static void x86_bc_jmp_destroy(void *contents); | 50 static void x86_bc_jmp_destroy(void *contents); |
| 51 static void x86_bc_jmp_print(const void *contents, FILE *f, int indent_level); | 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, | 52 static int x86_bc_jmp_calc_len(yasm_bytecode *bc, |
| 53 yasm_bc_add_span_func add_span, | 53 yasm_bc_add_span_func add_span, |
| 54 void *add_span_data); | 54 void *add_span_data); |
| 55 static int x86_bc_jmp_expand(yasm_bytecode *bc, int span, long old_val, | 55 static int x86_bc_jmp_expand(yasm_bytecode *bc, int span, long old_val, |
| 56 long new_val, /*@out@*/ long *neg_thres, | 56 long new_val, /*@out@*/ long *neg_thres, |
| 57 /*@out@*/ long *pos_thres); | 57 /*@out@*/ long *pos_thres); |
| 58 static int x86_bc_jmp_tobytes(yasm_bytecode *bc, unsigned char **bufp, | 58 static int x86_bc_jmp_tobytes(yasm_bytecode *bc, unsigned char **bufp, |
| 59 unsigned char *bufstart, |
| 59 void *d, yasm_output_value_func output_value, | 60 void *d, yasm_output_value_func output_value, |
| 60 /*@null@*/ yasm_output_reloc_func output_reloc); | 61 /*@null@*/ yasm_output_reloc_func output_reloc); |
| 61 | 62 |
| 62 static void x86_bc_jmpfar_destroy(void *contents); | 63 static void x86_bc_jmpfar_destroy(void *contents); |
| 63 static void x86_bc_jmpfar_print(const void *contents, FILE *f, | 64 static void x86_bc_jmpfar_print(const void *contents, FILE *f, |
| 64 int indent_level); | 65 int indent_level); |
| 65 static int x86_bc_jmpfar_calc_len(yasm_bytecode *bc, | 66 static int x86_bc_jmpfar_calc_len(yasm_bytecode *bc, |
| 66 yasm_bc_add_span_func add_span, | 67 yasm_bc_add_span_func add_span, |
| 67 void *add_span_data); | 68 void *add_span_data); |
| 68 static int x86_bc_jmpfar_tobytes | 69 static int x86_bc_jmpfar_tobytes |
| 69 (yasm_bytecode *bc, unsigned char **bufp, void *d, | 70 (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d, |
| 70 yasm_output_value_func output_value, | 71 yasm_output_value_func output_value, |
| 71 /*@null@*/ yasm_output_reloc_func output_reloc); | 72 /*@null@*/ yasm_output_reloc_func output_reloc); |
| 72 | 73 |
| 73 /* Bytecode callback structures */ | 74 /* Bytecode callback structures */ |
| 74 | 75 |
| 75 static const yasm_bytecode_callback x86_bc_callback_insn = { | 76 static const yasm_bytecode_callback x86_bc_callback_insn = { |
| 76 x86_bc_insn_destroy, | 77 x86_bc_insn_destroy, |
| 77 x86_bc_insn_print, | 78 x86_bc_insn_print, |
| 78 yasm_bc_finalize_common, | 79 yasm_bc_finalize_common, |
| 79 NULL, | 80 NULL, |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 | 183 |
| 183 yasm_value_initialize(&x86_ea->ea.disp, NULL, 0); | 184 yasm_value_initialize(&x86_ea->ea.disp, NULL, 0); |
| 184 x86_ea->ea.need_nonzero_len = 0; | 185 x86_ea->ea.need_nonzero_len = 0; |
| 185 x86_ea->ea.need_disp = 0; | 186 x86_ea->ea.need_disp = 0; |
| 186 x86_ea->ea.nosplit = 0; | 187 x86_ea->ea.nosplit = 0; |
| 187 x86_ea->ea.strong = 0; | 188 x86_ea->ea.strong = 0; |
| 188 x86_ea->ea.segreg = 0; | 189 x86_ea->ea.segreg = 0; |
| 189 x86_ea->ea.pc_rel = 0; | 190 x86_ea->ea.pc_rel = 0; |
| 190 x86_ea->ea.not_pc_rel = 0; | 191 x86_ea->ea.not_pc_rel = 0; |
| 191 x86_ea->ea.data_len = 0; | 192 x86_ea->ea.data_len = 0; |
| 193 x86_ea->vsib_mode = 0; |
| 192 x86_ea->modrm = 0; | 194 x86_ea->modrm = 0; |
| 193 x86_ea->valid_modrm = 0; | 195 x86_ea->valid_modrm = 0; |
| 194 x86_ea->need_modrm = 0; | 196 x86_ea->need_modrm = 0; |
| 195 x86_ea->sib = 0; | 197 x86_ea->sib = 0; |
| 196 x86_ea->valid_sib = 0; | 198 x86_ea->valid_sib = 0; |
| 197 x86_ea->need_sib = 0; | 199 x86_ea->need_sib = 0; |
| 198 | 200 |
| 199 return x86_ea; | 201 return x86_ea; |
| 200 } | 202 } |
| 201 | 203 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 | 375 |
| 374 void | 376 void |
| 375 yasm_x86__ea_print(const yasm_effaddr *ea, FILE *f, int indent_level) | 377 yasm_x86__ea_print(const yasm_effaddr *ea, FILE *f, int indent_level) |
| 376 { | 378 { |
| 377 const x86_effaddr *x86_ea = (const x86_effaddr *)ea; | 379 const x86_effaddr *x86_ea = (const x86_effaddr *)ea; |
| 378 fprintf(f, "%*sDisp:\n", indent_level, ""); | 380 fprintf(f, "%*sDisp:\n", indent_level, ""); |
| 379 yasm_value_print(&ea->disp, f, indent_level+1); | 381 yasm_value_print(&ea->disp, f, indent_level+1); |
| 380 fprintf(f, "%*sNoSplit=%u\n", indent_level, "", (unsigned int)ea->nosplit); | 382 fprintf(f, "%*sNoSplit=%u\n", indent_level, "", (unsigned int)ea->nosplit); |
| 381 fprintf(f, "%*sSegmentOv=%02x\n", indent_level, "", | 383 fprintf(f, "%*sSegmentOv=%02x\n", indent_level, "", |
| 382 (unsigned int)x86_ea->ea.segreg); | 384 (unsigned int)x86_ea->ea.segreg); |
| 385 fprintf(f, "%*sVSIBMode=%u\n", indent_level, "", |
| 386 (unsigned int)x86_ea->vsib_mode); |
| 383 fprintf(f, "%*sModRM=%03o ValidRM=%u NeedRM=%u\n", indent_level, "", | 387 fprintf(f, "%*sModRM=%03o ValidRM=%u NeedRM=%u\n", indent_level, "", |
| 384 (unsigned int)x86_ea->modrm, (unsigned int)x86_ea->valid_modrm, | 388 (unsigned int)x86_ea->modrm, (unsigned int)x86_ea->valid_modrm, |
| 385 (unsigned int)x86_ea->need_modrm); | 389 (unsigned int)x86_ea->need_modrm); |
| 386 fprintf(f, "%*sSIB=%03o ValidSIB=%u NeedSIB=%u\n", indent_level, "", | 390 fprintf(f, "%*sSIB=%03o ValidSIB=%u NeedSIB=%u\n", indent_level, "", |
| 387 (unsigned int)x86_ea->sib, (unsigned int)x86_ea->valid_sib, | 391 (unsigned int)x86_ea->sib, (unsigned int)x86_ea->valid_sib, |
| 388 (unsigned int)x86_ea->need_sib); | 392 (unsigned int)x86_ea->need_sib); |
| 389 } | 393 } |
| 390 | 394 |
| 391 static void | 395 static void |
| 392 x86_common_print(const x86_common *common, FILE *f, int indent_level) | 396 x86_common_print(const x86_common *common, FILE *f, int indent_level) |
| (...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 793 | 797 |
| 794 static void | 798 static void |
| 795 x86_opcode_tobytes(const x86_opcode *opcode, unsigned char **bufp) | 799 x86_opcode_tobytes(const x86_opcode *opcode, unsigned char **bufp) |
| 796 { | 800 { |
| 797 unsigned int i; | 801 unsigned int i; |
| 798 for (i=0; i<opcode->len; i++) | 802 for (i=0; i<opcode->len; i++) |
| 799 YASM_WRITE_8(*bufp, opcode->opcode[i]); | 803 YASM_WRITE_8(*bufp, opcode->opcode[i]); |
| 800 } | 804 } |
| 801 | 805 |
| 802 static int | 806 static int |
| 803 x86_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d, | 807 x86_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, |
| 808 unsigned char *bufstart, void *d, |
| 804 yasm_output_value_func output_value, | 809 yasm_output_value_func output_value, |
| 805 /*@unused@*/ yasm_output_reloc_func output_reloc) | 810 /*@unused@*/ yasm_output_reloc_func output_reloc) |
| 806 { | 811 { |
| 807 x86_insn *insn = (x86_insn *)bc->contents; | 812 x86_insn *insn = (x86_insn *)bc->contents; |
| 808 /*@null@*/ x86_effaddr *x86_ea = (x86_effaddr *)insn->x86_ea; | 813 /*@null@*/ x86_effaddr *x86_ea = (x86_effaddr *)insn->x86_ea; |
| 809 yasm_value *imm = insn->imm; | 814 yasm_value *imm = insn->imm; |
| 810 unsigned char *bufp_orig = *bufp; | |
| 811 | 815 |
| 812 /* Prefixes */ | 816 /* Prefixes */ |
| 813 x86_common_tobytes(&insn->common, bufp, | 817 x86_common_tobytes(&insn->common, bufp, |
| 814 x86_ea ? (unsigned int)(x86_ea->ea.segreg>>8) : 0); | 818 x86_ea ? (unsigned int)(x86_ea->ea.segreg>>8) : 0); |
| 815 if (insn->special_prefix != 0) | 819 if (insn->special_prefix != 0) |
| 816 YASM_WRITE_8(*bufp, insn->special_prefix); | 820 YASM_WRITE_8(*bufp, insn->special_prefix); |
| 817 if (insn->special_prefix == 0xC4 || insn->special_prefix == 0x8F) { | 821 if (insn->special_prefix == 0xC4 || insn->special_prefix == 0x8F) { |
| 818 /* 3-byte VEX/XOP; merge in 1s complement of REX.R, REX.X, REX.B */ | 822 /* 3-byte VEX/XOP; merge in 1s complement of REX.R, REX.X, REX.B */ |
| 819 insn->opcode.opcode[0] &= 0x1F; | 823 insn->opcode.opcode[0] &= 0x1F; |
| 820 if (insn->rex != 0xff) | 824 if (insn->rex != 0xff) |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 867 if (!x86_ea->ea.disp.abs) | 871 if (!x86_ea->ea.disp.abs) |
| 868 x86_ea->ea.disp.abs = | 872 x86_ea->ea.disp.abs = |
| 869 yasm_expr_create_ident(yasm_expr_int(delta), bc->line); | 873 yasm_expr_create_ident(yasm_expr_int(delta), bc->line); |
| 870 else | 874 else |
| 871 x86_ea->ea.disp.abs = | 875 x86_ea->ea.disp.abs = |
| 872 yasm_expr_create(YASM_EXPR_ADD, | 876 yasm_expr_create(YASM_EXPR_ADD, |
| 873 yasm_expr_expr(x86_ea->ea.disp.abs), | 877 yasm_expr_expr(x86_ea->ea.disp.abs), |
| 874 yasm_expr_int(delta), bc->line); | 878 yasm_expr_int(delta), bc->line); |
| 875 } | 879 } |
| 876 if (output_value(&x86_ea->ea.disp, *bufp, disp_len, | 880 if (output_value(&x86_ea->ea.disp, *bufp, disp_len, |
| 877 (unsigned long)(*bufp-bufp_orig), bc, 1, d)) | 881 (unsigned long)(*bufp-bufstart), bc, 1, d)) |
| 878 return 1; | 882 return 1; |
| 879 *bufp += disp_len; | 883 *bufp += disp_len; |
| 880 } | 884 } |
| 881 } | 885 } |
| 882 | 886 |
| 883 /* Immediate (if required) */ | 887 /* Immediate (if required) */ |
| 884 if (imm) { | 888 if (imm) { |
| 885 unsigned int imm_len; | 889 unsigned int imm_len; |
| 886 if (insn->postop == X86_POSTOP_SIGNEXT_IMM8) { | 890 if (insn->postop == X86_POSTOP_SIGNEXT_IMM8) { |
| 887 /* If we got here with this postop still set, we need to force | 891 /* If we got here with this postop still set, we need to force |
| 888 * imm size to 8 here. | 892 * imm size to 8 here. |
| 889 */ | 893 */ |
| 890 imm->size = 8; | 894 imm->size = 8; |
| 891 imm->sign = 1; | 895 imm->sign = 1; |
| 892 imm_len = 1; | 896 imm_len = 1; |
| 893 } else | 897 } else |
| 894 imm_len = imm->size/8; | 898 imm_len = imm->size/8; |
| 895 if (output_value(imm, *bufp, imm_len, (unsigned long)(*bufp-bufp_orig), | 899 if (output_value(imm, *bufp, imm_len, (unsigned long)(*bufp-bufstart), |
| 896 bc, 1, d)) | 900 bc, 1, d)) |
| 897 return 1; | 901 return 1; |
| 898 *bufp += imm_len; | 902 *bufp += imm_len; |
| 899 } | 903 } |
| 900 | 904 |
| 901 return 0; | 905 return 0; |
| 902 } | 906 } |
| 903 | 907 |
| 904 static int | 908 static int |
| 905 x86_bc_jmp_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d, | 909 x86_bc_jmp_tobytes(yasm_bytecode *bc, unsigned char **bufp, |
| 910 unsigned char *bufstart, void *d, |
| 906 yasm_output_value_func output_value, | 911 yasm_output_value_func output_value, |
| 907 /*@unused@*/ yasm_output_reloc_func output_reloc) | 912 /*@unused@*/ yasm_output_reloc_func output_reloc) |
| 908 { | 913 { |
| 909 x86_jmp *jmp = (x86_jmp *)bc->contents; | 914 x86_jmp *jmp = (x86_jmp *)bc->contents; |
| 910 unsigned char opersize; | 915 unsigned char opersize; |
| 911 unsigned int i; | 916 unsigned int i; |
| 912 unsigned char *bufp_orig = *bufp; | |
| 913 /*@only@*/ yasm_intnum *delta; | 917 /*@only@*/ yasm_intnum *delta; |
| 914 | 918 |
| 915 /* Prefixes */ | 919 /* Prefixes */ |
| 916 x86_common_tobytes(&jmp->common, bufp, 0); | 920 x86_common_tobytes(&jmp->common, bufp, 0); |
| 917 | 921 |
| 918 /* As opersize may be 0, figure out its "real" value. */ | 922 /* As opersize may be 0, figure out its "real" value. */ |
| 919 opersize = (jmp->common.opersize == 0) ? | 923 opersize = (jmp->common.opersize == 0) ? |
| 920 jmp->common.mode_bits : jmp->common.opersize; | 924 jmp->common.mode_bits : jmp->common.opersize; |
| 921 | 925 |
| 922 /* Check here again to see if forms are actually legal. */ | 926 /* Check here again to see if forms are actually legal. */ |
| (...skipping 14 matching lines...) Expand all Loading... |
| 937 bc->line); | 941 bc->line); |
| 938 else | 942 else |
| 939 jmp->target.abs = | 943 jmp->target.abs = |
| 940 yasm_expr_create(YASM_EXPR_ADD, | 944 yasm_expr_create(YASM_EXPR_ADD, |
| 941 yasm_expr_expr(jmp->target.abs), | 945 yasm_expr_expr(jmp->target.abs), |
| 942 yasm_expr_int(delta), bc->line); | 946 yasm_expr_int(delta), bc->line); |
| 943 | 947 |
| 944 jmp->target.size = 8; | 948 jmp->target.size = 8; |
| 945 jmp->target.sign = 1; | 949 jmp->target.sign = 1; |
| 946 if (output_value(&jmp->target, *bufp, 1, | 950 if (output_value(&jmp->target, *bufp, 1, |
| 947 (unsigned long)(*bufp-bufp_orig), bc, 1, d)) | 951 (unsigned long)(*bufp-bufstart), bc, 1, d)) |
| 948 return 1; | 952 return 1; |
| 949 *bufp += 1; | 953 *bufp += 1; |
| 950 break; | 954 break; |
| 951 case JMP_NEAR_FORCED: | 955 case JMP_NEAR_FORCED: |
| 952 case JMP_NEAR: | 956 case JMP_NEAR: |
| 953 /* 2/4 byte relative displacement (depending on operand size) */ | 957 /* 2/4 byte relative displacement (depending on operand size) */ |
| 954 if (jmp->nearop.len == 0) { | 958 if (jmp->nearop.len == 0) { |
| 955 yasm_error_set(YASM_ERROR_TYPE, | 959 yasm_error_set(YASM_ERROR_TYPE, |
| 956 N_("near jump does not exist")); | 960 N_("near jump does not exist")); |
| 957 return 1; | 961 return 1; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 969 bc->line); | 973 bc->line); |
| 970 else | 974 else |
| 971 jmp->target.abs = | 975 jmp->target.abs = |
| 972 yasm_expr_create(YASM_EXPR_ADD, | 976 yasm_expr_create(YASM_EXPR_ADD, |
| 973 yasm_expr_expr(jmp->target.abs), | 977 yasm_expr_expr(jmp->target.abs), |
| 974 yasm_expr_int(delta), bc->line); | 978 yasm_expr_int(delta), bc->line); |
| 975 | 979 |
| 976 jmp->target.size = i*8; | 980 jmp->target.size = i*8; |
| 977 jmp->target.sign = 1; | 981 jmp->target.sign = 1; |
| 978 if (output_value(&jmp->target, *bufp, i, | 982 if (output_value(&jmp->target, *bufp, i, |
| 979 (unsigned long)(*bufp-bufp_orig), bc, 1, d)) | 983 (unsigned long)(*bufp-bufstart), bc, 1, d)) |
| 980 return 1; | 984 return 1; |
| 981 *bufp += i; | 985 *bufp += i; |
| 982 break; | 986 break; |
| 983 case JMP_NONE: | 987 case JMP_NONE: |
| 984 yasm_internal_error(N_("jump op_sel cannot be JMP_NONE in tobytes"))
; | 988 yasm_internal_error(N_("jump op_sel cannot be JMP_NONE in tobytes"))
; |
| 985 default: | 989 default: |
| 986 yasm_internal_error(N_("unrecognized relative jump op_sel")); | 990 yasm_internal_error(N_("unrecognized relative jump op_sel")); |
| 987 } | 991 } |
| 988 return 0; | 992 return 0; |
| 989 } | 993 } |
| 990 | 994 |
| 991 static int | 995 static int |
| 992 x86_bc_jmpfar_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d, | 996 x86_bc_jmpfar_tobytes(yasm_bytecode *bc, unsigned char **bufp, |
| 997 unsigned char *bufstart, void *d, |
| 993 yasm_output_value_func output_value, | 998 yasm_output_value_func output_value, |
| 994 /*@unused@*/ yasm_output_reloc_func output_reloc) | 999 /*@unused@*/ yasm_output_reloc_func output_reloc) |
| 995 { | 1000 { |
| 996 x86_jmpfar *jmpfar = (x86_jmpfar *)bc->contents; | 1001 x86_jmpfar *jmpfar = (x86_jmpfar *)bc->contents; |
| 997 unsigned int i; | 1002 unsigned int i; |
| 998 unsigned char *bufp_orig = *bufp; | |
| 999 unsigned char opersize; | 1003 unsigned char opersize; |
| 1000 | 1004 |
| 1001 x86_common_tobytes(&jmpfar->common, bufp, 0); | 1005 x86_common_tobytes(&jmpfar->common, bufp, 0); |
| 1002 x86_opcode_tobytes(&jmpfar->opcode, bufp); | 1006 x86_opcode_tobytes(&jmpfar->opcode, bufp); |
| 1003 | 1007 |
| 1004 /* As opersize may be 0, figure out its "real" value. */ | 1008 /* As opersize may be 0, figure out its "real" value. */ |
| 1005 opersize = (jmpfar->common.opersize == 0) ? | 1009 opersize = (jmpfar->common.opersize == 0) ? |
| 1006 jmpfar->common.mode_bits : jmpfar->common.opersize; | 1010 jmpfar->common.mode_bits : jmpfar->common.opersize; |
| 1007 | 1011 |
| 1008 /* Absolute displacement: segment and offset */ | 1012 /* Absolute displacement: segment and offset */ |
| 1009 i = (opersize == 16) ? 2 : 4; | 1013 i = (opersize == 16) ? 2 : 4; |
| 1010 jmpfar->offset.size = i*8; | 1014 jmpfar->offset.size = i*8; |
| 1011 if (output_value(&jmpfar->offset, *bufp, i, | 1015 if (output_value(&jmpfar->offset, *bufp, i, |
| 1012 (unsigned long)(*bufp-bufp_orig), bc, 1, d)) | 1016 (unsigned long)(*bufp-bufstart), bc, 1, d)) |
| 1013 return 1; | 1017 return 1; |
| 1014 *bufp += i; | 1018 *bufp += i; |
| 1015 jmpfar->segment.size = 16; | 1019 jmpfar->segment.size = 16; |
| 1016 if (output_value(&jmpfar->segment, *bufp, 2, | 1020 if (output_value(&jmpfar->segment, *bufp, 2, |
| 1017 (unsigned long)(*bufp-bufp_orig), bc, 1, d)) | 1021 (unsigned long)(*bufp-bufstart), bc, 1, d)) |
| 1018 return 1; | 1022 return 1; |
| 1019 *bufp += 2; | 1023 *bufp += 2; |
| 1020 | 1024 |
| 1021 return 0; | 1025 return 0; |
| 1022 } | 1026 } |
| 1023 | 1027 |
| 1024 int | 1028 int |
| 1025 yasm_x86__intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn, | 1029 yasm_x86__intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn, |
| 1026 unsigned char *buf, size_t destsize, size_t valsize, | 1030 unsigned char *buf, size_t destsize, size_t valsize, |
| 1027 int shift, const yasm_bytecode *bc, int warn) | 1031 int shift, const yasm_bytecode *bc, int warn) |
| 1028 { | 1032 { |
| 1029 /* Write value out. */ | 1033 /* Write value out. */ |
| 1030 yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn); | 1034 yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn); |
| 1031 return 0; | 1035 return 0; |
| 1032 } | 1036 } |
| OLD | NEW |