| @@ -654,8 +654,8 @@ ST_FUNC void relocate_common_syms(void) · 653 unmodified lines |
| 654 | true and output error if undefined symbol. */ | 654 | true and output error if undefined symbol. */ |
| 655 | ST_FUNC void relocate_syms(TCCState *s1, int do_resolve) | 655 | ST_FUNC void relocate_syms(TCCState *s1, int do_resolve) |
| 656 | { | 656 | { |
| 657 | ElfW(Sym) *sym, *esym; | 657 | ElfW(Sym) *sym; |
| 658 | int sym_bind, sh_num, sym_index; | 658 | int sym_bind, sh_num; |
| 659 | const char *name; | 659 | const char *name; |
| 660 | | 660 | |
| 661 | for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { | 661 | for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { |
| @@ -676,15 +676,9 @@ ST_FUNC void relocate_syms(TCCState *s1, int do_resolve) · 14 unmodified lines |
| 676 | goto found; | 676 | goto found; |
| 677 | } | 677 | } |
| 678 | #endif | 678 | #endif |
| 679 | } else if (s1->dynsym) { | 679 | /* if dynamic symbol exist, it will be used in relocate_section */ |
| 680 | /* if dynamic symbol exist, then use it */ | 680 | } else if (s1->dynsym && find_elf_sym(s1->dynsym, name)) |
| 681 | sym_index = find_elf_sym(s1->dynsym, name); | 681 | goto found; |
| 682 | if (sym_index) { | | |
| 683 | esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index]; | | |
| 684 | sym->st_value = esym->st_value; | | |
| 685 | goto found; | | |
| 686 | } | | |
| 687 | } | | |
| 688 | /* XXX: _fp_hw seems to be part of the ABI, so we ignore | 682 | /* XXX: _fp_hw seems to be part of the ABI, so we ignore |
| 689 | it */ | 683 | it */ |
| 690 | if (!strcmp(name, "_fp_hw")) | 684 | if (!strcmp(name, "_fp_hw")) |
| @@ -714,7 +708,8 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 23 unmodified lines |
| 714 | ElfW(Sym) *sym; | 708 | ElfW(Sym) *sym; |
| 715 | int type, sym_index; | 709 | int type, sym_index; |
| 716 | unsigned char *ptr; | 710 | unsigned char *ptr; |
| 717 | addr_t val, addr; | 711 | addr_t tgt, addr; |
| | 712 | struct sym_attr *symattr; |
| 718 | | 713 | |
| 719 | relocate_init(sr); | 714 | relocate_init(sr); |
| 720 | for_each_elem(sr, 0, rel, ElfW_Rel) { | 715 | for_each_elem(sr, 0, rel, ElfW_Rel) { |
| @@ -722,14 +717,22 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 1 unmodified line |
| 722 | | 717 | |
| 723 | sym_index = ELFW(R_SYM)(rel->r_info); | 718 | sym_index = ELFW(R_SYM)(rel->r_info); |
| 724 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; | 719 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; |
| 725 | val = sym->st_value; | 720 | type = ELFW(R_TYPE)(rel->r_info); |
| | 721 | symattr = get_sym_attr(s1, sym_index, 0); |
| | 722 | tgt = sym->st_value; |
| | 723 | /* If static relocation to a dynamic symbol, relocate to PLT entry. |
| | 724 | Note 1: in tcc -run mode we go through PLT to avoid range issues |
| | 725 | Note 2: symbols compiled with libtcc and later added with |
| | 726 | tcc_add_symbol are not dynamic and thus have symattr NULL */ |
| | 727 | if (relocs_info[type].gotplt_entry != NO_GOTPLT_ENTRY && |
| | 728 | relocs_info[type].code_reloc && symattr && symattr->plt_offset) |
| | 729 | tgt = s1->plt->sh_addr + symattr->plt_offset; |
| 726 | #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) | 730 | #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) |
| 727 | val += rel->r_addend; | 731 | tgt += rel->r_addend; |
| 728 | #endif | 732 | #endif |
| 729 | type = ELFW(R_TYPE)(rel->r_info); | | |
| 730 | addr = s->sh_addr + rel->r_offset; | 733 | addr = s->sh_addr + rel->r_offset; |
| 731 | | 734 | |
| 732 | relocate(s1, rel, type, ptr, addr, val); | 735 | relocate(s1, rel, type, ptr, addr, tgt); |
| 733 | } | 736 | } |
| 734 | /* if the relocation is allocated, we change its symbol table */ | 737 | /* if the relocation is allocated, we change its symbol table */ |
| 735 | if (sr->sh_flags & SHF_ALLOC) | 738 | if (sr->sh_flags & SHF_ALLOC) |
| @@ -1030,7 +1033,6 @@ ST_FUNC void build_got_entries(TCCState *s1) · 294 unmodified lines |
| 1030 | ElfW_Rel *rel; | 1033 | ElfW_Rel *rel; |
| 1031 | ElfW(Sym) *sym; | 1034 | ElfW(Sym) *sym; |
| 1032 | int i, type, reloc_type, sym_index; | 1035 | int i, type, reloc_type, sym_index; |
| 1033 | unsigned long ofs; | | |
| 1034 | | 1036 | |
| 1035 | for(i = 1; i < s1->nb_sections; i++) { | 1037 | for(i = 1; i < s1->nb_sections; i++) { |
| 1036 | s = s1->sections[i]; | 1038 | s = s1->sections[i]; |
| @@ -1075,38 +1077,8 @@ ST_FUNC void build_got_entries(TCCState *s1) · 38 unmodified lines |
| 1075 | reloc_type = R_JMP_SLOT; | 1077 | reloc_type = R_JMP_SLOT; |
| 1076 | else | 1078 | else |
| 1077 | reloc_type = R_GLOB_DAT; | 1079 | reloc_type = R_GLOB_DAT; |
| 1078 | ofs = put_got_entry(s1, reloc_type, type, sym->st_size, | 1080 | put_got_entry(s1, reloc_type, type, sym->st_size, sym->st_info, |
| 1079 | sym->st_info, sym_index); | 1081 | sym_index); |
| 1080 | | | |
| 1081 | #ifdef DEBUG_RELOC | | |
| 1082 | printf ("maybegot: %s, %d, %d --> ofs=0x%x\n", | | |
| 1083 | (char *) symtab_section->link->data + sym->st_name, type, | | |
| 1084 | sym->st_shndx, ofs); | | |
| 1085 | #endif | | |
| 1086 | | | |
| 1087 | #if defined (TCC_TARGET_X86_64) || defined(TCC_TARGET_ARM64) | | |
| 1088 | /* We store the place of the generated PLT slot in our addend. */ | | |
| 1089 | if (relocs_info[type].pltoff_addend) | | |
| 1090 | rel->r_addend += ofs; | | |
| 1091 | | | |
| 1092 | #elif defined (TCC_TARGET_ARM) | | |
| 1093 | if (type == R_ARM_PC24 || type == R_ARM_CALL || | | |
| 1094 | type == R_ARM_JUMP24 || type == R_ARM_PLT32) { | | |
| 1095 | addr_t *ptr = (addr_t*)(s1->sections[s->sh_info]->data | | |
| 1096 | + rel->r_offset); | | |
| 1097 | /* x must be signed! */ | | |
| 1098 | int x = *ptr & 0xffffff; | | |
| 1099 | x = (x << 8) >> 8; | | |
| 1100 | x <<= 2; | | |
| 1101 | x += ofs; | | |
| 1102 | x >>= 2; | | |
| 1103 | #ifdef DEBUG_RELOC | | |
| 1104 | printf ("insn=0x%x --> 0x%x (x==0x%x)\n", *ptr, | | |
| 1105 | (*ptr & 0xff000000) | x, x); | | |
| 1106 | #endif | | |
| 1107 | *ptr = (*ptr & 0xff000000) | x; | | |
| 1108 | } | | |
| 1109 | #endif | | |
| 1110 | } | 1082 | } |
| 1111 | } | 1083 | } |
| 1112 | } | 1084 | } |