This isn't quite a 100% clean sweep of IWYU.
There are some false positives where clang fails.
Additionally there are still a few missed in the frontend side of things
that I didn't get to
This is very tricky to handle and it has a bunch of rough edges.
One of the major problems that we can't workaround is that if we receive a
clone flag that pthreads can't support with THREAD, then we are required to fall down
the pthreads code path.
This is because threads going down the clone path will break TLS and we don't have
a way to work around it currently.
So this adds a clone path, a clone3 path, and keeps the legacy path as well.
Which makes this fairly convoluted but it gets pressure-vessel working on x86-64 host.
It's a bit tricky to setup but it does work.
Still some work necessary to get pressure-vessel working on AArch64 host, but I'm working on that.
When we are running a 32-bit process we end up mixing VMA Region allocators which
can cause crashes on shutdown.
This is because if a statically initialized object allocates memory, and then frees that
memory in the atexit handler. There is a chance that if it had to reallocate memory during the
VMA allocator switch, that the atexit handler will try freeing memory from the FEX VMA region allocator
AFTER it has already been deallocated.
This can't be safely worked around with atexit handlers.
So until we resolve this issue, we HAVE to leak the allocator so it can safely clean up and then let the kernel
clean up after us
This information is only ever going to be offline. Will be useful for multiple reasons.
1) Searching for split lock usage in applications, which can be a programming bug.
a) This isn't visible on AMD systems and on Intel is a fairly new linux feature
2) Having more information about when an application breaks.
3) Useful for some minor profiling for devs looking for statistical data
These parameters are used as indexes into the tracked memory, so sizing
the index variable relative to the type being stored is kind of sketchy.
e.g. If the tracked types were uint8_t for example, we'd still want the
indexing parameters to be regularly sized so that we aren't implicitly
truncating values all the time when passing values to a uint8_t
parameter (and while all usages are currently using uint64_t as type
T, we may as well address this).
While we're at it, we can make both Get() and operator[] const member
functions, since they don't directly modify any underlying data, they
only read it.
Only the frontends need to deal with ELF files specifically.
The backend doesn't need to be aware of them at all.
Since the ELF handling is the frontend's responsibility, move all the code to the frontend.
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