Signed-off-by: liguang <lig.f...@cn.fujitsu.com> --- target-i386/seg_helper.c | 71 +++++++++++++++++++++++++++++++++------------ 1 files changed, 52 insertions(+), 19 deletions(-)
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c index eb9dc04..2e6ee7c 100644 --- a/target-i386/seg_helper.c +++ b/target-i386/seg_helper.c @@ -2288,6 +2288,39 @@ void helper_sysexit(CPUX86State *env, int dflag) EIP = EDX; } +/* + * for data segment types + * RO -- read-only, A -- accessed, + * W -- write, E -- expand-down + */ +#define DESC_DSEG_RO 0 +#define DESC_DSEG_ROA 1 +#define DESC_DSEG_RW 2 +#define DESC_DSEG_RWA 3 +#define DESC_DSEG_ROE 4 +#define DESC_DSEG_ROEA 5 +#define DESC_DSEG_RWE 6 +#define DESC_DSEG_RWEA 7 + +/* + * for code segment types + * EO -- execute-only, A -- accessed, + * C -- conforming, E -- expand-down, R -- read + */ + +#define DESC_CSEG_EO 8 +#define DESC_CSEG_EOA 9 +#define DESC_CSEG_ER 10 +#define DESC_CSEG_ERA 11 +#define DESC_CSEG_EOC 12 +#define DESC_CSEG_EOCA 13 +#define DESC_CSEG_ERC 14 +#define DESC_CSEG_ERCA 15 + +#define FUNC_LSL 4 +#define FUNC_LAR 3 +#define FUNC_VERR 2 +#define FUNC_VERW 1 static target_ulong privilege_check(CPUX86State *env, target_ulong selector1, int inst) @@ -2313,15 +2346,15 @@ static target_ulong privilege_check(CPUX86State *env, target_ulong selector1, if (e2 & DESC_S_MASK) { if (e2 & DESC_CS_MASK) { switch (inst) { - case 1: + case FUNC_VERW: goto fail; - case 2: + case FUNC_VERR: if (!(e2 & (DESC_R_MASK | DESC_C_MASK))) { goto fail; } break; - case 3: - case 4: + case FUNC_LAR: + case FUNC_LSL: if (!(e2 & DESC_C_MASK)) { goto check_pl; } @@ -2333,17 +2366,17 @@ static target_ulong privilege_check(CPUX86State *env, target_ulong selector1, } else { type = (e2 >> DESC_TYPE_SHIFT) & 0xf; switch (type) { - case 1: - case 2: - case 3: - case 9: - case 11: - if (inst == 3) { + case DESC_DSEG_ROA: + case DESC_DSEG_RW: + case DESC_DSEG_RWA: + case DESC_CSEG_EOA: + case DESC_CSEG_ERA: + if (inst == FUNC_LAR) { break; } - case 5: - case 12: - if (inst == 4) { + case DESC_DSEG_ROEA: + case DESC_CSEG_EOC: + if (inst == FUNC_LSL) { break; } default: @@ -2352,10 +2385,10 @@ static target_ulong privilege_check(CPUX86State *env, target_ulong selector1, goto check_pl; } - if (inst == 3) { + if (inst == FUNC_LAR) { e2 &= 0x00f0ff00; } - if (inst == 4) { + if (inst == FUNC_LSL) { e2 = get_seg_limit(e1, e2); } @@ -2372,22 +2405,22 @@ fail: target_ulong helper_lsl(CPUX86State *env, target_ulong selector1) { - return privilege_check(env, selector1, 4); + return privilege_check(env, selector1, FUNC_LSL); } target_ulong helper_lar(CPUX86State *env, target_ulong selector1) { - return privilege_check(env, selector1, 3); + return privilege_check(env, selector1, FUNC_LAR); } void helper_verr(CPUX86State *env, target_ulong selector1) { - privilege_check(env, selector1, 2); + privilege_check(env, selector1, FUNC_VERR); } void helper_verw(CPUX86State *env, target_ulong selector1) { - privilege_check(env, selector1, 1); + privilege_check(env, selector1, FUNC_VERW); } #if defined(CONFIG_USER_ONLY) -- 1.7.2.5