Adding the same user flags as native, for Global/Local allocs, and
returning the pointer from Global/LocalHandle by default.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53741
This avoids relying on libunwind, which isn't always available,
and which can be brittle (e.g. current git master of libunwind fails, see
https://github.com/libunwind/libunwind/pull/203#issuecomment-984126066).
This allows unwinding with the EXIDX/EXTBL info which is used
normally for C++ exception handling/unwinding. This avoids needing
to keep the .so files unstripped and avoids needing libunwind to
load .debug_frame from disk instead of the already mapped
EXIDX/EXTBL.
This patch uses the dl_iterate_phdr function for finding the EXIDX
section; keeping this call within #ifdef linux to avoid breaking
someone's build, even though it probably is available on most unix
(or ELF) platforms.
Alternatively, we could add configure checks for this function.
This passes all my unwinding tests, for full ELF builds of Wine,
built with both GCC and Clang. (It also works for PE builds, where
only very few ELF bits need to be unwound.)
Signed-off-by: Martin Storsjö <martin@martin.st>
On most ELF platforms on ARM, ARM EHABI is the unwind info
format normally used, instead of DWARF like on most other platforms.
Currently, when unwinding through ELF objects with libunwind, the
libraries don't have any .eh_frame section mapped at runtime (since
DWARF isn't used for unwinding). Instead, what happens is that
libunwind ends up loading .debug_frame from the libraries on disk
instead.
Therefore, currently, ELF unwinding relies on the .so files not being
stripped.
This patch adds the necessary EHABI unwinding instructions in the
assembly functions that currently have DWARF CFI instructions.
EHABI isn't signaled via any specific preprocessor macro, but
is signaled by the absence of other unwind mechanisms (such
as __ARM_DWARF_EH__ and __SEH__, or maybe SjLj).
Mark the asm functions in the preloaders as .cantunwind, to avoid
undefined references to __aeabi_unwind_cpp_pr* functions.
Also mark other assembly functions as .cantunwind; for
signal_exit_thread this is essential if the function is marked
with .fnstart/.fnend - otherwise exiting threads does hang.
(pthread_exit internally calls _Unwind_ForcedUnwind, which would
hang if signal_exit_thread had .fnstart without any matching unwind
info).
This would, in principle, allow unwinding through these functions with
libunwind, for versions of libunwind that can parse the EHABI unwind
info - see e.g.
4d779f55c0.
(This commit isn't yet in any current release AFAIK). Unwinding with
EHABI via libunwind would require a few tweaks to the libunwind interface
usage in unix/signal_arm.c though, since e.g. the unw_get_proc_info call
fails if there's no .eh_frame or .debug_frame available.
Signed-off-by: Martin Storsjö <martin@martin.st>
This change is adding DWARF (CFI) unwind information to the
hand-written assembly of the `__wine_syscall_dispatcher` function.
This enables unwinding through the dispatcher from the Linux stack
into (and through) the Windows stack.
The general idea is that the `syscall_frame` struct contains the
content of the callee-save registers before the function call
(in particular the stack pointer and the return address). At any
point of the execution, we have a pointer into the `syscall_frame`
in $ebx, $ecx, $ebp, or $esp.
For the CFI codes the general idea is that we are defining the
computations of the callee-save registers based on the
`syscall_frame` using DWARF’s `breg` instruction, rather than
relative to CFA.
This makes unwinding work if libunwind is unavailable.
The dwarf_virtual_unwind function is modelled heavily on the x86_64
version of it. (Going forward, if there are changes to either of them,
one should probably look at whether those changes should be mirrored
to the other one too.)
Signed-off-by: Martin Storsjö <martin@martin.st>
This is essentially about mapping dwarf register numbers to
aarch64 registers, and for updating the right CONTEXT variable
with the CFA.
Signed-off-by: Martin Storsjö <martin@martin.st>