From 1af3bca4eae32e172a422fd3046246c5662078c3 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Mon, 12 Nov 2012 23:14:21 +0100 Subject: [PATCH] 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. --- tcc.h | 11 +++------- tccelf.c | 76 ++++++++++++++++++++-------------------------------------------- 2 files changed, 26 insertions(+), 61 deletions(-) diff --git a/tcc.h b/tcc.h index fd4e8da4..4e88782c 100644 --- a/tcc.h +++ b/tcc.h @@ -33,7 +33,6 @@ #include #include -#include #include #include #include @@ -525,15 +524,11 @@ struct TCCState { Section **priv_sections; int nb_priv_sections; /* number of private sections */ - /* got & plt handling */ + /* got handling */ Section *got; Section *plt; - struct { - unsigned long plt_thumb_stub:1; - /* mult by 2 (or left shift by 1) before use */ - unsigned long got_offset:(sizeof(long)*CHAR_BIT-1); - } *sym_infos; - int nb_sym_infos; + unsigned long *got_offsets; + int nb_got_offsets; /* give the correspondance from symtab indexes to dynsym indexes */ int *symtab_to_dynsym; diff --git a/tccelf.c b/tccelf.c index a2559eec..c5690dd4 100644 --- a/tccelf.c +++ b/tccelf.c @@ -581,7 +581,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) break; case R_386_GOT32: /* we load the got offset */ - *(int *)ptr += s1->sym_infos[sym_index].got_offset << 1; + *(int *)ptr += s1->got_offsets[sym_index]; break; case R_386_16: if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) { @@ -760,7 +760,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) break; case R_ARM_GOT_BREL: /* we load the got offset */ - *(int *)ptr += s1->sym_infos[sym_index].got_offset << 1; + *(int *)ptr += s1->got_offsets[sym_index]; break; case R_ARM_COPY: break; @@ -866,14 +866,14 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) } #endif *(int *)ptr += (s1->got->sh_addr - addr + - (s1->sym_infos[sym_index].got_offset << 1) - 4); + s1->got_offsets[sym_index] - 4); break; case R_X86_64_GOTTPOFF: *(int *)ptr += val - s1->got->sh_addr; break; case R_X86_64_GOT32: /* we load the got offset */ - *(int *)ptr += s1->sym_infos[sym_index].got_offset << 1; + *(int *)ptr += s1->got_offsets[sym_index]; break; #else #error unsupported processor @@ -943,36 +943,23 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr) return count; } -static void put_sym_info(TCCState *s1, int index) +static void put_got_offset(TCCState *s1, int index, unsigned long val) { int n; - typeof(s1->sym_infos) tab; + unsigned long *tab; - if (index >= s1->nb_sym_infos) { + if (index >= s1->nb_got_offsets) { /* find immediately bigger power of 2 and reallocate array */ n = 1; while (index >= n) n *= 2; - tab = tcc_realloc(s1->sym_infos, n * sizeof(unsigned long)); - s1->sym_infos = tab; - memset(s1->sym_infos + s1->nb_sym_infos, 0, - (n - s1->nb_sym_infos) * sizeof(unsigned long)); - s1->nb_sym_infos = n; + tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long)); + s1->got_offsets = tab; + memset(s1->got_offsets + s1->nb_got_offsets, 0, + (n - s1->nb_got_offsets) * sizeof(unsigned long)); + s1->nb_got_offsets = n; } -} - -#ifdef TCC_TARGET_ARM -static void put_plt_thumb_stub(TCCState *s1, int index, unsigned char bit) -{ - put_sym_info(s1, index); - s1->sym_infos[index].plt_thumb_stub = bit; -} -#endif - -static void put_got_offset(TCCState *s1, int index, unsigned long val) -{ - put_sym_info(s1, index); - s1->sym_infos[index].got_offset = val >> 1; + s1->got_offsets[index] = val; } /* XXX: suppress that */ @@ -1036,8 +1023,8 @@ static void put_got_entry(TCCState *s1, build_got(s1); /* if a got entry already exists for that symbol, no need to add one */ - if (sym_index < s1->nb_sym_infos && - s1->sym_infos[sym_index].got_offset << 1) + if (sym_index < s1->nb_got_offsets && + s1->got_offsets[sym_index] != 0) return; put_got_offset(s1, sym_index, s1->got->data_offset); @@ -1117,13 +1104,10 @@ static void put_got_entry(TCCState *s1, put32(p + 12, 0xe5bef008); } - if (s1->sym_infos[sym_index].plt_thumb_stub) { - p = section_ptr_add(plt, 20); - put32(p , 0x4778); // bx pc - put32(p+2, 0x46c0); // nop - p += 4; - } else - p = section_ptr_add(plt, 16); + p = section_ptr_add(plt, 20); + put32(p , 0x4778); // bx pc + put32(p+2, 0x46c0); // nop + p += 4; put32(p , 0xe59fc004); // ldr ip, [pc, #4] // offset in GOT put32(p+4, 0xe08fc00c); // add ip, pc, ip // absolute address or offset 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) ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index]; unsigned long offset; - if (sym_index >= s1->nb_sym_infos) + if (sym_index >= s1->nb_got_offsets) return; - offset = s1->sym_infos[sym_index].got_offset << 1; + offset = s1->got_offsets[sym_index]; section_reserve(s1->got, offset + PTR_SIZE); #ifdef TCC_TARGET_X86_64 /* only works for x86-64 */ @@ -2086,8 +2070,7 @@ static int elf_output_file(TCCState *s1, const char *filename) x=s1->got->sh_addr - s1->plt->sh_addr - 12; p += 16; while (p < p_end) { - if (get32(p) == 0x46c04778) /* PLT Thumb stub present */ - p += 4; + p += 4; put32(p + 12, x + get32(p + 12) + s1->plt->data - p); p += 16; } @@ -2321,7 +2304,7 @@ static int elf_output_file(TCCState *s1, const char *filename) tcc_free(s1->symtab_to_dynsym); tcc_free(section_order); tcc_free(phdr); - tcc_free(s1->sym_infos); + tcc_free(s1->got_offsets); return ret; } @@ -2616,19 +2599,6 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, rel->r_info = ELFW(R_INFO)(sym_index, type); /* offset the relocation offset */ rel->r_offset += offseti; -#ifdef TCC_TARGET_ARM - /* Jumps and branches from a Thumb code to a PLT entry need - special handling since PLT entries are ARM code. - Unconditional bl instructions referencing PLT entries are - handled by converting these instructions into blx - instructions. Other case of instructions referencing a PLT - entry require to add a Thumb stub before the PLT entry to - switch to ARM mode. We set bit 0 of the got offset of a - symbol to indicate such a case. */ - if (type == R_ARM_THM_JUMP24) { - put_plt_thumb_stub(s1, sym_index, 1); - } -#endif } break; default: -- 2.11.4.GIT