Revert commit 891dfcdf3fc441a1863c43d179dc6e0e4d65836f since it assumes *all* architectures supported by tcc have GOT offsets aligned on 2. A rework of this commit is being done since without it all PLT entries grow by 4 bytes.
Unified · Split
| @@ -33,7 +33,6 @@ · 32 unmodified lines | ||
| 33 | 33 | |
| 34 | 34 | #include <stdlib.h> |
| 35 | 35 | #include <stdio.h> |
| 36 | −#include <limits.h> | |
| 37 | 36 | #include <stdarg.h> |
| 38 | 37 | #include <string.h> |
| 39 | 38 | #include <errno.h> |
| @@ -525,15 +524,11 @@ struct TCCState { · 485 unmodified lines | ||
| 525 | 524 | Section **priv_sections; |
| 526 | 525 | int nb_priv_sections; /* number of private sections */ |
| 527 | 526 | |
| 528 | − /* got & plt handling */ | |
| 527 | + /* got handling */ | |
| 529 | 528 | Section *got; |
| 530 | 529 | Section *plt; |
| 531 | − struct { | |
| 532 | − unsigned long plt_thumb_stub:1; | |
| 533 | − /* mult by 2 (or left shift by 1) before use */ | |
| 534 | − unsigned long got_offset:(sizeof(long)*CHAR_BIT-1); | |
| 535 | − } *sym_infos; | |
| 536 | − int nb_sym_infos; | |
| 530 | + unsigned long *got_offsets; | |
| 531 | + int nb_got_offsets; | |
| 537 | 532 | /* give the correspondance from symtab indexes to dynsym indexes */ |
| 538 | 533 | int *symtab_to_dynsym; |
| 539 | 534 | |
| @@ -581,7 +581,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 580 unmodified lines | ||
| 581 | 581 | break; |
| 582 | 582 | case R_386_GOT32: |
| 583 | 583 | /* we load the got offset */ |
| 584 | − *(int *)ptr += s1->sym_infos[sym_index].got_offset << 1; | |
| 584 | + *(int *)ptr += s1->got_offsets[sym_index]; | |
| 585 | 585 | break; |
| 586 | 586 | case R_386_16: |
| 587 | 587 | if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) { |
| @@ -760,7 +760,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 172 unmodified lines | ||
| 760 | 760 | break; |
| 761 | 761 | case R_ARM_GOT_BREL: |
| 762 | 762 | /* we load the got offset */ |
| 763 | − *(int *)ptr += s1->sym_infos[sym_index].got_offset << 1; | |
| 763 | + *(int *)ptr += s1->got_offsets[sym_index]; | |
| 764 | 764 | break; |
| 765 | 765 | case R_ARM_COPY: |
| 766 | 766 | break; |
| @@ -866,14 +866,14 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 99 unmodified lines | ||
| 866 | 866 | } |
| 867 | 867 | #endif |
| 868 | 868 | *(int *)ptr += (s1->got->sh_addr - addr + |
| 869 | − (s1->sym_infos[sym_index].got_offset << 1) - 4); | |
| 869 | + s1->got_offsets[sym_index] - 4); | |
| 870 | 870 | break; |
| 871 | 871 | case R_X86_64_GOTTPOFF: |
| 872 | 872 | *(int *)ptr += val - s1->got->sh_addr; |
| 873 | 873 | break; |
| 874 | 874 | case R_X86_64_GOT32: |
| 875 | 875 | /* we load the got offset */ |
| 876 | − *(int *)ptr += s1->sym_infos[sym_index].got_offset << 1; | |
| 876 | + *(int *)ptr += s1->got_offsets[sym_index]; | |
| 877 | 877 | break; |
| 878 | 878 | #else |
| 879 | 879 | #error unsupported processor |
| @@ -943,36 +943,23 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr) · 63 unmodified lines | ||
| 943 | 943 | return count; |
| 944 | 944 | } |
| 945 | 945 | |
| 946 | −static void put_sym_info(TCCState *s1, int index) | |
| 946 | +static void put_got_offset(TCCState *s1, int index, unsigned long val) | |
| 947 | 947 | { |
| 948 | 948 | int n; |
| 949 | − typeof(s1->sym_infos) tab; | |
| 949 | + unsigned long *tab; | |
| 950 | 950 | |
| 951 | − if (index >= s1->nb_sym_infos) { | |
| 951 | + if (index >= s1->nb_got_offsets) { | |
| 952 | 952 | /* find immediately bigger power of 2 and reallocate array */ |
| 953 | 953 | n = 1; |
| 954 | 954 | while (index >= n) |
| 955 | 955 | n *= 2; |
| 956 | − tab = tcc_realloc(s1->sym_infos, n * sizeof(unsigned long)); | |
| 957 | − s1->sym_infos = tab; | |
| 958 | − memset(s1->sym_infos + s1->nb_sym_infos, 0, | |
| 959 | − (n - s1->nb_sym_infos) * sizeof(unsigned long)); | |
| 960 | − s1->nb_sym_infos = n; | |
| 956 | + tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long)); | |
| 957 | + s1->got_offsets = tab; | |
| 958 | + memset(s1->got_offsets + s1->nb_got_offsets, 0, | |
| 959 | + (n - s1->nb_got_offsets) * sizeof(unsigned long)); | |
| 960 | + s1->nb_got_offsets = n; | |
| 961 | 961 | } |
| 962 | −} | |
| 963 | − | |
| 964 | −#ifdef TCC_TARGET_ARM | |
| 965 | −static void put_plt_thumb_stub(TCCState *s1, int index, unsigned char bit) | |
| 966 | −{ | |
| 967 | − put_sym_info(s1, index); | |
| 968 | − s1->sym_infos[index].plt_thumb_stub = bit; | |
| 969 | −} | |
| 970 | −#endif | |
| 971 | − | |
| 972 | −static void put_got_offset(TCCState *s1, int index, unsigned long val) | |
| 973 | −{ | |
| 974 | − put_sym_info(s1, index); | |
| 975 | − s1->sym_infos[index].got_offset = val >> 1; | |
| 962 | + s1->got_offsets[index] = val; | |
| 976 | 963 | } |
| 977 | 964 | |
| 978 | 965 | /* XXX: suppress that */ |
| @@ -1036,8 +1023,8 @@ static void put_got_entry(TCCState *s1, · 57 unmodified lines | ||
| 1036 | 1023 | build_got(s1); |
| 1037 | 1024 | |
| 1038 | 1025 | /* if a got entry already exists for that symbol, no need to add one */ |
| 1039 | − if (sym_index < s1->nb_sym_infos && | |
| 1040 | − s1->sym_infos[sym_index].got_offset << 1) | |
| 1026 | + if (sym_index < s1->nb_got_offsets && | |
| 1027 | + s1->got_offsets[sym_index] != 0) | |
| 1041 | 1028 | return; |
| 1042 | 1029 | |
| 1043 | 1030 | put_got_offset(s1, sym_index, s1->got->data_offset); |
| @@ -1117,13 +1104,10 @@ static void put_got_entry(TCCState *s1, · 73 unmodified lines | ||
| 1117 | 1104 | put32(p + 12, 0xe5bef008); |
| 1118 | 1105 | } |
| 1119 | 1106 | |
| 1120 | − if (s1->sym_infos[sym_index].plt_thumb_stub) { | |
| 1121 | − p = section_ptr_add(plt, 20); | |
| 1122 | − put32(p , 0x4778); // bx pc | |
| 1123 | − put32(p+2, 0x46c0); // nop | |
| 1124 | − p += 4; | |
| 1125 | − } else | |
| 1126 | − p = section_ptr_add(plt, 16); | |
| 1107 | + p = section_ptr_add(plt, 20); | |
| 1108 | + put32(p , 0x4778); // bx pc | |
| 1109 | + put32(p+2, 0x46c0); // nop | |
| 1110 | + p += 4; | |
| 1127 | 1111 | put32(p , 0xe59fc004); // ldr ip, [pc, #4] // offset in GOT |
| 1128 | 1112 | put32(p+4, 0xe08fc00c); // add ip, pc, ip // absolute address or offset |
| 1129 | 1113 | put32(p+8, 0xe59cf000); // ldr pc, [ip] // load absolute address or load offset |
| @@ -1510,9 +1494,9 @@ ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel) · 380 unmodified lines | ||
| 1510 | 1494 | ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index]; |
| 1511 | 1495 | unsigned long offset; |
| 1512 | 1496 | |
| 1513 | − if (sym_index >= s1->nb_sym_infos) | |
| 1497 | + if (sym_index >= s1->nb_got_offsets) | |
| 1514 | 1498 | return; |
| 1515 | − offset = s1->sym_infos[sym_index].got_offset << 1; | |
| 1499 | + offset = s1->got_offsets[sym_index]; | |
| 1516 | 1500 | section_reserve(s1->got, offset + PTR_SIZE); |
| 1517 | 1501 | #ifdef TCC_TARGET_X86_64 |
| 1518 | 1502 | /* only works for x86-64 */ |
| @@ -2086,8 +2070,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 567 unmodified lines | ||
| 2086 | 2070 | x=s1->got->sh_addr - s1->plt->sh_addr - 12; |
| 2087 | 2071 | p += 16; |
| 2088 | 2072 | while (p < p_end) { |
| 2089 | − if (get32(p) == 0x46c04778) /* PLT Thumb stub present */ | |
| 2090 | − p += 4; | |
| 2073 | + p += 4; | |
| 2091 | 2074 | put32(p + 12, x + get32(p + 12) + s1->plt->data - p); |
| 2092 | 2075 | p += 16; |
| 2093 | 2076 | } |
| @@ -2321,7 +2304,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 227 unmodified lines | ||
| 2321 | 2304 | tcc_free(s1->symtab_to_dynsym); |
| 2322 | 2305 | tcc_free(section_order); |
| 2323 | 2306 | tcc_free(phdr); |
| 2324 | − tcc_free(s1->sym_infos); | |
| 2307 | + tcc_free(s1->got_offsets); | |
| 2325 | 2308 | return ret; |
| 2326 | 2309 | } |
| 2327 | 2310 | |
| @@ -2616,19 +2599,6 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 288 unmodified lines | ||
| 2616 | 2599 | rel->r_info = ELFW(R_INFO)(sym_index, type); |
| 2617 | 2600 | /* offset the relocation offset */ |
| 2618 | 2601 | rel->r_offset += offseti; |
| 2619 | −#ifdef TCC_TARGET_ARM | |
| 2620 | − /* Jumps and branches from a Thumb code to a PLT entry need | |
| 2621 | − special handling since PLT entries are ARM code. | |
| 2622 | − Unconditional bl instructions referencing PLT entries are | |
| 2623 | − handled by converting these instructions into blx | |
| 2624 | − instructions. Other case of instructions referencing a PLT | |
| 2625 | − entry require to add a Thumb stub before the PLT entry to | |
| 2626 | − switch to ARM mode. We set bit 0 of the got offset of a | |
| 2627 | − symbol to indicate such a case. */ | |
| 2628 | − if (type == R_ARM_THM_JUMP24) { | |
| 2629 | − put_plt_thumb_stub(s1, sym_index, 1); | |
| 2630 | − } | |
| 2631 | −#endif | |
| 2632 | 2602 | } |
| 2633 | 2603 | break; |
| 2634 | 2604 | default: |