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
3333
3434 #include <stdlib.h>
3535 #include <stdio.h>
36−#include <limits.h>
3736 #include <stdarg.h>
3837 #include <string.h>
3938 #include <errno.h>
@@ -525,15 +524,11 @@ struct TCCState { · 485 unmodified lines
525524 Section **priv_sections;
526525 int nb_priv_sections; /* number of private sections */
527526
528− /* got & plt handling */
527+ /* got handling */
529528 Section *got;
530529 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;
537532 /* give the correspondance from symtab indexes to dynsym indexes */
538533 int *symtab_to_dynsym;
539534
tccelf.c+23−53
@@ -581,7 +581,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 580 unmodified lines
581581 break;
582582 case R_386_GOT32:
583583 /* we load the got offset */
584− *(int *)ptr += s1->sym_infos[sym_index].got_offset << 1;
584+ *(int *)ptr += s1->got_offsets[sym_index];
585585 break;
586586 case R_386_16:
587587 if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {
@@ -760,7 +760,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 172 unmodified lines
760760 break;
761761 case R_ARM_GOT_BREL:
762762 /* we load the got offset */
763− *(int *)ptr += s1->sym_infos[sym_index].got_offset << 1;
763+ *(int *)ptr += s1->got_offsets[sym_index];
764764 break;
765765 case R_ARM_COPY:
766766 break;
@@ -866,14 +866,14 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 99 unmodified lines
866866 }
867867 #endif
868868 *(int *)ptr += (s1->got->sh_addr - addr +
869− (s1->sym_infos[sym_index].got_offset << 1) - 4);
869+ s1->got_offsets[sym_index] - 4);
870870 break;
871871 case R_X86_64_GOTTPOFF:
872872 *(int *)ptr += val - s1->got->sh_addr;
873873 break;
874874 case R_X86_64_GOT32:
875875 /* we load the got offset */
876− *(int *)ptr += s1->sym_infos[sym_index].got_offset << 1;
876+ *(int *)ptr += s1->got_offsets[sym_index];
877877 break;
878878 #else
879879 #error unsupported processor
@@ -943,36 +943,23 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr) · 63 unmodified lines
943943 return count;
944944 }
945945
946−static void put_sym_info(TCCState *s1, int index)
946+static void put_got_offset(TCCState *s1, int index, unsigned long val)
947947 {
948948 int n;
949− typeof(s1->sym_infos) tab;
949+ unsigned long *tab;
950950
951− if (index >= s1->nb_sym_infos) {
951+ if (index >= s1->nb_got_offsets) {
952952 /* find immediately bigger power of 2 and reallocate array */
953953 n = 1;
954954 while (index >= n)
955955 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;
961961 }
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;
976963 }
977964
978965 /* XXX: suppress that */
@@ -1036,8 +1023,8 @@ static void put_got_entry(TCCState *s1, · 57 unmodified lines
10361023 build_got(s1);
10371024
10381025 /* 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)
10411028 return;
10421029
10431030 put_got_offset(s1, sym_index, s1->got->data_offset);
@@ -1117,13 +1104,10 @@ static void put_got_entry(TCCState *s1, · 73 unmodified lines
11171104 put32(p + 12, 0xe5bef008);
11181105 }
11191106
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;
11271111 put32(p , 0xe59fc004); // ldr ip, [pc, #4] // offset in GOT
11281112 put32(p+4, 0xe08fc00c); // add ip, pc, ip // absolute address or offset
11291113 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
15101494 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
15111495 unsigned long offset;
15121496
1513− if (sym_index >= s1->nb_sym_infos)
1497+ if (sym_index >= s1->nb_got_offsets)
15141498 return;
1515− offset = s1->sym_infos[sym_index].got_offset << 1;
1499+ offset = s1->got_offsets[sym_index];
15161500 section_reserve(s1->got, offset + PTR_SIZE);
15171501 #ifdef TCC_TARGET_X86_64
15181502 /* only works for x86-64 */
@@ -2086,8 +2070,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 567 unmodified lines
20862070 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
20872071 p += 16;
20882072 while (p < p_end) {
2089− if (get32(p) == 0x46c04778) /* PLT Thumb stub present */
2090− p += 4;
2073+ p += 4;
20912074 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
20922075 p += 16;
20932076 }
@@ -2321,7 +2304,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 227 unmodified lines
23212304 tcc_free(s1->symtab_to_dynsym);
23222305 tcc_free(section_order);
23232306 tcc_free(phdr);
2324− tcc_free(s1->sym_infos);
2307+ tcc_free(s1->got_offsets);
23252308 return ret;
23262309 }
23272310
@@ -2616,19 +2599,6 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 288 unmodified lines
26162599 rel->r_info = ELFW(R_INFO)(sym_index, type);
26172600 /* offset the relocation offset */
26182601 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
26322602 }
26332603 break;
26342604 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