2009/8/21 Juan Lang juan.lang@gmail.com:
Personally, I don't think the cut-and-paste approach we've been taking to fix this works all that well for a 126-argument function, so it seems like an assembly approach is the only tenable method. I'm not certain whether Jon's approach is the correct one, but since it didn't get any comment before, I'd like to know: if it isn't acceptable, why not?
I don't know if there's a reason the general approach couldn't work, but the code in the patch is gcc specific, so I think it should at least be protected by __GNUC__ in addition to __i386__. This won't work on OS X either, it requires 16 byte alignment for the stack. Also:
"subl %eax, %esp\n\t" \
...
"0:\n\t" \
"pushl (%ecx, %eax)\n\t" \
"subl $4, %eax\n\t" \
"jns 0b\n\t" \
...
"leal (%esp, %ecx, " #pop_size "), %esp\n\t" \
This look like a somewhat questionable way to handle both cdecl and stdcall with the same code to me.
You should probably look at call_entry_point() in dlls/ntdll/relay.c for an example, although I also guess an argument could be made that something like this should be in libwine. (That would probably break functions that check their return address, not sure if that's an issue here.)