Troy Rollo wine@troy.rollo.name writes:
* The problem with emulating this is that on Linux the top of the stack is at
* 0xbfffffff and below, so reserving even the balance of this range would
* artificially limit stack growth. We could move the stack, but it's too late
* to do that here because there will be pointers to things on the stack
* that will be affected - moving the stack would need to be done in main() in
* loader/main.c, which would then be responsible for moving it back (this would
* be done with mremap and subsequent adjustment to the stack pointer).
Actually we don't run on the main stack, so allocating the space above 0x80000000 would definitely be possible, the stack doesn't need to grow there.
On Wed, 3 Mar 2004 16:20, Alexandre Julliard wrote:
Actually we don't run on the main stack, so allocating the space above 0x80000000 would definitely be possible, the stack doesn't need to grow there.
In that case I could move the changes to start_process and incorporate the address space modifications as per the comments. The only issue then would be determining how far the original stack has already grown so as to know how many bytes to reserve (the alternative would be to deallocate the whole range and then reserve it, but if something else has mapped into that region in the interim this would not be helpful).
Options I can see for this would be:
1. Start with the expected size, and then looping until success, dropping the size by 65536 each iteration.
2. Start with the expected size, if that doesn't work use a binary search algorithm to see how many we can reserve.
3. Grovel at /proc/{pid}/mem on Linux, do nothing on others.
None of these is ideal. This might be in the "don't fix it until something's known to be broken" category.
Troy Rollo wine@troy.rollo.name writes:
- Start with the expected size, and then looping until success, dropping the
size by 65536 each iteration.
- Start with the expected size, if that doesn't work use a binary search
algorithm to see how many we can reserve.
Definitely a binary search.
None of these is ideal. This might be in the "don't fix it until something's known to be broken" category.
Well, it's currently broken on Solaris, and on some Linux distros (RHEL3 for instance). The main problem is that we have to prevent the kernel from allocating things above 0x80000000, but we still need to be able to put things there ourselves, like Win9x native dlls. This will require some restructuring of the memory management code.
On Thu, 4 Mar 2004 11:36, Alexandre Julliard wrote:
Well, it's currently broken on Solaris, and on some Linux distros (RHEL3 for instance). The main problem is that we have to prevent the kernel from allocating things above 0x80000000, but we still need to be able to put things there ourselves, like Win9x native dlls. This will require some restructuring of the memory management code.
So you'd rather ensure that we hold one or more anonymous maps reserving everything above 0x80000000 (except for NT emulations, assuming the 3G emulation is to be preferred, or there's an option for 3G), and when the system needs to allocate something there, free a portion of the anonymous map and reallocate?
Presumably this should all only apply to PE files since Winelib files should be sufficiently aware of where they're running to be able to deal with whatever the system wants to do with its memory.
Troy Rollo wine@troy.rollo.name writes:
So you'd rather ensure that we hold one or more anonymous maps reserving everything above 0x80000000 (except for NT emulations, assuming the 3G emulation is to be preferred, or there's an option for 3G), and when the system needs to allocate something there, free a portion of the anonymous map and reallocate?
Something like that yes. It means we need to keep track of the allocations in that area, which cannot be done with the existing mechanism since we currently rely on the kernel to manage the free space. So there's a bit of work involved.
Presumably this should all only apply to PE files since Winelib files should be sufficiently aware of where they're running to be able to deal with whatever the system wants to do with its memory.
Winelib apps can load PE dlls too, so they probably need the same treatment. We can set the IMAGE_FILE_LARGE_ADDRESS flag if we don't want that behavior.
On Wed, 03 Mar 2004 17:23:27 -0800, Alexandre Julliard wrote:
So you'd rather ensure that we hold one or more anonymous maps reserving everything above 0x80000000 (except for NT emulations, assuming the 3G emulation is to be preferred, or there's an option for 3G), and when the system needs to allocate something there, free a portion of the anonymous map and reallocate?
Something like that yes. It means we need to keep track of the allocations in that area, which cannot be done with the existing mechanism since we currently rely on the kernel to manage the free space. So there's a bit of work involved.
This sounds a bit like what we need to do for exec-shield/prelink. Is it possible we could use the same mechanism used to reserve the PE load area to reserve this range as well?
Mike Hearn mh@codeweavers.com writes:
This sounds a bit like what we need to do for exec-shield/prelink. Is it possible we could use the same mechanism used to reserve the PE load area to reserve this range as well?
Probably not, we don't know the proper range to use at compile time.
So you'd rather ensure that we hold one or more anonymous maps reserving everything above 0x80000000 (except for NT emulations, assuming the 3G emulation is to be preferred, or there's an option for 3G), and when the system needs to allocate something there, free a portion of the anonymous map and reallocate?
Something like that yes. It means we need to keep track of the allocations in that area, which cannot be done with the existing mechanism since we currently rely on the kernel to manage the free space. So there's a bit of work involved.
Doesn't the list in VIRTUAL_FirstView hold all that is needed? If we reserve the whole lot, it seems to me that the only parts that would need to be added in there would be the parts that are below the 0xc0000000 boundary and were allocated before we get in to claim the range.
On related matters, looking at the code that calls mmap yesterday, I noticed that a VirtualAlloc with MEM_RESERVED (the flag to reserve a range of virtual addresses under windows) does not use the MAP_NORESERVE flag (the flag to prevent the system from allocating swap space for the mapped range) - is there a reason for this? If we're going to be mapping 1GB+ chunks of memory it would seem imperative that MAP_NORESERVE be used where available and we have no immediate plans to actually use the memory.
Troy Rollo wine@troy.rollo.name writes:
Doesn't the list in VIRTUAL_FirstView hold all that is needed? If we reserve the whole lot, it seems to me that the only parts that would need to be added in there would be the parts that are below the 0xc0000000 boundary and were allocated before we get in to claim the range.
No, because we can't currently allocate a view in the middle of another one, which we would need in order to load Win9x native dlls.
On related matters, looking at the code that calls mmap yesterday, I noticed that a VirtualAlloc with MEM_RESERVED (the flag to reserve a range of virtual addresses under windows) does not use the MAP_NORESERVE flag (the flag to prevent the system from allocating swap space for the mapped range) - is there a reason for this?
No real reason no, this could be changed.