tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Tinycc-devel] Win64 PE JIT codegen: Bad unwind info / runtime funct


From: Janus Lynggaard Thorborg
Subject: Re: [Tinycc-devel] Win64 PE JIT codegen: Bad unwind info / runtime function tables
Date: Sun, 5 Nov 2017 16:15:53 +0100

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 <address@hidden>:
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 <address@hidden>:
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
address@hidden
https://lists.nongnu.org/mailman/listinfo/tinycc-devel



_______________________________________________
Tinycc-devel mailing list
address@hidden
https://lists.nongnu.org/mailman/listinfo/tinycc-devel



reply via email to

[Prev in Thread] Current Thread [Next in Thread]