Size of the extra buffer is too large for now.
Unified · Split
| @@ -545,6 +545,12 @@ struct TCCState { · 544 unmodified lines | |||
| 545 | 545 | ||
| 546 | /* for tcc_relocate */ | 546 | /* for tcc_relocate */ |
| 547 | int runtime_added; | 547 | int runtime_added; |
| 548 | |||
| 549 | #ifdef TCC_TARGET_X86_64 | ||
| 550 | /* write PLT and GOT here */ | ||
| 551 | char *runtime_plt_and_got; | ||
| 552 | unsigned int runtime_plt_and_got_offset; | ||
| 553 | #endif | ||
| 548 | }; | 554 | }; |
| 549 | 555 | ||
| 550 | /* The current value can be: */ | 556 | /* The current value can be: */ |
| @@ -1311,12 +1317,7 @@ Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags) · 760 unmodified lines | |||
| 1311 | 1317 | ||
| 1312 | static void free_section(Section *s) | 1318 | static void free_section(Section *s) |
| 1313 | { | 1319 | { |
| 1314 | #ifdef TCC_TARGET_X86_64 | 1320 | tcc_free(s->data); |
| 1315 | /* after tcc_relocate(), some sections share the data buffer. | ||
| 1316 | let's check if the data is allocated not to free the shared buffers */ | ||
| 1317 | if (s->data_allocated) | ||
| 1318 | #endif | ||
| 1319 | tcc_free(s->data); | ||
| 1320 | } | 1321 | } |
| 1321 | 1322 | ||
| 1322 | /* realloc section and set its content to zero */ | 1323 | /* realloc section and set its content to zero */ |
| @@ -10327,14 +10328,22 @@ int tcc_relocate(TCCState *s1, void *ptr) · 9004 unmodified lines | |||
| 10327 | offset = (offset + length + 15) & ~15; | 10328 | offset = (offset + length + 15) & ~15; |
| 10328 | } | 10329 | } |
| 10329 | 10330 | ||
| 10331 | #ifdef TCC_TARGET_X86_64 | ||
| 10332 | s1->runtime_plt_and_got_offset = 0; | ||
| 10333 | s1->runtime_plt_and_got = (char *)(mem + offset); | ||
| 10334 | /* double the size of the buffer for got and plt entries | ||
| 10335 | XXX: calculate exact size for them? */ | ||
| 10336 | offset *= 2; | ||
| 10337 | #endif | ||
| 10338 | |||
| 10339 | if (0 == mem) | ||
| 10340 | return offset + 15; | ||
| 10341 | |||
| 10330 | /* relocate symbols */ | 10342 | /* relocate symbols */ |
| 10331 | relocate_syms(s1, 1); | 10343 | relocate_syms(s1, 1); |
| 10332 | if (s1->nb_errors) | 10344 | if (s1->nb_errors) |
| 10333 | return -1; | 10345 | return -1; |
| 10334 | 10346 | ||
| 10335 | if (0 == mem) | ||
| 10336 | return offset + 15; | ||
| 10337 | |||
| 10338 | /* relocate each section */ | 10347 | /* relocate each section */ |
| 10339 | for(i = 1; i < s1->nb_sections; i++) { | 10348 | for(i = 1; i < s1->nb_sections; i++) { |
| 10340 | s = s1->sections[i]; | 10349 | s = s1->sections[i]; |
| @@ -10357,6 +10366,10 @@ int tcc_relocate(TCCState *s1, void *ptr) · 16 unmodified lines | |||
| 10357 | if (s->sh_flags & SHF_EXECINSTR) | 10366 | if (s->sh_flags & SHF_EXECINSTR) |
| 10358 | set_pages_executable(ptr, length); | 10367 | set_pages_executable(ptr, length); |
| 10359 | } | 10368 | } |
| 10369 | #ifdef TCC_TARGET_X86_64 | ||
| 10370 | set_pages_executable(s1->runtime_plt_and_got, | ||
| 10371 | s1->runtime_plt_and_got_offset); | ||
| 10372 | #endif | ||
| 10360 | return 0; | 10373 | return 0; |
| 10361 | } | 10374 | } |
| 10362 | 10375 | ||
| @@ -480,7 +480,8 @@ static void relocate_syms(TCCState *s1, int do_resolve) · 479 unmodified lines | |||
| 480 | #define JMP_TABLE_ENTRY_SIZE 14 | 480 | #define JMP_TABLE_ENTRY_SIZE 14 |
| 481 | static unsigned long add_jmp_table(TCCState *s1, unsigned long val) | 481 | static unsigned long add_jmp_table(TCCState *s1, unsigned long val) |
| 482 | { | 482 | { |
| 483 | char *p = (char *)section_ptr_add(text_section, JMP_TABLE_ENTRY_SIZE); | 483 | char *p = s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset; |
| 484 | s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE; | ||
| 484 | /* jmp *0x0(%rip) */ | 485 | /* jmp *0x0(%rip) */ |
| 485 | p[0] = 0xff; | 486 | p[0] = 0xff; |
| 486 | p[1] = 0x25; | 487 | p[1] = 0x25; |
| @@ -491,8 +492,9 @@ static unsigned long add_jmp_table(TCCState *s1, unsigned long val) · 4 unmodified lines | |||
| 491 | 492 | ||
| 492 | static unsigned long add_got_table(TCCState *s1, unsigned long val) | 493 | static unsigned long add_got_table(TCCState *s1, unsigned long val) |
| 493 | { | 494 | { |
| 494 | unsigned long *p = | 495 | unsigned long *p =(unsigned long *)(s1->runtime_plt_and_got + |
| 495 | (unsigned long *)section_ptr_add(text_section, sizeof(void *)); | 496 | s1->runtime_plt_and_got_offset); |
| 497 | s1->runtime_plt_and_got_offset += sizeof(void *); | ||
| 496 | *p = val; | 498 | *p = val; |
| 497 | return (unsigned long)p; | 499 | return (unsigned long)p; |
| 498 | } | 500 | } |