aboutsummaryrefslogtreecommitdiff
path: root/x86_64-gen.c
diff options
context:
space:
mode:
authorPhilip <pipcet@gmail.com>2015-04-23 17:30:16 +0000
committerPhilip <pipcet@gmail.com>2015-04-23 17:30:16 +0000
commitaacf65bbfa1dad801428c1978cebb45400a2bd93 (patch)
tree81305a29fa40dc4a2d42447fad6fcfa8d4bb9bbe /x86_64-gen.c
parentb08ce880822875d4bef103719179501d6ba38730 (diff)
downloadtinycc-aacf65bbfa1dad801428c1978cebb45400a2bd93.tar.gz
tinycc-aacf65bbfa1dad801428c1978cebb45400a2bd93.tar.bz2
Bugfix: 32-bit vs 64-bit bug in x86_64-gen.c:gcall_or_jmp
Verify an immediate value fits into 32 bits before jumping to it/calling it with a 32-bit immediate operand. Without this fix, code along the lines of ((int (*)(const char *, ...))140244834372944LL)("hi\n"); will fail mysteriously, even if that decimal constant is the correct address for printf. See https://github.com/pipcet/tinycc/tree/bugfix-1
Diffstat (limited to 'x86_64-gen.c')
-rw-r--r--x86_64-gen.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/x86_64-gen.c b/x86_64-gen.c
index 0083f8b..dc7eeca 100644
--- a/x86_64-gen.c
+++ b/x86_64-gen.c
@@ -600,7 +600,8 @@ void store(int r, SValue *v)
static void gcall_or_jmp(int is_jmp)
{
int r;
- if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+ if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
+ ((vtop->r & VT_SYM) || (vtop->c.ll-4) == (int)(vtop->c.ll-4))) {
/* constant case */
if (vtop->r & VT_SYM) {
/* relocation case */