16 #include "libfkvm-common.h"
19 kvm_reg_from_x86_reg(int x86_reg_id
)
21 static const int const map
[] = {
118 if (x86_reg_id
<= 0 || x86_reg_id
>= ARRAY_SIZE(map
))
120 return map
[x86_reg_id
];
124 cr_num_from_x86_reg(int x86_reg_id
)
135 cr_num
= x86_reg_id
- 49;
136 if (cr_num
>= 0 && cr_num
<= 7)
143 kvm_seg_from_x86_op(struct kvm_sregs
*sregs
, x86_op_t
*op
)
145 switch (op
->flags
& 0xF00) {
146 case op_es_seg
: return &sregs
->es
;
147 case op_cs_seg
: return &sregs
->cs
;
148 case op_ss_seg
: return &sregs
->ss
;
149 case op_ds_seg
: return &sregs
->ds
;
150 case op_fs_seg
: return &sregs
->fs
;
151 case op_gs_seg
: return &sregs
->gs
;
160 get_source_data(struct kvm_regs
*regs
, x86_op_t
*op
)
164 if (op
->type
== op_register
) {
165 source
= kvm_regs_get(regs
,
166 kvm_reg_from_x86_reg(op
->data
.reg
.id
));
168 else if (op
->type
== op_immediate
) {
169 source
= op
->data
.qword
;
175 //printf("source = %" PRIx64 "\n", source);
177 source
= mask_reg(source
, x86_operand_size(op
));
182 get_memi_address(struct kvm_regs
*regs
, struct kvm_sregs
*sregs
,
183 x86_op_t
*op
, size_t size
)
185 struct kvm_segment
*segment
;
186 uint64_t address
= 0;
188 if (op
->type
== op_expression
) {
192 ea
= &op
->data
.expression
;
194 if (ea
->base
.id
!= 0) {
195 reg_idx
= kvm_reg_from_x86_reg(ea
->base
.id
);
196 address
+= kvm_regs_get(regs
, reg_idx
);
199 if (ea
->index
.id
!= 0) {
200 reg_idx
= kvm_reg_from_x86_reg(ea
->index
.id
);
201 address
+= ea
->scale
* kvm_regs_get(regs
, reg_idx
);
204 if (ea
->disp_size
!= 0 && ea
->disp
!= 0) {
205 address
+= ea
->disp
; /* TODO: disp_sign ? */
208 else if (op
->type
== op_offset
) {
209 address
= op
->data
.offset
;
215 //printf("address = %" PRIx64 "\n", address);
216 address
= mask_reg(address
, size
);
218 switch (op
->flags
& ~0xFF) {
220 segment
= &sregs
->cs
;
223 segment
= &sregs
->ds
;
226 segment
= &sregs
->es
;
229 segment
= &sregs
->fs
;
232 segment
= &sregs
->gs
;
235 segment
= &sregs
->ss
;
242 /* if (reg_value > segment->limit) */
244 //printf("segment base: %" PRIx64 "\n", segment->base);
245 return segment
->base
+ address
;
249 get_x86_insn(const uint64_t insn_addr
, x86_insn_t
*insn
)
251 uint8_t buf
[MAX_INSN_SIZE
];
252 unsigned int insn_size
;
254 cpu_virtual_memory_rw(insn_addr
, buf
, MAX_INSN_SIZE
, 0);
259 printf("buf @ 0x%" PRIx64
":", insn_addr
);
260 for (i
= 0; i
< MAX_INSN_SIZE
; i
++)
261 printf(" %02x", buf
[i
]);
267 insn_size
= x86_disasm(buf
, MAX_INSN_SIZE
, 0, 0, insn
);
274 x86_format_insn(insn
, line
, 80, intel_syntax
);
275 printf("%s\n", line
);
283 libdisasm_init(size_t reg_size
)
286 x86_init(opt_16_bit
, NULL
, NULL
);
288 else if (reg_size
== 4) {
289 x86_init(opt_none
, NULL
, NULL
);