diff options
Diffstat (limited to 'tcc.c')
| -rw-r--r-- | tcc.c | 31 |
1 files changed, 22 insertions, 9 deletions
@@ -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; } |
