Xcode 15.3 adds a new linker flag ('-no_huge') which allows the loader
to use zero-fill sections to reserve the areas currently being
reserved by the preloader.
This means the preloader is no longer needed (a good thing, since it's
heavily dependent on private APIs).
The preloader will still be used when Xcode <15.3 is being used, or when
building for i386 (32-bit for 10.14 and earlier).
CDBurnerXP expects the ContextMenuHandlers key to exist, and apparently
enumerates it until it receives ERROR_NO_MORE_ITEMS. If it fails to open the
key, it will spin forever trying to call RegEnumKeyExW(NULL) and getting
ERROR_INVALID_HANDLE.
We could simply create an empty ContextMenuHandlers key here, but this will
allow the New menu to work in the builtin explorer view once shellex handlers
are implemented.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=29523
GCC expects __stack_chk_fail() to be noreturn[1]. Returning from
__stack_chk_fail() can thus lead to subtle failures.
When crashing, use a volatile NULL pointer dereference. Ideally we
would like to "abort()" here, but doing so would require two more
syscall definitions just for a cold function. After all, the function
isn't even used at all if -fno-stack-protector is specified.
Also, don't say "stack smashing" (unlike glibc). The preloader
currently initializes the stack canary value to a fixed value (0), which
serves little value in protecting against actual buffer overrun attacks.
[1]: https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gccint/Stack-Smashing-Protection.html
A zerofill section is the only way to reserve address space and prevent
system frameworks from using it, including preventing allocations
before any preloader code runs:
- starting with Ventura, dyld allocates private memory from 0x1000-0x81000.
This breaks EXEs that have an image base of 0x10000.
- Rosetta allocates memory starting at 0x100000000, which breaks EXEs based there.
- starting with Monterey, for proper 10.7 binaries (which include a __program_vars section),
libSystem initializes itself before the preloader runs. This fragments the <4GB
address space which is needed for Wow64.
This will need to be adjusted if any EXEs based at 0x200000000 or higher
are found.
Today, the preloader is linked with -fPIE in spite of the fact that the
preloader is a non-PIE statically linked binary. This is due to a
limitation in tools/makedep that makes it difficult to specify CFLAGS
for each individual object file's recipe.
This can seemingly cause problems with some GOTPCREL(X) relocations
inside the preloader. Since preloader does not link to the system
library directly, there is no need for a Global Offset Table (GOT).
However, a few extern (non-static) function symbols are declared, the
use of which makes GCC emit instructions that references those symbols
by indirection through GOT. The linker then tries to optimize such
instructions to eliminate GOT references, which can fail due to various
reasons.
This stands in contradiction with Jinoh Kang's suggestion (in bug 55050)
that "-fPIE is harmless even when applied to an object linked into
non-PIE executables." The claim is theoretically true since
position-independent code can in principle be relocated to any address
(fixed or dynamic); however, it fails due to some peculiar practical
issues, which is arguably a limitation in the linker's implementation
(since it can be worked around with -Wl,--no-relax without issues).
Fix this by eliminating GOT usage by setting the default visibility of
non-static declarations to "hidden". Assuming GCC's medium code model
(-mcmodel=medium; default code model for x86_64), this suppresses any
unnecessary PLT or GOT relocations for defined symbols, and provides
opportunity for GCC to optimize the code better.
Fixes: 78ed343842
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55091