From: Florian Krohm Date: Mon, 6 Aug 2012 13:35:33 +0000 (+0000) Subject: The arguments in a helper call need to be sign/zero-extended X-Git-Tag: svn/VALGRIND_3_8_1^2~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=569355ef79fb1150cb17dd369470572a445e6f15;p=thirdparty%2Fvalgrind.git The arguments in a helper call need to be sign/zero-extended to 64 bit. Fix helper calls accordingly. And because I keep forgetting this, add checking machinery in the insn selector so it won't happen again. Diagnosed by Christian Borntraeger. git-svn-id: svn://svn.valgrind.org/vex/trunk@2462 --- diff --git a/VEX/priv/guest_s390_toIR.c b/VEX/priv/guest_s390_toIR.c index 188992f748..334287fe1a 100644 --- a/VEX/priv/guest_s390_toIR.c +++ b/VEX/priv/guest_s390_toIR.c @@ -10685,7 +10685,7 @@ s390_call_cvd(IRExpr *in) static HChar * s390_irgen_CVD(UChar r1, IRTemp op2addr) { - store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1))); + store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1)))); return "cvd"; } @@ -11212,7 +11212,8 @@ s390_irgen_CU21(UChar m3, UChar r1, UChar r2) /* Call the helper */ IRTemp retval = newTemp(Ity_I64); - assign(retval, s390_call_cu21(mkexpr(srcval), mkexpr(low_surrogate))); + assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)), + unop(Iop_32Uto64, mkexpr(low_surrogate)))); /* Before we can test whether the 1st operand is exhausted we need to test for an invalid low surrogate. Because cc=2 outranks cc=1. */ @@ -11339,7 +11340,8 @@ s390_irgen_CU24(UChar m3, UChar r1, UChar r2) /* Call the helper */ IRTemp retval = newTemp(Ity_I64); - assign(retval, s390_call_cu24(mkexpr(srcval), mkexpr(low_surrogate))); + assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)), + unop(Iop_32Uto64, mkexpr(low_surrogate)))); /* Before we can test whether the 1st operand is exhausted we need to test for an invalid low surrogate. Because cc=2 outranks cc=1. */ @@ -11416,7 +11418,7 @@ s390_irgen_CU42(UChar r1, UChar r2) /* Call the helper */ IRTemp retval = newTemp(Ity_I64); - assign(retval, s390_call_cu42(mkexpr(srcval))); + assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval)))); /* If the UTF-32 character was invalid, set cc=2 and we're done. cc=2 outranks cc=1 (1st operand exhausted) */ @@ -11510,7 +11512,7 @@ s390_irgen_CU41(UChar r1, UChar r2) /* Call the helper */ IRTemp retval = newTemp(Ity_I64); - assign(retval, s390_call_cu41(mkexpr(srcval))); + assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval)))); /* If the UTF-32 character was invalid, set cc=2 and we're done. cc=2 outranks cc=1 (1st operand exhausted) */ @@ -11628,13 +11630,13 @@ s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12) next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1))); /* There is at least one byte there. Read it. */ - IRTemp byte1 = newTemp(Ity_I32); - assign(byte1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(addr2)))); + IRTemp byte1 = newTemp(Ity_I64); + assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2)))); /* Call the helper to get number of bytes and invalid byte indicator */ IRTemp retval1 = newTemp(Ity_I64); assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1), - mkU32(extended_checking))); + mkU64(extended_checking))); /* Check for invalid 1st byte */ IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1)); @@ -11654,13 +11656,13 @@ s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12) cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes)); addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1)); - byte2 = mkite(cond, unop(Iop_8Uto32, load(Ity_I8, addr)), mkU32(0)); + byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0)); cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes)); addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2)); - byte3 = mkite(cond, unop(Iop_8Uto32, load(Ity_I8, addr)), mkU32(0)); + byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0)); cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes)); addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3)); - byte4 = mkite(cond, unop(Iop_8Uto32, load(Ity_I8, addr)), mkU32(0)); + byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0)); /* Call the helper to get the converted value and invalid byte indicator. We can pass at most 5 arguments; therefore some encoding is needed diff --git a/VEX/priv/host_s390_isel.c b/VEX/priv/host_s390_isel.c index 565111ab3c..8ac425a38e 100644 --- a/VEX/priv/host_s390_isel.c +++ b/VEX/priv/host_s390_isel.c @@ -465,6 +465,25 @@ doHelperCall(ISelEnv *env, Bool passBBP, IRExpr *guard, vpanic("doHelperCall: too many arguments"); } + /* All arguments must have Ity_I64. For two reasons: + (1) We do not handle floating point arguments. + (2) The ABI requires that integer values are sign- or zero-extended + to 64 bit. + */ + Int arg_errors = 0; + for (i = 0; i < n_args; ++i) { + IRType type = typeOfIRExpr(env->type_env, args[i]); + if (type != Ity_I64) { + ++arg_errors; + vex_printf("calling %s: argument #%d has type ", callee->name, i); + ppIRType(type); + vex_printf("; Ity_I64 is required\n"); + } + } + + if (arg_errors) + vpanic("cannot continue due to errors in argument passing"); + argreg = 0; /* If we need the guest state pointer put it in a temporary arg reg */