aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhang Boyang <zhangboyang.id@gmail.com>2017-09-09 21:11:56 +0800
committerZhang Boyang <zhangboyang.id@gmail.com>2017-09-09 21:11:56 +0800
commitb39810ff7820665f1780a3dff99420b5061e02c4 (patch)
tree8852e20ee7ddaa2fc7b80e19467b8d44967a3abe
parent02370acdc9967255cd06a928499fd1981356595e (diff)
downloadtinycc-b39810ff7820665f1780a3dff99420b5061e02c4.tar.gz
tinycc-b39810ff7820665f1780a3dff99420b5061e02c4.tar.bz2
Fix calling function pointers casted from intergers in DLL
The code generated for "((void (*)(void))0x12345678)()" will be a single "CALL 0x12345678" in previous code. However, this will not work for DLLs, because "CALL imm" is PC related, DLL relocation will break the code. This commit fixed the problem by forcing TCC generates indirect CALLs in this situation.
-rw-r--r--i386-gen.c14
1 files changed, 3 insertions, 11 deletions
diff --git a/i386-gen.c b/i386-gen.c
index ef893b3..4924381 100644
--- a/i386-gen.c
+++ b/i386-gen.c
@@ -345,17 +345,9 @@ static void gen_static_call(int v)
static void gcall_or_jmp(int is_jmp)
{
int r;
- if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
- /* constant case */
- if (vtop->r & VT_SYM) {
- /* relocation case */
- greloc(cur_text_section, vtop->sym,
- ind + 1, R_386_PC32);
- } else {
- /* put an empty PC32 relocation */
- put_elf_reloc(symtab_section, cur_text_section,
- ind + 1, R_386_PC32, 0);
- }
+ if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) {
+ /* constant and relocation case */
+ greloc(cur_text_section, vtop->sym, ind + 1, R_386_PC32);
oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */
} else {
/* otherwise, indirect call */