From 3e5a009f20a556cd4faccb45c9f55ebdb17a8424 Mon Sep 17 00:00:00 2001 From: bellard Date: Sun, 17 Apr 2005 19:50:21 +0000 Subject: [PATCH] make lsl, lar verr and verw exception safe --- target-i386/helper.c | 78 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 33 deletions(-) diff --git a/target-i386/helper.c b/target-i386/helper.c index b358c2ecfe..2c852090aa 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -2335,13 +2335,13 @@ void helper_rdmsr(void) void helper_lsl(void) { unsigned int selector, limit; - uint32_t e1, e2; + uint32_t e1, e2, eflags; int rpl, dpl, cpl, type; - CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z; + eflags = cc_table[CC_OP].compute_all(); selector = T0 & 0xffff; if (load_segment(&e1, &e2, selector) != 0) - return; + goto fail; rpl = selector & 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3; cpl = env->hflags & HF_CPL_MASK; @@ -2350,7 +2350,7 @@ void helper_lsl(void) /* conforming */ } else { if (dpl < cpl || dpl < rpl) - return; + goto fail; } } else { type = (e2 >> DESC_TYPE_SHIFT) & 0xf; @@ -2362,28 +2362,31 @@ void helper_lsl(void) case 11: break; default: - return; + goto fail; } - if (dpl < cpl || dpl < rpl) + if (dpl < cpl || dpl < rpl) { + fail: + CC_SRC = eflags & ~CC_Z; return; + } } limit = get_seg_limit(e1, e2); T1 = limit; - CC_SRC |= CC_Z; + CC_SRC = eflags | CC_Z; } void helper_lar(void) { unsigned int selector; - uint32_t e1, e2; + uint32_t e1, e2, eflags; int rpl, dpl, cpl, type; - CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z; + eflags = cc_table[CC_OP].compute_all(); selector = T0 & 0xffff; if ((selector & 0xfffc) == 0) - return; + goto fail; if (load_segment(&e1, &e2, selector) != 0) - return; + goto fail; rpl = selector & 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3; cpl = env->hflags & HF_CPL_MASK; @@ -2392,7 +2395,7 @@ void helper_lar(void) /* conforming */ } else { if (dpl < cpl || dpl < rpl) - return; + goto fail; } } else { type = (e2 >> DESC_TYPE_SHIFT) & 0xf; @@ -2407,72 +2410,81 @@ void helper_lar(void) case 12: break; default: - return; + goto fail; } - if (dpl < cpl || dpl < rpl) + if (dpl < cpl || dpl < rpl) { + fail: + CC_SRC = eflags & ~CC_Z; return; + } } T1 = e2 & 0x00f0ff00; - CC_SRC |= CC_Z; + CC_SRC = eflags | CC_Z; } void helper_verr(void) { unsigned int selector; - uint32_t e1, e2; + uint32_t e1, e2, eflags; int rpl, dpl, cpl; - CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z; + eflags = cc_table[CC_OP].compute_all(); selector = T0 & 0xffff; if ((selector & 0xfffc) == 0) - return; + goto fail; if (load_segment(&e1, &e2, selector) != 0) - return; + goto fail; if (!(e2 & DESC_S_MASK)) - return; + goto fail; rpl = selector & 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3; cpl = env->hflags & HF_CPL_MASK; if (e2 & DESC_CS_MASK) { if (!(e2 & DESC_R_MASK)) - return; + goto fail; if (!(e2 & DESC_C_MASK)) { if (dpl < cpl || dpl < rpl) - return; + goto fail; } } else { - if (dpl < cpl || dpl < rpl) + if (dpl < cpl || dpl < rpl) { + fail: + CC_SRC = eflags & ~CC_Z; return; + } } - CC_SRC |= CC_Z; + CC_SRC = eflags | CC_Z; } void helper_verw(void) { unsigned int selector; - uint32_t e1, e2; + uint32_t e1, e2, eflags; int rpl, dpl, cpl; - CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z; + eflags = cc_table[CC_OP].compute_all(); selector = T0 & 0xffff; if ((selector & 0xfffc) == 0) - return; + goto fail; if (load_segment(&e1, &e2, selector) != 0) - return; + goto fail; if (!(e2 & DESC_S_MASK)) - return; + goto fail; rpl = selector & 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3; cpl = env->hflags & HF_CPL_MASK; if (e2 & DESC_CS_MASK) { - return; + goto fail; } else { if (dpl < cpl || dpl < rpl) + goto fail; + if (!(e2 & DESC_W_MASK)) { + fail: + CC_SRC = eflags & ~CC_Z; return; - if (!(e2 & DESC_W_MASK)) - return; + } } - CC_SRC |= CC_Z; + CC_SRC = eflags | CC_Z; } /* FPU helpers */ -- 2.11.4.GIT