From 9a7173bf69cc1e620f33e2d08550a70d31674a0f Mon Sep 17 00:00:00 2001 From: Shinichiro Hamaji Date: Fri, 17 Apr 2009 10:17:14 +0900 Subject: [PATCH] x86-64: Fix tcc -run. We need extra memory for PLT and GOT. Size of the extra buffer is too large for now. --- tcc.c | 31 ++++++++++++++++++++++--------- tccelf.c | 8 +++++--- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/tcc.c b/tcc.c index acff2e4c..3a0f7257 100644 --- a/tcc.c +++ b/tcc.c @@ -545,6 +545,12 @@ struct TCCState { /* for tcc_relocate */ int runtime_added; + +#ifdef TCC_TARGET_X86_64 + /* write PLT and GOT here */ + char *runtime_plt_and_got; + unsigned int runtime_plt_and_got_offset; +#endif }; /* The current value can be: */ @@ -1311,12 +1317,7 @@ Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags) static void free_section(Section *s) { -#ifdef TCC_TARGET_X86_64 - /* after tcc_relocate(), some sections share the data buffer. - let's check if the data is allocated not to free the shared buffers */ - if (s->data_allocated) -#endif - tcc_free(s->data); + tcc_free(s->data); } /* realloc section and set its content to zero */ @@ -10327,14 +10328,22 @@ int tcc_relocate(TCCState *s1, void *ptr) offset = (offset + length + 15) & ~15; } +#ifdef TCC_TARGET_X86_64 + s1->runtime_plt_and_got_offset = 0; + s1->runtime_plt_and_got = (char *)(mem + offset); + /* double the size of the buffer for got and plt entries + XXX: calculate exact size for them? */ + offset *= 2; +#endif + + if (0 == mem) + return offset + 15; + /* relocate symbols */ relocate_syms(s1, 1); if (s1->nb_errors) return -1; - if (0 == mem) - return offset + 15; - /* relocate each section */ for(i = 1; i < s1->nb_sections; i++) { s = s1->sections[i]; @@ -10357,6 +10366,10 @@ int tcc_relocate(TCCState *s1, void *ptr) if (s->sh_flags & SHF_EXECINSTR) set_pages_executable(ptr, length); } +#ifdef TCC_TARGET_X86_64 + set_pages_executable(s1->runtime_plt_and_got, + s1->runtime_plt_and_got_offset); +#endif return 0; } diff --git a/tccelf.c b/tccelf.c index 6a26831b..11bb82c7 100644 --- a/tccelf.c +++ b/tccelf.c @@ -480,7 +480,8 @@ static void relocate_syms(TCCState *s1, int do_resolve) #define JMP_TABLE_ENTRY_SIZE 14 static unsigned long add_jmp_table(TCCState *s1, unsigned long val) { - char *p = (char *)section_ptr_add(text_section, JMP_TABLE_ENTRY_SIZE); + char *p = s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset; + s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE; /* jmp *0x0(%rip) */ p[0] = 0xff; p[1] = 0x25; @@ -491,8 +492,9 @@ static unsigned long add_jmp_table(TCCState *s1, unsigned long val) static unsigned long add_got_table(TCCState *s1, unsigned long val) { - unsigned long *p = - (unsigned long *)section_ptr_add(text_section, sizeof(void *)); + unsigned long *p =(unsigned long *)(s1->runtime_plt_and_got + + s1->runtime_plt_and_got_offset); + s1->runtime_plt_and_got_offset += sizeof(void *); *p = val; return (unsigned long)p; } -- 2.11.4.GIT