tcg/s390x: Return false on failure from patch_reloc

This does require an extra two checks within the slow paths
to replace the assert that we're moving. Also add two checks
within existing functions that lacked any kind of assert for
out of range branch.

Backports commit 55dfd8fedceb1311d9cdded1a0f94b2da91a387d from qemu
This commit is contained in:
Richard Henderson 2018-12-18 05:33:59 -05:00 committed by Lioncash
parent 51b802223a
commit 7927f3cff5
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -383,23 +383,29 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
switch (type) {
case R_390_PC16DBL:
assert(pcrel2 == (int16_t)pcrel2);
tcg_patch16(code_ptr, pcrel2);
if (pcrel2 == (int16_t)pcrel2) {
tcg_patch16(code_ptr, pcrel2);
return true;
}
break;
case R_390_PC32DBL:
assert(pcrel2 == (int32_t)pcrel2);
tcg_patch32(code_ptr, pcrel2);
if (pcrel2 == (int32_t)pcrel2) {
tcg_patch32(code_ptr, pcrel2);
return true;
}
break;
case R_390_20:
assert(value == sextract64(value, 0, 20));
old = *(uint32_t *)code_ptr & 0xf00000ff;
old |= ((value & 0xfff) << 16) | ((value & 0xff000) >> 4);
tcg_patch32(code_ptr, old);
if (value == sextract64(value, 0, 20)) {
old = *(uint32_t *)code_ptr & 0xf00000ff;
old |= ((value & 0xfff) << 16) | ((value & 0xff000) >> 4);
tcg_patch32(code_ptr, old);
return true;
}
break;
default:
g_assert_not_reached();
}
return true;
return false;
}
/* parse target specific constraints */
@ -1339,6 +1345,7 @@ static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
if (l->has_value) {
off = l->u.value_ptr - s->code_ptr;
tcg_debug_assert(off == (int16_t)off);
} else {
tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, 2);
}
@ -1355,6 +1362,7 @@ static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
if (l->has_value) {
off = l->u.value_ptr - s->code_ptr;
tcg_debug_assert(off == (int16_t)off);
} else {
tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, l, 2);
}
@ -1621,7 +1629,9 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
TCGMemOpIdx oi = lb->oi;
TCGMemOp opc = get_memop(oi);
patch_reloc(lb->label_ptr[0], R_390_PC16DBL, (intptr_t)s->code_ptr, 2);
bool ok = patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
(intptr_t)s->code_ptr, 2);
tcg_debug_assert(ok);
tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_AREG0);
if (TARGET_LONG_BITS == 64) {
@ -1642,7 +1652,9 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
TCGMemOpIdx oi = lb->oi;
TCGMemOp opc = get_memop(oi);
patch_reloc(lb->label_ptr[0], R_390_PC16DBL, (intptr_t)s->code_ptr, 2);
bool ok = patch_reloc(lb->label_ptr[0], R_390_PC16DBL,
(intptr_t)s->code_ptr, 2);
tcg_debug_assert(ok);
tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_AREG0);
if (TARGET_LONG_BITS == 64) {