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.
master
Zhang Boyang 2017-09-09 21:11:56 +08:00
parent 02370acdc9
commit b39810ff78
1 changed files with 3 additions and 11 deletions

View File

@ -345,17 +345,9 @@ static void gen_static_call(int v)
static void gcall_or_jmp(int is_jmp) static void gcall_or_jmp(int is_jmp)
{ {
int r; int r;
if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) {
/* constant case */ /* constant and relocation case */
if (vtop->r & VT_SYM) { greloc(cur_text_section, vtop->sym, ind + 1, R_386_PC32);
/* 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);
}
oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */ oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */
} else { } else {
/* otherwise, indirect call */ /* otherwise, indirect call */