mirror of
https://github.com/mirror/tinycc.git
synced 2025-03-10 08:50:07 +08:00
x86-64: Fix calls via absolute function pointers
linkers don't treat relocations using symindex 0 (undefined) very well, it can't be misused as indicator for an absolute number. Just don't bother with special casing this, rather emit an indirect call/jump right away. ARM64 needs the same (and didn't handle calls via constant absolute func pointers before). The testcase as is doesn't fail without the patch, it actually needs separate compilation (to -fPIC .o file, then to shared lib) to fail.
This commit is contained in:
parent
65c7f19deb
commit
d79caa9ff6
@ -580,8 +580,8 @@ ST_FUNC void store(int r, SValue *sv)
|
|||||||
|
|
||||||
static void arm64_gen_bl_or_b(int b)
|
static void arm64_gen_bl_or_b(int b)
|
||||||
{
|
{
|
||||||
if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
|
if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) {
|
||||||
assert(!b && (vtop->r & VT_SYM));
|
assert(!b);
|
||||||
greloca(cur_text_section, vtop->sym, ind, R_AARCH64_CALL26, 0);
|
greloca(cur_text_section, vtop->sym, ind, R_AARCH64_CALL26, 0);
|
||||||
o(0x94000000); // bl .
|
o(0x94000000); // bl .
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,11 @@ void qfunc()
|
|||||||
printf("qfunc()\n");
|
printf("qfunc()\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void zfunc()
|
||||||
|
{
|
||||||
|
((void (*)(void))0) ();
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
printf("%d\n", myfunc(3));
|
printf("%d\n", myfunc(3));
|
||||||
|
15
x86_64-gen.c
15
x86_64-gen.c
@ -623,20 +623,13 @@ 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) || (vtop->c.i-4) == (int)(vtop->c.i-4))) {
|
((vtop->r & VT_SYM) && (vtop->c.i-4) == (int)(vtop->c.i-4))) {
|
||||||
/* constant case */
|
/* constant symbolic case -> simple relocation */
|
||||||
if (vtop->r & VT_SYM) {
|
|
||||||
/* relocation case */
|
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PC32, (int)(vtop->c.i-4));
|
greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PC32, (int)(vtop->c.i-4));
|
||||||
#else
|
#else
|
||||||
greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PLT32, (int)(vtop->c.i-4));
|
greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PLT32, (int)(vtop->c.i-4));
|
||||||
#endif
|
#endif
|
||||||
} else {
|
|
||||||
/* put an empty PC32 relocation */
|
|
||||||
put_elf_reloca(symtab_section, cur_text_section,
|
|
||||||
ind + 1, R_X86_64_PC32, 0, (int)(vtop->c.i-4));
|
|
||||||
}
|
|
||||||
oad(0xe8 + is_jmp, 0); /* call/jmp im */
|
oad(0xe8 + is_jmp, 0); /* call/jmp im */
|
||||||
} else {
|
} else {
|
||||||
/* otherwise, indirect call */
|
/* otherwise, indirect call */
|
||||||
|
Loading…
Reference in New Issue
Block a user