History

Revert "Generate PLT thumb stub only when necessary"

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.

Thomas Preud'homme committed 14 years ago

Commit 1af3bca1 parent 3c986ee2 files · +26 −61Browse files

Unified · Split

2 files
  1. tcc.h +3 −8
  2. tccelf.c +23 −53
tcc.h+3−8
@@ -33,7 +33,6 @@ · 32 unmodified lines
33 33
34#include <stdlib.h>34#include <stdlib.h>
35#include <stdio.h>35#include <stdio.h>
36#include <limits.h>
37#include <stdarg.h>36#include <stdarg.h>
38#include <string.h>37#include <string.h>
39#include <errno.h>38#include <errno.h>
@@ -525,15 +524,11 @@ struct TCCState { · 485 unmodified lines
525 Section **priv_sections;524 Section **priv_sections;
526 int nb_priv_sections; /* number of private sections */525 int nb_priv_sections; /* number of private sections */
527 526
528 /* got & plt handling */527 /* got handling */
529 Section *got;528 Section *got;
530 Section *plt;529 Section *plt;
531 struct {530 unsigned long *got_offsets;
532 unsigned long plt_thumb_stub:1;531 int nb_got_offsets;
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;
537 /* give the correspondance from symtab indexes to dynsym indexes */532 /* give the correspondance from symtab indexes to dynsym indexes */
538 int *symtab_to_dynsym;533 int *symtab_to_dynsym;
539 534
tccelf.c+23−53
@@ -581,7 +581,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 580 unmodified lines
581 break;581 break;
582 case R_386_GOT32:582 case R_386_GOT32:
583 /* we load the got offset */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 break;585 break;
586 case R_386_16:586 case R_386_16:
587 if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {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 break;760 break;
761 case R_ARM_GOT_BREL:761 case R_ARM_GOT_BREL:
762 /* we load the got offset */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 break;764 break;
765 case R_ARM_COPY:765 case R_ARM_COPY:
766 break;766 break;
@@ -866,14 +866,14 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 99 unmodified lines
866 }866 }
867#endif867#endif
868 *(int *)ptr += (s1->got->sh_addr - addr +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 break;870 break;
871 case R_X86_64_GOTTPOFF:871 case R_X86_64_GOTTPOFF:
872 *(int *)ptr += val - s1->got->sh_addr;872 *(int *)ptr += val - s1->got->sh_addr;
873 break;873 break;
874 case R_X86_64_GOT32:874 case R_X86_64_GOT32:
875 /* we load the got offset */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 break;877 break;
878#else878#else
879#error unsupported processor879#error unsupported processor
@@ -943,36 +943,23 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr) · 63 unmodified lines
943 return count;943 return count;
944}944}
945 945
946static void put_sym_info(TCCState *s1, int index)946static void put_got_offset(TCCState *s1, int index, unsigned long val)
947{947{
948 int n;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 /* find immediately bigger power of 2 and reallocate array */952 /* find immediately bigger power of 2 and reallocate array */
953 n = 1;953 n = 1;
954 while (index >= n)954 while (index >= n)
955 n *= 2;955 n *= 2;
956 tab = tcc_realloc(s1->sym_infos, n * sizeof(unsigned long));956 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
957 s1->sym_infos = tab;957 s1->got_offsets = tab;
958 memset(s1->sym_infos + s1->nb_sym_infos, 0,958 memset(s1->got_offsets + s1->nb_got_offsets, 0,
959 (n - s1->nb_sym_infos) * sizeof(unsigned long));959 (n - s1->nb_got_offsets) * sizeof(unsigned long));
960 s1->nb_sym_infos = n;960 s1->nb_got_offsets = n;
961 }961 }
962}962 s1->got_offsets[index] = val;
963
964#ifdef TCC_TARGET_ARM
965static 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
972static 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;
976}963}
977 964
978/* XXX: suppress that */965/* XXX: suppress that */
@@ -1036,8 +1023,8 @@ static void put_got_entry(TCCState *s1, · 57 unmodified lines
1036 build_got(s1);1023 build_got(s1);
1037 1024
1038 /* if a got entry already exists for that symbol, no need to add one */1025 /* if a got entry already exists for that symbol, no need to add one */
1039 if (sym_index < s1->nb_sym_infos &&1026 if (sym_index < s1->nb_got_offsets &&
1040 s1->sym_infos[sym_index].got_offset << 1)1027 s1->got_offsets[sym_index] != 0)
1041 return;1028 return;
1042 1029
1043 put_got_offset(s1, sym_index, s1->got->data_offset);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 put32(p + 12, 0xe5bef008);1104 put32(p + 12, 0xe5bef008);
1118 }1105 }
1119 1106
1120 if (s1->sym_infos[sym_index].plt_thumb_stub) {1107 p = section_ptr_add(plt, 20);
1121 p = section_ptr_add(plt, 20);1108 put32(p , 0x4778); // bx pc
1122 put32(p , 0x4778); // bx pc1109 put32(p+2, 0x46c0); // nop
1123 put32(p+2, 0x46c0); // nop1110 p += 4;
1124 p += 4;
1125 } else
1126 p = section_ptr_add(plt, 16);
1127 put32(p , 0xe59fc004); // ldr ip, [pc, #4] // offset in GOT1111 put32(p , 0xe59fc004); // ldr ip, [pc, #4] // offset in GOT
1128 put32(p+4, 0xe08fc00c); // add ip, pc, ip // absolute address or offset1112 put32(p+4, 0xe08fc00c); // add ip, pc, ip // absolute address or offset
1129 put32(p+8, 0xe59cf000); // ldr pc, [ip] // load absolute address or load offset1113 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 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];1494 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1511 unsigned long offset;1495 unsigned long offset;
1512 1496
1513 if (sym_index >= s1->nb_sym_infos)1497 if (sym_index >= s1->nb_got_offsets)
1514 return;1498 return;
1515 offset = s1->sym_infos[sym_index].got_offset << 1;1499 offset = s1->got_offsets[sym_index];
1516 section_reserve(s1->got, offset + PTR_SIZE);1500 section_reserve(s1->got, offset + PTR_SIZE);
1517#ifdef TCC_TARGET_X86_641501#ifdef TCC_TARGET_X86_64
1518 /* only works for x86-64 */1502 /* only works for x86-64 */
@@ -2086,8 +2070,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 567 unmodified lines
2086 x=s1->got->sh_addr - s1->plt->sh_addr - 12;2070 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
2087 p += 16;2071 p += 16;
2088 while (p < p_end) {2072 while (p < p_end) {
2089 if (get32(p) == 0x46c04778) /* PLT Thumb stub present */2073 p += 4;
2090 p += 4;
2091 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);2074 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
2092 p += 16;2075 p += 16;
2093 }2076 }
@@ -2321,7 +2304,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 227 unmodified lines
2321 tcc_free(s1->symtab_to_dynsym);2304 tcc_free(s1->symtab_to_dynsym);
2322 tcc_free(section_order);2305 tcc_free(section_order);
2323 tcc_free(phdr);2306 tcc_free(phdr);
2324 tcc_free(s1->sym_infos);2307 tcc_free(s1->got_offsets);
2325 return ret;2308 return ret;
2326}2309}
2327 2310
@@ -2616,19 +2599,6 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 288 unmodified lines
2616 rel->r_info = ELFW(R_INFO)(sym_index, type);2599 rel->r_info = ELFW(R_INFO)(sym_index, type);
2617 /* offset the relocation offset */2600 /* offset the relocation offset */
2618 rel->r_offset += offseti;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 break;2603 break;
2634 default:2604 default:

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t