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 | Section *s; | 665 | Section *s; |
| 666 | ElfW_Rel *rel, save_rel; | 666 | ElfW_Rel *rel, save_rel; |
| 667 | ElfW(Sym) *sym; | 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 | uint32_t *pi, *goti; | 669 | uint32_t *pi, *goti; |
| 670 | struct sym_attr *attr; | 670 | struct sym_attr *attr; |
| 671 | 671 | ||
| @@ -711,8 +711,8 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 39 unmodified lines | |||
| 711 | && type == R_AARCH64_ADR_GOT_PAGE | 711 | && type == R_AARCH64_ADR_GOT_PAGE |
| 712 | #endif | 712 | #endif |
| 713 | ) { | 713 | ) { |
| 714 | attr->plt_offset = -mo->n_bind_rebase - 1; | ||
| 714 | bind_rebase_add(mo, 1, s1->got->reloc->sh_info, &save_rel, attr); | 715 | bind_rebase_add(mo, 1, s1->got->reloc->sh_info, &save_rel, attr); |
| 715 | attr->plt_offset = 0; // ignore next bind | ||
| 716 | s1->got->reloc->data_offset -= sizeof (ElfW_Rel); | 716 | s1->got->reloc->data_offset -= sizeof (ElfW_Rel); |
| 717 | } | 717 | } |
| 718 | if (for_code && sym->st_shndx == SHN_UNDEF) | 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 | if (for_code && sym->st_shndx == SHN_UNDEF) { | 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 | if (attr->plt_offset == -1) { | 728 | if (attr->plt_offset == -1) { |
| 724 | uint8_t *jmp; | 729 | uint8_t *jmp; |
| 725 | 730 | ||
| @@ -764,6 +769,13 @@ static void check_relocs(TCCState *s1, struct macho *mo) · 38 unmodified lines | |||
| 764 | s->sh_info, &save_rel, NULL); | 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 | pi = section_ptr_add(mo->indirsyms, mo->n_got * sizeof(*pi)); | 779 | pi = section_ptr_add(mo->indirsyms, mo->n_got * sizeof(*pi)); |
| 768 | memcpy(pi, goti, mo->n_got * sizeof(*pi)); | 780 | memcpy(pi, goti, mo->n_got * sizeof(*pi)); |
| 769 | tcc_free(goti); | 781 | tcc_free(goti); |