Transparent huge pages is a feature that the linux kernel opportunistically uses.
Depending on kernel configuration this feature is either enabled always, or when you madvise the region.
To ensure we hit both cases, madvise the regions we allocate in the 64-bit VMA allocator always
Can reduce kernel bookkeeping memory usage for our abusive allocator
After FEX has forked, there aren't any other threads in the process but their stacks remain.
We need to have some book keeping in place to have the stack ranges available to clean up
after fork.
We now keep both live stacks and dead stacks in a dequeue and on fork we will walk both to
clean up all stack objects that aren't our current thread.
Due to a disjoint mechanism inside of glibc we need to override both the glibc
publicly visible allocation functions AND the hooks.
We had broken the overriding when we changed the default visibility. So first fix that.
Then only override to FEX's allocators once we are ready for it.
Then also replace the hooks.
Additionally have a way to clear the hooks back to default.
Addresses #146 a little more by providing an interface to perform
fmt-compatible logging.
No more, will people on the project be tormented by classic printf
features like:
- Accidentally passing in a non-trivial type
- PRI macros
- Not being able to add support for custom types
- Mixing up signed/unsigned printf formatting specifiers accidentally
fmt-capable versions of the logging functions are named the same as the
existing functions, just with a "Fmt" or _FMT suffix (depending on
whether or not it's a function being used or a macro, respectively).
Overriding glibc's mmap and munmap functions don't encapsulate that functions they use
for allocating stack data so it was falling down the system mmap/munmap path.
This was causing host side stacks to end up in the 32-bit VA space in 32-bit applications.
C++ no-op functions can't optimize out the predicate arguments in all cases.
This was causing a problem where zero cost assertions weren't actually zero cost.
The only way to resolve this is to actually use macros sadly enough.
This will give a fairly hefty performance uplift with anything operating on IR.
Ubuntu's x86_64 rootfs does a soft link from `/lib64/ld-linux-x86-64.so.2` to an absolute path of `/lib/x86_64-linux-gnu/ld-2.32.so`
Our frontend ELF loader logic would resolve this symlink to be just `/lib/x86_64-linux-gnu/ld-2.32.so` which would then fail.
Adds some additional logic to our frontend that if the symlink ends up being a softlink to an absolute address then it'll first resolve that symlink.
Then combines rootfs + absolute path. If that still fails then it'll fall down the regular linker path, which could still find the linker on the host side.
This is all a bit of a kludge to just work around Ubuntu doing an absolute address rather than a relative one.
Fixes#869
va_list types have an edge where after operating on it, then it is undefined behaviour to do anything other than va_end on the object.
So in order to call vsnprintf on it multiple times we must create copies with va_copy.
Easy enough to work around by doing a few more copies of the va_list
Passes the result back up to the frontend as well which allows us to early exit correctly.
Also ensures that we return ENOEXEC on these error cases so if someone is waiting on a return value, they don't just get zero
Fixes#757
Base size is now only one page in size. We will then increment that BRK
size by 8MB alignments. 256MB for 32bit applications was causing some
applications on the edge to run out of virtual memory
I was hitting some 32bit applications that were being fairly mean with
BRK. They were allocating all of BRK space then running out of virtual
memory space with its mmap handler fallback after freeing BRK space.
This means we now munmap BRK pages on release for the guest, similar to
behaviour that Linux does.
Additionally I had an application that was getting very upset that BRK
wasn't actually at the end of program space. So allocate at the end of
program space like expected.
brk test now passes from gvisor
Instead of hardcoding 64bit dynamic ELF files to 0x1'0000'0000 we
instead calculate the size of the ELF in memory. Then allocate the
ELF base up front.
LLVM ASAN steals a large amount of virtual memory space that intersected
with the original hardcoded range which caused memory allocations to
fail.