Also add new function modify_reloctions_old_to_new for common code in sort_syms and update_gnu_hash.
Unified · Split
| @@ -796,6 +796,25 @@ ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc) · 795 unmodified lines | |||
| 796 | return &s1->sym_attrs[index]; | 796 | return &s1->sym_attrs[index]; |
| 797 | } | 797 | } |
| 798 | 798 | ||
| 799 | static void modify_reloctions_old_to_new(TCCState *s1, Section *s, int *old_to_new_syms) | ||
| 800 | { | ||
| 801 | int i, type, sym_index; | ||
| 802 | Section *sr; | ||
| 803 | ElfW_Rel *rel; | ||
| 804 | |||
| 805 | for(i = 1; i < s1->nb_sections; i++) { | ||
| 806 | sr = s1->sections[i]; | ||
| 807 | if (sr->sh_type == SHT_RELX && sr->link == s) { | ||
| 808 | for_each_elem(sr, 0, rel, ElfW_Rel) { | ||
| 809 | sym_index = ELFW(R_SYM)(rel->r_info); | ||
| 810 | type = ELFW(R_TYPE)(rel->r_info); | ||
| 811 | sym_index = old_to_new_syms[sym_index]; | ||
| 812 | rel->r_info = ELFW(R_INFO)(sym_index, type); | ||
| 813 | } | ||
| 814 | } | ||
| 815 | } | ||
| 816 | } | ||
| 817 | |||
| 799 | /* In an ELF file symbol table, the local symbols must appear below | 818 | /* In an ELF file symbol table, the local symbols must appear below |
| 800 | the global and weak ones. Since TCC cannot sort it while generating | 819 | the global and weak ones. Since TCC cannot sort it while generating |
| 801 | the code, we must do it after. All the relocation tables are also | 820 | the code, we must do it after. All the relocation tables are also |
| @@ -806,9 +825,6 @@ static void sort_syms(TCCState *s1, Section *s) · 4 unmodified lines | |||
| 806 | ElfW(Sym) *new_syms; | 825 | ElfW(Sym) *new_syms; |
| 807 | int nb_syms, i; | 826 | int nb_syms, i; |
| 808 | ElfW(Sym) *p, *q; | 827 | ElfW(Sym) *p, *q; |
| 809 | ElfW_Rel *rel; | ||
| 810 | Section *sr; | ||
| 811 | int type, sym_index; | ||
| 812 | 828 | ||
| 813 | nb_syms = s->data_offset / sizeof(ElfW(Sym)); | 829 | nb_syms = s->data_offset / sizeof(ElfW(Sym)); |
| 814 | new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym))); | 830 | new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym))); |
| @@ -842,18 +858,7 @@ static void sort_syms(TCCState *s1, Section *s) · 27 unmodified lines | |||
| 842 | memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym))); | 858 | memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym))); |
| 843 | tcc_free(new_syms); | 859 | tcc_free(new_syms); |
| 844 | 860 | ||
| 845 | /* now we modify all the relocations */ | 861 | modify_reloctions_old_to_new(s1, s, old_to_new_syms); |
| 846 | for(i = 1; i < s1->nb_sections; i++) { | ||
| 847 | sr = s1->sections[i]; | ||
| 848 | if (sr->sh_type == SHT_RELX && sr->link == s) { | ||
| 849 | for_each_elem(sr, 0, rel, ElfW_Rel) { | ||
| 850 | sym_index = ELFW(R_SYM)(rel->r_info); | ||
| 851 | type = ELFW(R_TYPE)(rel->r_info); | ||
| 852 | sym_index = old_to_new_syms[sym_index]; | ||
| 853 | rel->r_info = ELFW(R_INFO)(sym_index, type); | ||
| 854 | } | ||
| 855 | } | ||
| 856 | } | ||
| 857 | 862 | ||
| 858 | tcc_free(old_to_new_syms); | 863 | tcc_free(old_to_new_syms); |
| 859 | } | 864 | } |
| @@ -862,6 +867,7 @@ static void sort_syms(TCCState *s1, Section *s) · 2 unmodified lines | |||
| 862 | 867 | ||
| 863 | #define ELFCLASS_BITS (PTR_SIZE * 8) | 868 | #define ELFCLASS_BITS (PTR_SIZE * 8) |
| 864 | 869 | ||
| 870 | #ifndef ELF_OBJ_ONLY | ||
| 865 | static void create_gnu_hash(TCCState *s1) | 871 | static void create_gnu_hash(TCCState *s1) |
| 866 | { | 872 | { |
| 867 | int nb_syms, i, ndef, nbuckets, symoffset, bloom_size, bloom_shift; | 873 | int nb_syms, i, ndef, nbuckets, symoffset, bloom_size, bloom_shift; |
| @@ -900,6 +906,7 @@ static void create_gnu_hash(TCCState *s1) · 32 unmodified lines | |||
| 900 | ptr[2] = bloom_size; | 906 | ptr[2] = bloom_size; |
| 901 | ptr[3] = bloom_shift; | 907 | ptr[3] = bloom_shift; |
| 902 | } | 908 | } |
| 909 | #endif | ||
| 903 | 910 | ||
| 904 | static void update_gnu_hash(TCCState *s1) | 911 | static void update_gnu_hash(TCCState *s1) |
| 905 | { | 912 | { |
| @@ -907,11 +914,9 @@ static void update_gnu_hash(TCCState *s1) · 1 unmodified line | |||
| 907 | ElfW(Sym) *new_syms; | 914 | ElfW(Sym) *new_syms; |
| 908 | int nb_syms, i, nbuckets, bloom_size, bloom_shift; | 915 | int nb_syms, i, nbuckets, bloom_size, bloom_shift; |
| 909 | ElfW(Sym) *p, *q; | 916 | ElfW(Sym) *p, *q; |
| 910 | ElfW_Rel *rel; | 917 | Section *vs; |
| 911 | Section *sr, *vs; | ||
| 912 | Section *gnu_hash; | 918 | Section *gnu_hash; |
| 913 | Section *dynsym = s1->dynsym; | 919 | Section *dynsym = s1->dynsym; |
| 914 | int type, sym_index; | ||
| 915 | Elf32_Word *ptr, *buckets, *chain, *hash; | 920 | Elf32_Word *ptr, *buckets, *chain, *hash; |
| 916 | unsigned int *nextbuck; | 921 | unsigned int *nextbuck; |
| 917 | addr_t *bloom; | 922 | addr_t *bloom; |
| @@ -1004,18 +1009,7 @@ static void update_gnu_hash(TCCState *s1) · 86 unmodified lines | |||
| 1004 | tcc_free(buck); | 1009 | tcc_free(buck); |
| 1005 | tcc_free(nextbuck); | 1010 | tcc_free(nextbuck); |
| 1006 | 1011 | ||
| 1007 | /* modify all the relocations */ | 1012 | modify_reloctions_old_to_new(s1, dynsym, old_to_new_syms); |
| 1008 | for(i = 1; i < s1->nb_sections; i++) { | ||
| 1009 | sr = s1->sections[i]; | ||
| 1010 | if (sr->sh_type == SHT_RELX && sr->link == dynsym) { | ||
| 1011 | for_each_elem(sr, 0, rel, ElfW_Rel) { | ||
| 1012 | sym_index = ELFW(R_SYM)(rel->r_info); | ||
| 1013 | type = ELFW(R_TYPE)(rel->r_info); | ||
| 1014 | sym_index = old_to_new_syms[sym_index]; | ||
| 1015 | rel->r_info = ELFW(R_INFO)(sym_index, type); | ||
| 1016 | } | ||
| 1017 | } | ||
| 1018 | } | ||
| 1019 | 1013 | ||
| 1020 | /* modify the versions */ | 1014 | /* modify the versions */ |
| 1021 | vs = find_section_create(s1, ".gnu.version", 0); | 1015 | vs = find_section_create(s1, ".gnu.version", 0); |