DLL memory model

Kernel, Loader, code execution and working with memory

DLL memory model

Postby adimetrius » Thu Nov 04, 2021 10:06 am

Reading the Kernel module, I have noticed two memory models distinguished by the variable dllMem: BOOLEAN;
Also, the Kernel module used in Linux for the cross-platform BlackBox does not have two memory models, but only one; and it looks like the one used in Linux Kernel matches the dllMem model in Windows. Is there anywhere a discussion of these models in Windows, and why it is necessary to have two instead of one?

In the changes list, there is this line: 20120906, luowy, deallocate cluster only if dllMem. What is the rationale behind this decision, as opposed to the ~dllMem => leave cluster allocated?
User avatar
adimetrius
 
Posts: 64
Joined: Sun Aug 04, 2019 1:02 pm

Re: DLL memory model

Postby adimetrius » Sat Nov 06, 2021 6:13 pm

I have discovered that Kernel uses WinApi.VirtualAlloc/VirtualFree for 'module memory': code, global vars, metainformation; and WinApi.HeapAlloc/HeapFree to allocate clusters of memory that are used for dynamic variables.
I wonder if it makse sense to use HeapAlloc/Free. These functions allow to allocate memory with byte granularity. Of course, this comes at a cost: WinApi keeps track of these granularity-free blocks; HeapAlloc/Free make in turn calls to VirtualAlloc/Free as necessary.
However, BlackBox does not need byte-granular memory for it's clusters. In fact, special care is taken to make sure Kernel.Cluster variables are aligned at 16-byte (it seems) boundary. In fact, BlackBox allocates clusters of 64 or 256 kilobytes.
So, I wonder if Kernel could do away with HeapAlloc/Free and use VirtualAlloc/Free for cluster allocation as well.

Also, it seems that when in .exe memory model, Kernel does not free address space after, say, a module is unloaded; rather, it only frees the memory pages. The only rationale for this that I can think of is to prevent the possibility of some other data or code being allocated at the same addresses, and then some old pointer into this range being used, most likely resulting in a trap or a crash. Are there any other reasons? Would the same have to hold for dynamic memory - wouldn't it be safer to never reuse addresses once allocated for dynamic variables?
User avatar
adimetrius
 
Posts: 64
Joined: Sun Aug 04, 2019 1:02 pm

Re: DLL memory model

Postby Josef Templ » Sun Nov 14, 2021 1:41 pm

If I remember correctly, modules are marked as "unusable" when unloaded. If a procedure variable is called that calls such a code address, a trap is generated and it is discovered and reported correctly that a call to an unloaded module has been made.
However, the physical memory pages are recovered after unload but the virtual memory space remains allocated. So you can do a lot of load/unload cycles but not infinitely many.

This cannot be done with heap memory. The unloaded code could simply be executed via a procedure variable as long as the memory is not reused. But executing such code is unsafe because the heap roots (global variables) are no longer tracked by the garbage collector. In addition the physical memory pages are not recovered after unload and you cannot have a lot of load/unload cycles.

There are probably even more subtle trade-offs between the two kinds of memory such as the available address space, fragmentation, etc.

- Josef
Josef Templ
 
Posts: 258
Joined: Tue Sep 17, 2013 6:50 am


Return to System

Who is online

Users browsing this forum: No registered users and 1 guest

cron