From 830b7533c99f86203c4fbaf94897679678c3bad0 Mon Sep 17 00:00:00 2001 From: Shinichiro Hamaji Date: Mon, 13 Apr 2009 00:27:04 +0900 Subject: Generate PIC code so that we can create shared objects properly. - Add got_table in TCCState. This approach is naive and the distance between executable code and GOT can be longer than 32bit. - Handle R_X86_64_GOTPCREL properly. We use got_table for TCC_OUTPUT_MEMORY case for now. - Fix load() and store() so that they access global variables via GOT. --- tccelf.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'tccelf.c') diff --git a/tccelf.c b/tccelf.c index 093f18d..56ee75a 100644 --- a/tccelf.c +++ b/tccelf.c @@ -502,6 +502,25 @@ static unsigned long add_jmp_table(TCCState *s1, unsigned long val) *(unsigned long *)(p + 6) = val; return (unsigned long)p; } + +#define GOT_TABLE_ENTRY_MAX_NUM 4096 +static unsigned long add_got_table(TCCState *s1, unsigned long val) +{ + unsigned long *p; + if (!s1->got_table) { + int size = sizeof(void *) * GOT_TABLE_ENTRY_MAX_NUM; + s1->got_table_num = 0; + s1->got_table = (char *)tcc_malloc(size); + } + if (s1->got_table_num == GOT_TABLE_ENTRY_MAX_NUM) { + error("relocating >%d symbols are not supported", + GOT_TABLE_ENTRY_MAX_NUM); + } + p = s1->got_table + s1->got_table_num; + s1->got_table_num++; + *p = val; + return (unsigned long)p; +} #endif /* relocate a given section (CPU dependent) */ @@ -727,11 +746,13 @@ static void relocate_section(TCCState *s1, Section *s) *(int *)ptr = val; break; case R_X86_64_GOTPCREL: - *(int *)ptr += s1->got->sh_addr - addr; - /* XXX: is this OK? */ - if (s1->output_type == TCC_OUTPUT_DLL) { - *(int *)ptr += s1->got_offsets[sym_index] - 4; + if (s1->output_type == TCC_OUTPUT_MEMORY) { + val = add_got_table(s1, val - rel->r_addend) + rel->r_addend; + *(int *)ptr += val - addr; + break; } + *(int *)ptr += (s1->got->sh_addr - addr + + s1->got_offsets[sym_index] - 4); break; case R_X86_64_GOTTPOFF: *(int *)ptr += val - s1->got->sh_addr; -- cgit v1.3.1