diff options
| author | Philip <pipcet@gmail.com> | 2015-04-23 17:30:16 +0000 |
|---|---|---|
| committer | Philip <pipcet@gmail.com> | 2015-04-23 17:30:16 +0000 |
| commit | aacf65bbfa1dad801428c1978cebb45400a2bd93 (patch) | |
| tree | 81305a29fa40dc4a2d42447fad6fcfa8d4bb9bbe /x86_64-gen.c | |
| parent | b08ce880822875d4bef103719179501d6ba38730 (diff) | |
| download | tinycc-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.c | 3 |
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 */ |
