Okay, so I thought everything was good, but it turns out one of the real issues was adding mixing object files and compilations into one tcc state, something my unit tests didn't cover. So here's a dump of the RUNTIME_FUNCTION array passed to RtlAddFunctionTable, where I compiled some stuff using *tcc_compile_string* and *tcc_add_file("someobject.o")*:
*syntax: (image base + rf[i].BeginAddress) -> image base + rf[i].BeginAddress .. rf[i].EndAddress (uwinfo @ rf[i].UnwindData)* RF[0]: 0x0000000008830AD3 -> 0x0000000008830AC8 + 0xB .. 0x42 (uwinfo @ 0x44) RF[1] : 0x0000000008830B1F -> 0x0000000008830AC8 + 0x57 .. 0x164 (uwinfo @ 0x44) RF[2] : 0x0000000008830C37 -> 0x0000000008830AC8 + 0x16F .. 0x18C (uwinfo @ 0x44) RF[3] : 0x0000000008830C5F -> 0x0000000008830AC8 + 0x197 .. 0x1B4 (uwinfo @ 0x44) RF[4] : 0x0000000008830C87 -> 0x0000000008830AC8 + 0x1BF .. 0x33E (uwinfo @ 0x44) RF[5] : 0x0000000008830E11 -> 0x0000000008830AC8 + 0x349 .. 0x4A0 (uwinfo @ 0x44) RF[6] : 0x0000000008830F73 -> 0x0000000008830AC8 + 0x4AB .. 0x519 (uwinfo @ 0x44) RF[7] : 0x0000000008830FEC -> 0x0000000008830AC8 + 0x524 .. 0x5C3 (uwinfo @ 0x44) RF[8] : 0x0000000008831096 -> 0x0000000008830AC8 + 0x5CE .. 0x620 (uwinfo @ 0x44) RF[9] : 0x00000000088310F3 -> 0x0000000008830AC8 + 0x62B .. 0x645 (uwinfo @ 0x44) RF[10] : 0x0000000008831118 -> 0x0000000008830AC8 + 0x650 .. 0x672 (uwinfo @ 0x44) RF[11] : 0x0000000008831145 -> 0x0000000008830AC8 + 0x67D .. 0x693 (uwinfo @ 0x44) RF[12] : 0x0000000008831166 -> 0x0000000008830AC8 + 0x69E .. 0x6B4 (uwinfo @ 0x44) RF[13] : 0x0000000008831187 -> 0x0000000008830AC8 + 0x6BF .. 0x708 (uwinfo @ 0x44) RF[14] : 0x0000000008830AD3 -> 0x0000000008830AC8 + 0xB .. 0x42 (uwinfo @ 0x44) RF[15] : 0x0000000008830B1F -> 0x0000000008830AC8 + 0x57 .. 0x68 (uwinfo @ 0x44) RF[16] : 0x0000000008830B3B -> 0x0000000008830AC8 + 0x73 .. 0x7C (uwinfo @ 0x44) RF[17] : 0x0000000008830B4F -> 0x0000000008830AC8 + 0x87 .. 0x14E (uwinfo @ 0x44) RF[18] : 0x0000000008830C21 -> 0x0000000008830AC8 + 0x159 .. 0x1E8 (uwinfo @ 0x44) RF[19] : 0x0000000008830CBB -> 0x0000000008830AC8 + 0x1F3 .. 0x26E (uwinfo @ 0x44) RF[20] : 0x0000000008830D41 -> 0x0000000008830AC8 + 0x279 .. 0x29D (uwinfo @ 0x44) RF[21] : 0x0000000008830D70 -> 0x0000000008830AC8 + 0x2A8 .. 0x2BD (uwinfo @ 0x44) RF[22] : 0x0000000008830D90 -> 0x0000000008830AC8 + 0x2C8 .. 0x384 (uwinfo @ 0x44) RF[23] : 0x0000000008830E57 -> 0x0000000008830AC8 + 0x38F .. 0x452 (uwinfo @ 0x44) RF[24] : 0x0000000008830F25 -> 0x0000000008830AC8 + 0x45D .. 0x4F7 (uwinfo @ 0x44) RF[25] : 0x0000000008830FCA -> 0x0000000008830AC8 + 0x502 .. 0x5AA (uwinfo @ 0x44) RF[26] : 0x000000000883107D -> 0x0000000008830AC8 + 0x5B5 .. 0x607 (uwinfo @ 0x44) RF[27] : 0x00000000088310DA -> 0x0000000008830AC8 + 0x612 .. 0x62C (uwinfo @ 0x44) RF[28] : 0x00000000088310FF -> 0x0000000008830AC8 + 0x637 .. 0x659 (uwinfo @ 0x44) RF[29] : 0x000000000883112C -> 0x0000000008830AC8 + 0x664 .. 0x67A (uwinfo @ 0x44) RF[30] : 0x000000000883114D -> 0x0000000008830AC8 + 0x685 .. 0x69B (uwinfo @ 0x44) RF[31] : 0x0000000008831876 -> 0x0000000008830AC8 + 0xDAE .. 0xDEF (uwinfo @ 0x44) RF[32] : 0x00000000088318C2 -> 0x0000000008830AC8 + 0xDFA .. 0xE3B (uwinfo @ 0x44) As can be seen, from runtime function 14, the function entries start to overlap again. Probably, there's a missing segment/section offset somewhere when TCC adds runtime functions from different contexts/sections/object files? However, I'm having a hard time discovering where exactly object files are added to the *TCCState.uw_pdata *(it is *not* done through *pe_add_unwind_data*). Any ideas? Regards, Janus 2017-11-03 2:11 GMT+01:00 Janus Lynggaard Thorborg <janus.thorb...@gmail.com >: > Thanks a lot grischka for the swift fix, it seems to work. I'll test some > more and push it if all is good. > > 2017-11-02 12:29 GMT+01:00 grischka <gris...@gmx.de>: > >> Janus Lynggaard Thorborg wrote: >> >>> However, there's a bug somewhere. When you relocate the code, >>> *win64_add_function_table >>> *is called to register all the generated function tables. This calls >>> *RtlAddFunctionTable*(table, ...) whose first argument is an array of >>> function entries. TCC passes *s1->uw_pdata->sh_addr *as the function >>> array, >>> but this memory location is just full of 0xCDCDCDCD (on windows, this is >>> the signature of uninitialized memory). >>> >> >> Hm. Probably we should call RtlAddFunctionTable _AFTER_ the tabble has >> been copied to memory actually rather than before. I think originally >> it was so but then was "unfixed" at some point (by myself). >> >> You could try the patch below. (Note that (void**)ptr is replaced >> by *(void**)mem) >> >> It it works you might push it on mob, also: >> http://repo.or.cz/w/tinycc.git >> >> >> -- gr >> >> ----------------------------------- tccrun.c >> ----------------------------------- >> index b9a052b..eded0a3 100644 >> @@ -247,10 +247,6 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr, >> addr_t ptr_diff) >> } >> relocate_plt(s1); >> >> -#ifdef _WIN64 >> - *(void**)ptr = win64_add_function_table(s1); >> -#endif >> - >> for(i = 1; i < s1->nb_sections; i++) { >> s = s1->sections[i]; >> if (0 == (s->sh_flags & SHF_ALLOC)) >> @@ -267,7 +263,12 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr, >> addr_t ptr_diff) >> if (s->sh_flags & SHF_EXECINSTR) >> set_pages_executable((char*)ptr + ptr_diff, length); >> } >> + >> +#ifdef _WIN64 >> + *(void**)mem = win64_add_function_table(s1); >> +#endif >> return 0; >> + >> } >> >> /* ------------------------------------------------------------- */ >> >> So there's something fishy about how *pe_add_unwind_data *stores this >>> >>> table. I noticed this for loop: >>> >>> /* record this function */ >>> p->BeginAddress = start; >>> p->EndAddress = end; >>> p->UnwindData = d; >>> >>> /* put relocations on it */ >>> for (n = o + sizeof *p; o < n; o += sizeof p->BeginAddress) >>> put_elf_reloc(symtab_section, pd, o, R_X86_64_RELATIVE, >>> s1->uw_sym); >>> >>> I'm new to actually messing around with TCC code, so I won't claim to >>> know >>> exactly what is going on. But it seems weird that it wants to relocate >>> the >>> runtime function table, as it is just an array of offsets relative to the >>> relocated image. >>> >>> Here's a minimal test I threw together (compile with msvc x64): >>> >>> typedef int(*Callback)(int arg); >>> typedef int(*CallbackCaller)(Callback, int); >>> >>> int callback(int arg) >>> { >>> return 10 / arg; >>> } >>> >>> void test() >>> { >>> const char * program = "int callback(int (* cb)(int), int arg) { return >>> cb(arg); }"; >>> >>> TCCState * tcc = tcc_new(); >>> tcc_set_lib_path(tcc, /* ... */); >>> tcc_set_output_type(tcc, TCC_OUTPUT_MEMORY); >>> tcc_compile_string(tcc, program); >>> tcc_relocate(tcc, TCC_RELOCATE_AUTO); >>> >>> CallbackCaller cbi = (CallbackCaller) tcc_get_symbol(tcc, "callback"); >>> >>> cbi(callback, 1); >>> >>> int exception_caught = 0; >>> >>> __try >>> { >>> cbi(callback, 0); >>> } >>> __except(1) >>> { >>> exception_caught = 1; >>> } >>> >>> assert(exception_caught == 1); >>> } >>> >>> *Also, if I directly pass the 'p' pointer above from >>> **pe_add_unwind_data** into >>> **RtlAddFunctionTable **(by hacking some stuff), everything works as it >>> should and the test passes.* >>> >>> So I wouldn't mind fixing this, but if anyone (especially grischka) could >>> shed some basic light upon the coding decisions and/or give some pointers >>> (or maybe knows exactly what is wrong), I would be thankful. >>> >>> Regards, Janus >>> >>> >>> >>> ------------------------------------------------------------------------ >>> >>> _______________________________________________ >>> Tinycc-devel mailing list >>> Tinycc-devel@nongnu.org >>> https://lists.nongnu.org/mailman/listinfo/tinycc-devel >>> >> >> >> >> _______________________________________________ >> Tinycc-devel mailing list >> Tinycc-devel@nongnu.org >> https://lists.nongnu.org/mailman/listinfo/tinycc-devel >> > >
_______________________________________________ Tinycc-devel mailing list Tinycc-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/tinycc-devel