Patch attached. This is my first contribution to wine, and I have checked through the wiki for what I should do, and have attempted to fulfill all criteria.
Commit message from patch:
Before, Wine would (very incorrectly) use the argument to specify how many *low-order* address bits should be 0, when in fact, in Windows it's used to specify how many *high-order* address bits should be zero!
The functionality is taken from the documentation for NtAllocateVirtualMemory: The number of high-order address bits that must be zero in the base address of the section view. Used only when the operating system determines where to allocate the region, as when BaseAddress is NULL. Note that when ZeroBits is larger than 32, it becomes a bitmask.
and NtMapViewOfSection: Specifies the number of high-order address bits that must be zero in the base address of the section view. The value of this parameter must be less than 21 and is used only if BaseAddress is NULL—in other words, when the caller allows the system to determine where to allocate the view.
and from documentation for LuaJIT's allocator: /* Number of top bits of the lower 32 bits of an address that must be zero. ** Apparently 0 gives us full 64 bit addresses and 1 gives us the lower 2GB. */ #define NTAVM_ZEROBITS 1
Thus the interpretation done here is: If zero_bits is 0, use the full address space. If zero_bits is over 20, err (12-bit pointers are the smallest allowed). Otherwise only the lower (32-zero_bits) bits should be used.
A lot of internal Wine functionality unfortunately depends on the old Wine behavior, but thankfully, all of the uses seem to be redundant, as no function requested an alignment higher than the minimum! It may however be that I have not fully understood the code, as it is not always clear what alignment is requested.
In addition, to implement this odd Windows API, Wine somehow has to mmap an address below the maximum, which is not possible efficiently on POSIX systems compared to the Windows API. Linux has the MAP_32BIT flag, but it restricts the address space to just 1 GiB, which is not enough. For that reason, the implementation of this API in Wine uses pseudorandom heuristics ripped from the LuaJIT project (which also seems to be the only project to use this Windows API) to achieve this. It is not optimal, but it works. A proper implementation would require extensions to the mmap API.
On Sat, Feb 16, 2019, 03:33 <Las@protonmail.ch wrote:
Patch attached. This is my first contribution to wine, and I have checked through the wiki for what I should do, and have attempted to fulfill all criteria.
Commit message from patch:
Before, Wine would (very incorrectly) use the argument to specify how many *low-order* address bits should be 0, when in fact, in Windows it's used to specify how many *high-order* address bits should be zero!
The functionality is taken from the documentation for NtAllocateVirtualMemory: The number of high-order address bits that must be zero in the base address of the section view. Used only when the operating system determines where to allocate the region, as when BaseAddress is NULL. Note that when ZeroBits is larger than 32, it becomes a bitmask.
and NtMapViewOfSection: Specifies the number of high-order address bits that must be zero in the base address of the section view. The value of this parameter must be less than 21 and is used only if BaseAddress is NULL—in other words, when the caller allows the system to determine where to allocate the view.
and from documentation for LuaJIT's allocator: /* Number of top bits of the lower 32 bits of an address that must be zero. ** Apparently 0 gives us full 64 bit addresses and 1 gives us the lower 2GB. */ #define NTAVM_ZEROBITS 1
Thus the interpretation done here is: If zero_bits is 0, use the full address space. If zero_bits is over 20, err (12-bit pointers are the smallest allowed). Otherwise only the lower (32-zero_bits) bits should be used.
A lot of internal Wine functionality unfortunately depends on the old Wine behavior, but thankfully, all of the uses seem to be redundant, as no function requested an alignment higher than the minimum! It may however be that I have not fully understood the code, as it is not always clear what alignment is requested.
In addition, to implement this odd Windows API, Wine somehow has to mmap an address below the maximum, which is not possible efficiently on POSIX systems compared to the Windows API. Linux has the MAP_32BIT flag, but it restricts the address space to just 1 GiB, which is not enough. For that reason, the implementation of this API in Wine uses pseudorandom heuristics ripped from the LuaJIT project (which also seems to be the only project to use this Windows API) to achieve this. It is not optimal, but it works. A proper implementation would require extensions to the mmap API.
Looks like your patch didn't attach.