Currently, unwinding the unix libraries (or full ELF builds) requires having libunwind available.
When starting up a wine environment, an exception of type `RPC_S_SERVER_UNAVAILABLE` gets thrown - and if libunwind isn't available, this breaks the startup. Thus, currently on ARM/ARM64, libunwind is essentially mandatory.
Additionally, at least on ARM, libunwind seems brittle (commits in latest git master breaks the unwinding use cases in Wine, see e.g. https://github.com/libunwind/libunwind/pull/203#issuecomment-984126066.
This MR tries to resolve all of this, by including the preexisting DWARF parser from x86_64 in the aarch64 version too. This bit was mostly quite straightforward.
For ARM, libunwind has currently relied on DWARF debug info in the `.debug_frame` section, since Linux on ARM doesn't use DWARF for runtime unwinding. This MR adds ARM EHABI unwind opcodes where necessary, and adds a local reimplementation of an ARM EHABI/EXIDX/EXTBL unwinder, similar to the DWARF one.
With these changes, unwinding on both ARM and ARM64 seems to work fine, even without libunwind.
See the individual commit messages for more commentary on the decisions taken so far (I've tried to write up all relevant considerations there - it's a fair amount of commentery).
A couple open questions:
- So far, the shared DWARF code was put in a header, `dwarf.h`. Do you want to make this a proper standalone `.c` file too?
- I wrote the ARM EHABI unwind code mostly with `stdint.h` types like `uint32_t`(as it's in the ntdll/unix directory anyway), but I can rewrite it with `DWORD` or similar if that's preferred.
- The ARM EHABI opcodes are enabled for `defined(__arm__) && defined(__ELF__) && defined(__GNUC__) && !defined(__SEH__) && !defined(__ARM_DWARF_EH__)` - there's no define to check for for knowing it's used and enabled, but it has to be implicitly assumed if no other other unwind mechanism is signaled.
- The `dl_iterate_phdr` function, used for finding the EXIDX section for locating ARM EHABI unwind info, is used within `#ifdef linux`. It might be available on other OSes too (like FreeBSD etc). Or should I go ahead and add a configure check for it?
CC @julliard @rbernon @AndreRH
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/1134
As far as my testing goes, the message box is never shown on Windows when abort() is called with retail runtime is used, regardless of error mode and abort behaviour. That is not the case with _assert which still can show a dialog even in release mode.
It happens rather often that an app meets the error condition during the process exit and that goes silent on Windows while we display the abort dialog on app's exit.
The test program below shows that (and the same behaviour is, e. g., with ucrtbase vs ucrtbased).
```
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
void CDECL _set_app_type(int app_type);
#define D(name) static typeof(name) *p_##name
#define L(name) p_##name = (void *)GetProcAddress(hdll, #name); if (!p_##name) printf("NULL %s.\n", #name)
D(abort);
D(_set_app_type);
D(_set_abort_behavior);
D(_set_error_mode);
int main(int argc, char *argv[])
{
HMODULE hdll = LoadLibraryA("msvcrt.dll");
printf("hdll %p.\n", hdll);
L(_set_app_type);
if (!p__set_app_type)
if (!(p__set_app_type = (void *)GetProcAddress(hdll, "__set_app_type")))
printf("NULL p__set_app_type.\n");
L(abort);
L(_set_abort_behavior);
L(_set_error_mode);
p__set_app_type(2);
if (p__set_abort_behavior)
p__set_abort_behavior(_WRITE_ABORT_MSG, _WRITE_ABORT_MSG);
p__set_error_mode(_OUT_TO_MSGBOX);
p_abort();
}
```
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/1128
On Fri Oct 21 09:44:38 2022 +0000, Rémi Bernon wrote:
> I suggested to do that so we can use these tokens in the macros, which
> need to stringify their value for the `.cfi_escape` strings.
Oh, I see - thanks, that makes sense.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/1065#note_11683
On Fri Oct 21 09:29:30 2022 +0000, Martin Storsjö wrote:
> Out of curiosity - was there any specific reason for changing these
> enums into defines (or was this maybe an artifact from how this patch
> evolved from earlier forms)?
I suggested to do that so we can use these tokens in the macros, which need to stringify their value for the `.cfi_escape` strings.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/1065#note_11674
Jan Sikorski (@jsikorski) commented about dlls/dbghelp/dwarf.c:
> }
>
> /* Dwarf tends to keep the structure of the C/C++ program, and emits DW_TAG_lexical_block
> - * for every block in source program.
> + * for every block the in source program.
in the ;)
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/1126#note_11664
On Thu Oct 20 17:51:23 2022 +0000, **** wrote:
> Zebediah Figura replied on the mailing list:
> ```
> On 10/20/22 03:54, Eric Pouech wrote:
> > From: Eric Pouech <eric.pouech(a)gmail.com>
> >
> > Some Windows version expect output to be aligned on 4 bytes.
> >
> > Notes (from i386 and x86_64 tests):
> > - MSVC and Mingw/gcc don't layout the two variables (sdki, sdki_ex)
> > the same way.
> > - MSVC aligns each variable on 4-byte boundary,
> > - MingW/GCC stores them in a 8-byte chunk, but starting from the
> > end of the buffer: hence none of them is on a 4-byte boundary.
> >
> > So, fixing the alignment of variables is not sufficient to
> > workaround the compilers' discrepancy on all source code.
> >
> > I didn't find a generic way to align on 4 bytes structures of size
> > smaller than 4 bytes (apart from adding the DECLSPEC_ALIGN to
> > each of the offending structures, likely not that many though).
> > Ideas welcomed.
> Should we put those structs in pshpack4/poppack in the header? (They
> aren't defined anywhere publicly on Windows, so we can't compare there.)
> ```
from the testbot results, it seems that only W8 and early versions of W10 return errors on pointers not aligned on 4-byte; newer versions of W10 happily handle calls with unaligned pointers
so I considered that the "default" is to support non aligned access, but this requires adapting the tests to workaround limitations (not to say bug) in W8/early W10 versions rather than to put it inside the structure declaration
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/1114#note_11659
--
v4: ntdll: Fill the IOSB in sock_transmit() only inside the "if (alerted)" block.
ntdll: Combine the "if (alerted)" blocks in sock_send().
ntdll: Fill the IOSB in sock_send() only inside the "if (alerted)" block.
ntdll: Combine the "if (alerted)" blocks in sock_recv().
ntdll: Fill the IOSB in sock_recv() only inside the "if (alerted)" block.
ntdll: The async handle passed to set_async_direct_result() cannot be NULL.
ws2_32/tests: Add more tests for iosb contents while a recv is pending.
https://gitlab.winehq.org/wine/wine/-/merge_requests/871
This should move all of the remaining interfaces out of basedoc, except for IDispatchEx (and some fields will still remain); those will be for next MR.
Because all of the remaining interfaces are in the `htmldoc.c` file, and they typically tend to just forward to the HTMLDocumentNode, I'm using some macros inspired by the HTMLWINDOW7_ONEVENT_PROPERTY_\* in `htmlwindow.c` to reduce duplication. The ones that are exceptions are implemented normally without macros.
The first commit converts all of the non-IHTMLDocument\* interfaces because most of the methods are FIXMEs/unimplemented, so splitting it up isn't worth it.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/1125
Based on [a patch](https://www.winehq.org/mailman3/hyperkitty/list/wine-devel@winehq.or… by Jinoh Kang (@iamahuman) from February 2022.
I removed the need for the event object and implemented fast paths for Linux.
On macOS 10.14+ `thread_get_register_pointer_values` is used on every thread of the process.
On Linux 4.14+ `membarrier(MEMBARRIER_CMD_GLOBAL_EXPEDITED, ...)` is used.
On x86 Linux <= 4.13 `madvise(..., MADV_DONTNEED)` is used, which sends IPIs to all cores causing them to do a memory barrier.
On non-x86 Linux <= 4.2 and on other platforms the fallback path using APCs is used.
--
v3: ntdll: Add thread_get_register_pointer_values-based fast path for NtFlushProcessWriteBuffers.
ntdll: Add sys_membarrier-based fast path to NtFlushProcessWriteBuffers.
ntdll: Add MADV_DONTNEED-based fast path for NtFlushProcessWriteBuffers.
ntdll: Make server_select a memory barrier.
ntdll: Implement NtFlushProcessWriteBuffers.
https://gitlab.winehq.org/wine/wine/-/merge_requests/741
Some Windows version expect output to be aligned on 4 bytes.
Notes (from i386 and x86_64 tests):
- MSVC and Mingw/gcc don't layout the two variables (sdki, sdki_ex)
the same way.
- MSVC aligns each variable on 4-byte boundary,
- MingW/GCC stores them in a 8-byte chunk, but starting from the
end of the buffer: hence none of them is on a 4-byte boundary.
So, fixing the alignment of variables is not sufficient to
workaround the compilers' discrepancy on all source code.
I didn't find a generic way to align on 4 bytes structures of size
smaller than 4 bytes (apart from adding the DECLSPEC_ALIGN to
each of the offending structures, likely not that many though).
Ideas welcomed.
Wine-Bugs: https://bugs.winehq.org/show_bug.cgi?id=53684
Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com>
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/1114
Fix a test failure when theming is off. A toolbar without TBSTYLE_FLAT will fill its checked button
background rectangle when theming is inactive, overwriting the checked pattern required for the test.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/1112
Method decriptor's strings are internally stored in ANSI, and
potentially converted from Unicode using current code page.
Test was expecting loss in Unicode to ANSI conversion.
Adapt test to also support loss-less conversion (that's the case
when code page is UTF-8).
Wine-Bugs: https://bugs.winehq.org/show_bug.cgi?id=52873
Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com>
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/1124
This seems to be more correct than what we previously had with fewer lines of code, so I like that. I still don't really like the extra flag I had to add for Nt{Create,Open}Key, but I couldn't find a way to make things work without it. I also checked that Windows doesn't use a similar flag (by iterating over all bit masks).
--
v4: wine.inf: Put the Clients key in the right place.
advapi32/tests: Copy Software\Classes tests from ntdll.
ntdll/tests: Refactor the Software\Classes tests.
ntdll/tests: Factor out the NtEnumerateKey() tests.
kernelbase: Remove special Wow64 handling for HKEY_CLASSES_ROOT.
kernelbase: Remove special Wow6432Node handling from RegCreateKeyEx().
kernelbase: Remove special Wow6432Node handling from RegOpenKeyEx().
server: Don't return the actual 32-bit Software\Classes key.
ntdll/tests: Add some some Software\Classes query and enumerate tests.
ntdll/tests: Test that NtCreateKeyEx() also recursively obtains the Wow6432Node parent.
server: Recursively obtain the Wow6432Node parent.
ntdll/tests: Add some Software\Classes subkey tests.
https://gitlab.winehq.org/wine/wine/-/merge_requests/966
On Thu Oct 20 13:10:51 2022 +0000, eric pouech wrote:
> Hi Hugh,
> IMO, this could be written without using 'goto'
> for example
> ```
> if (console_ioctl(...) && size >= sizeof(...))
> {
> }
> else size = 0;
> HeapFree(...);
> return size;
> ```
Sure. That’s the merged version, which I think @julliard modified.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/1107#note_11523
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 $rcx, $rbp or $rsp.
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 change adds a bunch of convenience macros, to (hopefully)
improve readability of the CFI instructions.
Note: Those change was used with great success for unwinding through
the dispatcher using a modified LLDB shown in the
[“how-wine-works-101”](https://werat.dev/blog/how-wine-works-101/)
blog post as well as for in the [Orbit profiler](https://github.com/google/orbit),
that has mixed-callstack unwinding support.
Test: Inspect callstacks reported by the Orbit profiler while
running some Windows targets using the modified wine, as well as
verify debugging reports correct callstacks when stepping with our
modified LLDB through the dispatcher itself (so that we are able
to unwind through the dispatcher at any instruction).
--
v8: ntdll: Add CFI unwind info to __wine_syscall_dispatcher (x86_64)
https://gitlab.winehq.org/wine/wine/-/merge_requests/1065
More font links are added to avoid issues related to missing font links.
Data comes from: https://testbot.winehq.org/JobDetails.pl?Key=125079
Test program in the tests above: [font_link_reg.c](/uploads/9d4a722450f0dd88344a2b098770aaa0/font_link_reg.c)
--
v3: win32u: Add font links for MS Gothic.
win32u: Add font links for MingLiU.
win32u: Add font links for Microsoft JhengHei.
win32u: Add locale_dependent member to struct system_link_reg.
https://gitlab.winehq.org/wine/wine/-/merge_requests/1089
Huw Davies (@huw) commented about dlls/win32u/font.c:
> + len = link_reg->link_jp_len;
> + break;
> + case 936:
> + link = link_reg->link_sc;
> + len = link_reg->link_sc_len;
> + break;
> + case 949:
> + link = link_reg->link_kr;
> + len = link_reg->link_kr_len;
> + break;
> + case 950:
> + link = link_reg->link_tc;
> + len = link_reg->link_tc_len;
> + break;
> + default:
> + break;
You should be able to remove the `default` label.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/1089#note_11470
I was really confused about whether strdupW or wcsdup is preferred in shell32. Since strdupW is deprecated, let's just get rid of it so that no one else has to wonder.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/1103
MmGetSystemRoutineAddress wasn't finding some functions in ntoskrnl and hal.dll, this patch fixes it
required by mrac anti cheat (and various other drivers)
--
v7: ntoskrnl.exe: use LoadLibraryW for MmGetSystemRoutineAddress.
https://gitlab.winehq.org/wine/wine/-/merge_requests/839
Continuation of the patch series to support:
* Complex broadcasts.
* Complex implicit casts between component-wise equal types.
* Complex explicit casts between component-wise compatible types.
By Zeb's suggestion, I added tests for explicit casts between structs and vectors and arrays and vectors.
This was helpful for catching special edge cases.
I realized that the natural thing to do would be to also include tests for explicit casts between matrices and structs, matrices and arrays, and matrices and vectors. This made the patch series larger so I split it again (that's why this is PART 2/3).
Following patches in: https://gitlab.winehq.org/fcasas/vkd3d/-/commits/complex_broadcasts_2/
--
https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/33
MmGetSystemRoutineAddress wasn't finding some functions in ntoskrnl and hal.dll, this patch fixes it
required by mrac anti cheat (and various other drivers)
--
v5: ntoskrnl.exe: Use LoadLibraryW for MmGetSystemRoutineAddress.
https://gitlab.winehq.org/wine/wine/-/merge_requests/839
In some 32bit modules, MingW/GCC generates in Dwarf debug information,
a cfa address to be computed as:
deref(register XX + offset)
which is too complicated to be expressed through regular DbgHelp APIs.
So silence the FIXME, and report a 'too complex' error (instead of
'internal').
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52790
Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com>
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/1110