History

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.

Michael Matz committed 8 years ago

Commit d79caa91 parent 65c7f193 files · +11 −13Browse files

Unified · Split

3 files
  1. arm64-gen.c +2 −2
  2. tests/tests2/07_function.c +5 −0
  3. x86_64-gen.c +4 −11
arm64-gen.c+2−2
@@ -580,8 +580,8 @@ ST_FUNC void store(int r, SValue *sv) · 579 unmodified lines
580580
581581 static void arm64_gen_bl_or_b(int b)
582582 {
583− if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
584− assert(!b && (vtop->r & VT_SYM));
583+ if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) {
584+ assert(!b);
585585 greloca(cur_text_section, vtop->sym, ind, R_AARCH64_CALL26, 0);
586586 o(0x94000000); // bl .
587587 }
tests/tests2/07_function.c+5−0
@@ -15,6 +15,11 @@ void qfunc() · 14 unmodified lines
1515 printf("qfunc()\n");
1616 }
1717
18+void zfunc()
19+{
20+ ((void (*)(void))0) ();
21+}
22+
1823 int main()
1924 {
2025 printf("%d\n", myfunc(3));
x86_64-gen.c+4−11
@@ -623,20 +623,13 @@ static void gcall_or_jmp(int is_jmp) · 622 unmodified lines
623623 {
624624 int r;
625625 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
626− ((vtop->r & VT_SYM) || (vtop->c.i-4) == (int)(vtop->c.i-4))) {
627− /* constant case */
628− if (vtop->r & VT_SYM) {
629− /* relocation case */
626+ ((vtop->r & VT_SYM) && (vtop->c.i-4) == (int)(vtop->c.i-4))) {
627+ /* constant symbolic case -> simple relocation */
630628 #ifdef TCC_TARGET_PE
631− greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PC32, (int)(vtop->c.i-4));
629+ greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PC32, (int)(vtop->c.i-4));
632630 #else
633− greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PLT32, (int)(vtop->c.i-4));
631+ greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PLT32, (int)(vtop->c.i-4));
634632 #endif
635− } else {
636− /* put an empty PC32 relocation */
637− put_elf_reloca(symtab_section, cur_text_section,
638− ind + 1, R_X86_64_PC32, 0, (int)(vtop->c.i-4));
639− }
640633 oad(0xe8 + is_jmp, 0); /* call/jmp im */
641634 } else {
642635 /* otherwise, indirect call */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t