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 |