The problem occurs when a shared library creates a pointer to a function and then the application also uses this function.
Unified · Split
| @@ -665,7 +665,7 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 664 unmodified lines | ||
| 665 | 665 | Section *s; |
| 666 | 666 | ElfW_Rel *rel, save_rel; |
| 667 | 667 | ElfW(Sym) *sym; |
| 668 | − int i, type, gotplt_entry, sym_index, for_code; | |
| 668 | + int i, j, type, gotplt_entry, sym_index, for_code; | |
| 669 | 669 | uint32_t *pi, *goti; |
| 670 | 670 | struct sym_attr *attr; |
| 671 | 671 | |
| @@ -711,8 +711,8 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 39 unmodified lines | ||
| 711 | 711 | && type == R_AARCH64_ADR_GOT_PAGE |
| 712 | 712 | #endif |
| 713 | 713 | ) { |
| 714 | + attr->plt_offset = -mo->n_bind_rebase - 1; | |
| 714 | 715 | bind_rebase_add(mo, 1, s1->got->reloc->sh_info, &save_rel, attr); |
| 715 | − attr->plt_offset = 0; // ignore next bind | |
| 716 | 716 | s1->got->reloc->data_offset -= sizeof (ElfW_Rel); |
| 717 | 717 | } |
| 718 | 718 | if (for_code && sym->st_shndx == SHN_UNDEF) |
| @@ -720,6 +720,11 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 1 unmodified line | ||
| 720 | 720 | } |
| 721 | 721 | } |
| 722 | 722 | if (for_code && sym->st_shndx == SHN_UNDEF) { |
| 723 | + if ((int)attr->plt_offset < -1) { | |
| 724 | + /* remove above bind and replace with plt */ | |
| 725 | + mo->bind_rebase[-attr->plt_offset - 1].bind = 2; | |
| 726 | + attr->plt_offset = -1; | |
| 727 | + } | |
| 723 | 728 | if (attr->plt_offset == -1) { |
| 724 | 729 | uint8_t *jmp; |
| 725 | 730 | |
| @@ -764,6 +769,13 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 38 unmodified lines | ||
| 764 | 769 | s->sh_info, &save_rel, NULL); |
| 765 | 770 | } |
| 766 | 771 | } |
| 772 | + /* remove deleted binds */ | |
| 773 | + for (i = 0, j = 0; i < mo->n_bind_rebase; i++) | |
| 774 | + if (mo->bind_rebase[i].bind == 2) | |
| 775 | + mo->n_bind--; | |
| 776 | + else | |
| 777 | + mo->bind_rebase[j++] = mo->bind_rebase[i]; | |
| 778 | + mo->n_bind_rebase = j; | |
| 767 | 779 | pi = section_ptr_add(mo->indirsyms, mo->n_got * sizeof(*pi)); |
| 768 | 780 | memcpy(pi, goti, mo->n_got * sizeof(*pi)); |
| 769 | 781 | tcc_free(goti); |