Fixes backtraces in Visual Studio Remote Debugging when the remote program is running on wine.
Not sure if this is entirely right yet, maybe the offset/size check should also be moved further up?
Test file is attached ( [map_test.c](/uploads/4d5b426fd9ad931ef4027332f75b1bd9/map_test.c) ), however it's probably not ideal since it tests against the value that the compiler happens to put at offset 0x10000 (I tested with mingw64 GCC). In any case this value just needs to match windows, so for other compilers it can be obtained by running the test on windows. This could probably be improved with a linker script if wanted.
From: Charlotte Pabst cpabst@codeweavers.com
--- dlls/ntdll/unix/virtual.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 4b4d9d6cd7f..92735e41d97 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -3512,10 +3512,14 @@ static unsigned int virtual_map_section( HANDLE handle, PVOID *addr_ptr, ULONG_P res = get_mapping_info( handle, access, &sec_flags, &full_size, &shared_file, &image_info ); if (res) return res;
+ offset.QuadPart = offset_ptr ? offset_ptr->QuadPart : 0; + if (image_info) { SECTION_IMAGE_INFORMATION info; ULONG64 prev = 0; + void *image_ptr; + SIZE_T image_size;
if (NtCurrentTeb64()) { @@ -3525,10 +3529,15 @@ static unsigned int virtual_map_section( HANDLE handle, PVOID *addr_ptr, ULONG_P filename = (WCHAR *)(image_info + 1); /* check if we can replace that mapping with the builtin */ res = load_builtin( image_info, filename, machine, &info, - addr_ptr, size_ptr, limit_low, limit_high ); + &image_ptr, &image_size, limit_low, limit_high ); if (res == STATUS_IMAGE_ALREADY_LOADED) - res = virtual_map_image( handle, addr_ptr, size_ptr, shared_file, limit_low, limit_high, + res = virtual_map_image( handle, &image_ptr, &image_size, shared_file, limit_low, limit_high, alloc_type, machine, image_info, filename, FALSE ); + if (NT_SUCCESS(res)) + { + *addr_ptr = (char *)image_ptr + offset.QuadPart; + *size_ptr = image_size - offset.QuadPart; + } if (shared_file) NtClose( shared_file ); free( image_info ); if (NtCurrentTeb64()) NtCurrentTeb64()->Tib.ArbitraryUserPointer = prev; @@ -3536,7 +3545,6 @@ static unsigned int virtual_map_section( HANDLE handle, PVOID *addr_ptr, ULONG_P }
base = *addr_ptr; - offset.QuadPart = offset_ptr ? offset_ptr->QuadPart : 0; if (offset.QuadPart >= full_size) return STATUS_INVALID_PARAMETER; if (*size_ptr) {
Returning a pointer to the middle of the view doesn't seem right, this needs proper tests. If you need a file to map you can use a system dll like kernel32.dll.
Will rewrite the MR and add proper tests.
Regarding returning a pointer to the middle of the view, I had only checked UnmapViewOfSection, which works even if the pointer doesn't point to the start of the view (this is documented). Seems like UnmapViewOfFile requires a pointer to the start tho.