Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libnvmm In !64bit mode RIP-relative is null+disp32, hand...
details: https://anonhg.NetBSD.org/src/rev/e3bfabb53d5c
branches: trunk
changeset: 447208:e3bfabb53d5c
user: maxv <maxv%NetBSD.org@localhost>
date: Fri Jan 04 10:25:39 2019 +0000
description:
In !64bit mode RIP-relative is null+disp32, handle that correctly.
diffstat:
lib/libnvmm/libnvmm_x86.c | 30 +++++++++++++++++++++++++-----
1 files changed, 25 insertions(+), 5 deletions(-)
diffs (66 lines):
diff -r 26d583eefc56 -r e3bfabb53d5c lib/libnvmm/libnvmm_x86.c
--- a/lib/libnvmm/libnvmm_x86.c Fri Jan 04 05:35:24 2019 +0000
+++ b/lib/libnvmm/libnvmm_x86.c Fri Jan 04 10:25:39 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: libnvmm_x86.c,v 1.8 2019/01/02 12:18:08 maxv Exp $ */
+/* $NetBSD: libnvmm_x86.c,v 1.9 2019/01/04 10:25:39 maxv Exp $ */
/*
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -1826,9 +1826,16 @@
}
static inline bool
-is_rip_relative(struct x86_instr *instr)
+is_rip_relative(struct x86_decode_fsm *fsm, struct x86_instr *instr)
{
- return (instr->strm->disp.type == DISP_0 &&
+ return (fsm->is64bit && instr->strm->disp.type == DISP_0 &&
+ instr->regmodrm.rm == RM_RBP_DISP32);
+}
+
+static inline bool
+is_disp32_only(struct x86_decode_fsm *fsm, struct x86_instr *instr)
+{
+ return (!fsm->is64bit && instr->strm->disp.type == DISP_0 &&
instr->regmodrm.rm == RM_RBP_DISP32);
}
@@ -1905,7 +1912,7 @@
/* The displacement applies to RM. */
strm->disp.type = get_disp_type(instr);
- if (is_rip_relative(instr)) {
+ if (is_rip_relative(fsm, instr)) {
/* Overwrites RM */
strm->type = STORE_REG;
strm->u.reg = &gpr_map__rip;
@@ -1914,6 +1921,15 @@
return 0;
}
+ if (is_disp32_only(fsm, instr)) {
+ /* Overwrites RM */
+ strm->type = STORE_REG;
+ strm->u.reg = NULL;
+ strm->disp.type = DISP_4;
+ fsm_advance(fsm, 1, node_disp);
+ return 0;
+ }
+
reg = get_register_rm(instr, opcode);
if (reg == NULL) {
return -1;
@@ -2405,7 +2421,11 @@
gva += sib->scale * reg;
}
} else if (store->type == STORE_REG) {
- gva = gpr_read_address(instr, state, store->u.reg->num);
+ if (store->u.reg == NULL) {
+ /* The base is null. Happens with disp32-only. */
+ } else {
+ gva = gpr_read_address(instr, state, store->u.reg->num);
+ }
} else {
gva = store->u.dmo;
}
Home |
Main Index |
Thread Index |
Old Index