I still haven't been able to figure out why this isn't working.
I worked around it using a custom implementation of setjmp/longjmp from
here.
https://github.com/GlinkieGamesInc/longjmp_win64
But, it'd be much nicer if the built-in function worked correctly. If
anyone has any idea why this isn't working, I'd love to hear it.
On 2024-01-17 20:02, Brad Robinson via Tinycc-devel wrote:
A little more information on this from here [5]:
You also have the option of dynamically controlling the set of icall
target addresses that are considered valid by CFG using the
SetProcessValidCallTargets [1] from the Memory Management API. The
same API can be used to specify whether pages are invalid or valid
targets for CFG. The VirtualProtect [2] and VirtualAlloc [3] functions
will by default treat a specified region of executable and committed
pages as valid indirect call targets. It is possible to override this
behavior, such as when implementing a Just-in-Time compiler, by
specifying PAGE_TARGETS_INVALID when calling VirtualAlloc or
PAGE_TARGETS_NO_UPDATE when calling VirtualProtect as detailed under
Memory Protection Constants [4].
On 2024-01-17 19:25, Brad Robinson via Tinycc-devel wrote:
Hi All,
I'm trying to use setjmp/longjmp in code that needs to be compiled to
in-memory.
On Windows 11 (and presumably Windows 10) when you have Control Flow
Guard enabled, it crashes on calling longjmp.
If compiled to .exe it works fine. When Control Flow Guard is
disabled (Control Panel ... -> ... Exploit Protection) is works fine.
I've read up a little on this and it seems like it's an exception
being thrown in kernel, by a call to check the call target from the
CRT. I've also read that the call target should be allowed if the
target address' page has been marked executable - so I think this
should work, but it's definitely not.
Sample program test.c below that fails in the longjmp call when
running `tcc -run test.c`
Any ideas?
Brad
#include <stdio.h>
#include <setjmp.h>
jmp_buf jmpbuf;
void my_function()
{
longjmp(jmpbuf, 1);
}
int main()
{
if (setjmp(jmpbuf) == 0)
{
printf("A\n");
my_function();
printf("B\n");
}
printf("C\n");
return 0;
}
_______________________________________________
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
Links:
------
[1]
https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-setprocessvalidcalltargets
[2]
https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualprotect
[3]
https://learn.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualalloc
[4]
https://learn.microsoft.com/en-us/windows/desktop/Memory/memory-protection-constants
[5]
https://learn.microsoft.com/en-us/windows/win32/secbp/control-flow-guard_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel