aboutsummaryrefslogtreecommitdiff
path: root/dyngen.c
diff options
context:
space:
mode:
authormalc <malc@c046a42c-6fe2-441c-8c8c-71466251a162>2008-06-09 06:06:28 +0000
committermalc <malc@c046a42c-6fe2-441c-8c8c-71466251a162>2008-06-09 06:06:28 +0000
commit5be1676206f83dc603a8746de8026b3f966b1b97 (patch)
tree42e2c0af455c5448e4a7772f4f4c3b0c8838d980 /dyngen.c
parent398ce98e4f4286370d97a7e51b01bf6334c3b65e (diff)
R_PPC_REL24 safety net
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4706 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'dyngen.c')
-rw-r--r--dyngen.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/dyngen.c b/dyngen.c
index c38d12386f..880d641a56 100644
--- a/dyngen.c
+++ b/dyngen.c
@@ -1963,6 +1963,14 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
break;
case R_PPC_REL24:
/* warning: must be at 32 MB distancy */
+ fprintf(outfile, "{\n"
+ " long disp = (%s - (long)(gen_code_ptr + %d) + %d);\n"
+ " if ((disp << 6) >> 6 != disp) {;\n"
+ " fprintf(stderr, \"Branch target is too far away\\n\");"
+ " abort();\n"
+ " }\n"
+ "}\n",
+ relname, reloc_offset, addend);
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n",
reloc_offset, reloc_offset, relname, reloc_offset, addend);
break;