Hi,
This seems to be the issue causing SQLite compilation to fail (or at least
part of it/related to it).
When a function pointer is declared in a particular way, it seems that
__stdcall (and presumably other attributes?) are ignored. As a result, TCC
thinks the function is caller-cleanup when it is not, and the stack gets
"cleaned" twice.
See the full test case attached. As a quick summary,
This works:
((int __stdcall (*)(int, int, int))some_stdcall_func) (2, 0, 0);
And so does this:
((int(*__stdcall)(int, int, int))some_stdcall_func) (3, 0, 0);
But this fails:
((int(__stdcall*)(int, int, int))some_stdcall_func) (4, 0, 0);
This is mostly relevant on 32-bit Windows (where the stdcall convention is
common).
// tcc -m32 minimal.c
#include <stdio.h>
void printf_stack_pointer(int ln) {
unsigned int i;
asm("\t movl %%esp,%0" : "=r"(i));
printf("At line %i, SP is %u\n", ln, i);
}
#define PRINTF_STACK_POINTER printf_stack_pointer(__LINE__);
__stdcall int some_stdcall_func(int foo, int bar, int baz) {
printf("Hello from stdcall: %i\n", foo);
return 12;
}
int main() {
PRINTF_STACK_POINTER
// Baseline stack pointer for comparison.
some_stdcall_func(1, 0, 0);
PRINTF_STACK_POINTER
// No problem. Stack pointer is unchanged, as it should be.
((int __stdcall (*)(int, int, int))some_stdcall_func) (2, 0, 0);
PRINTF_STACK_POINTER
// Still no problem.
((int(*__stdcall)(int, int, int))some_stdcall_func) (3, 0, 0);
PRINTF_STACK_POINTER
// Still no problem.
((int(__stdcall*)(int, int, int))some_stdcall_func) (4, 0, 0);
PRINTF_STACK_POINTER
// Problem! Notice that SP is now 12 ( e.g. sizeof(int)*3 ) bytes
higher.
// My guess: For whatever reason TCC thinks this is a cdecl function
// (caller-cleanup) and has generated code to recover the stack.
// Of course, since the function is actually callee-cleanup, it has
already
// did that. The stack has been "cleaned" twice and is now sizeof(args)
too high.
// Seems to happen when the calling convention attribute is inside the
brackets
// AND before the asterisk.
}_______________________________________________
Tinycc-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/tinycc-devel