Size of the extra buffer is too large for now.
Unified · Split
| @@ -545,6 +545,12 @@ struct TCCState { · 544 unmodified lines | ||
| 545 | 545 | |
| 546 | 546 | /* for tcc_relocate */ |
| 547 | 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 | 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 | 1318 | static void free_section(Section *s) |
| 1313 | 1319 | { |
| 1314 | −#ifdef TCC_TARGET_X86_64 | |
| 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 | + tcc_free(s->data); | |
| 1320 | 1321 | } |
| 1321 | 1322 | |
| 1322 | 1323 | /* realloc section and set its content to zero */ |
| @@ -10327,14 +10328,22 @@ int tcc_relocate(TCCState *s1, void *ptr) · 9004 unmodified lines | ||
| 10327 | 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 | 10342 | /* relocate symbols */ |
| 10331 | 10343 | relocate_syms(s1, 1); |
| 10332 | 10344 | if (s1->nb_errors) |
| 10333 | 10345 | return -1; |
| 10334 | 10346 | |
| 10335 | − if (0 == mem) | |
| 10336 | − return offset + 15; | |
| 10337 | − | |
| 10338 | 10347 | /* relocate each section */ |
| 10339 | 10348 | for(i = 1; i < s1->nb_sections; i++) { |
| 10340 | 10349 | s = s1->sections[i]; |
| @@ -10357,6 +10366,10 @@ int tcc_relocate(TCCState *s1, void *ptr) · 16 unmodified lines | ||
| 10357 | 10366 | if (s->sh_flags & SHF_EXECINSTR) |
| 10358 | 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 | 10373 | return 0; |
| 10361 | 10374 | } |
| 10362 | 10375 | |
| @@ -480,7 +480,8 @@ static void relocate_syms(TCCState *s1, int do_resolve) · 479 unmodified lines | ||
| 480 | 480 | #define JMP_TABLE_ENTRY_SIZE 14 |
| 481 | 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 | 485 | /* jmp *0x0(%rip) */ |
| 485 | 486 | p[0] = 0xff; |
| 486 | 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 | 493 | static unsigned long add_got_table(TCCState *s1, unsigned long val) |
| 493 | 494 | { |
| 494 | − unsigned long *p = | |
| 495 | − (unsigned long *)section_ptr_add(text_section, sizeof(void *)); | |
| 495 | + unsigned long *p =(unsigned long *)(s1->runtime_plt_and_got + | |
| 496 | + s1->runtime_plt_and_got_offset); | |
| 497 | + s1->runtime_plt_and_got_offset += sizeof(void *); | |
| 496 | 498 | *p = val; |
| 497 | 499 | return (unsigned long)p; |
| 498 | 500 | } |