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 | 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 | 818 | /* In an ELF file symbol table, the local symbols must appear below |
| 800 | 819 | the global and weak ones. Since TCC cannot sort it while generating |
| 801 | 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 | 825 | ElfW(Sym) *new_syms; |
| 807 | 826 | int nb_syms, i; |
| 808 | 827 | ElfW(Sym) *p, *q; |
| 809 | − ElfW_Rel *rel; | |
| 810 | − Section *sr; | |
| 811 | − int type, sym_index; | |
| 812 | 828 | |
| 813 | 829 | nb_syms = s->data_offset / sizeof(ElfW(Sym)); |
| 814 | 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 | 858 | memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym))); |
| 843 | 859 | tcc_free(new_syms); |
| 844 | 860 | |
| 845 | − /* now we modify all the relocations */ | |
| 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 | − } | |
| 861 | + modify_reloctions_old_to_new(s1, s, old_to_new_syms); | |
| 857 | 862 | |
| 858 | 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 | 868 | #define ELFCLASS_BITS (PTR_SIZE * 8) |
| 864 | 869 | |
| 870 | +#ifndef ELF_OBJ_ONLY | |
| 865 | 871 | static void create_gnu_hash(TCCState *s1) |
| 866 | 872 | { |
| 867 | 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 | 906 | ptr[2] = bloom_size; |
| 901 | 907 | ptr[3] = bloom_shift; |
| 902 | 908 | } |
| 909 | +#endif | |
| 903 | 910 | |
| 904 | 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 | 914 | ElfW(Sym) *new_syms; |
| 908 | 915 | int nb_syms, i, nbuckets, bloom_size, bloom_shift; |
| 909 | 916 | ElfW(Sym) *p, *q; |
| 910 | − ElfW_Rel *rel; | |
| 911 | − Section *sr, *vs; | |
| 917 | + Section *vs; | |
| 912 | 918 | Section *gnu_hash; |
| 913 | 919 | Section *dynsym = s1->dynsym; |
| 914 | − int type, sym_index; | |
| 915 | 920 | Elf32_Word *ptr, *buckets, *chain, *hash; |
| 916 | 921 | unsigned int *nextbuck; |
| 917 | 922 | addr_t *bloom; |
| @@ -1004,18 +1009,7 @@ static void update_gnu_hash(TCCState *s1) · 86 unmodified lines | ||
| 1004 | 1009 | tcc_free(buck); |
| 1005 | 1010 | tcc_free(nextbuck); |
| 1006 | 1011 | |
| 1007 | − /* modify all the relocations */ | |
| 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 | − } | |
| 1012 | + modify_reloctions_old_to_new(s1, dynsym, old_to_new_syms); | |
| 1019 | 1013 | |
| 1020 | 1014 | /* modify the versions */ |
| 1021 | 1015 | vs = find_section_create(s1, ".gnu.version", 0); |