TIP: Click on subject to list as thread! ANSI
echo: os2prog
to: Jonathan de Boyne Pollar
from: Denis Tonn
date: 1998-10-09 19:55:10
subject: How do DLLs load and unl

Original from  Jonathan de Boyne Pollard  to Denis Tonn on 10-06-1998
Original Subject: How do DLLs load and unlo

                         ---------------------------------------

  JP>> The problem with this is with recursion, and pathological 
  JP>> InitTerm functions.  As I said:
 
  JP>>> [...] the pathological, but permissible, case that the InitTerm
  JP>>> function of a module may itself call DosLoadModule or 
  JP>>> DosFreeModule ?  Or the equally pathological case that the InitTerm
  JP>>> function, either accidentally or deliberately, never returns at all
  JP>>> (leaving the kernel internals in an intermediate state) [...]
 
  JP>> I wasn't asking whether this sort of code was *valid*, by 
  JP>> the way.  It's obviously valid, and in any case a decent 
  JP>> operating system has to protect itself against mischeivous 
  JP>> application code.  The question is how does the kernel deal 
  JP>> with the kernel stack overflow or deadlock issues that 
  JP>> result ?  You didn't see that this was the main thrust of 
  JP>> my question, and only referred to this obliquely:
 
  DT>  It doesn't operate with a kernel stack during the callback. It
  DT> operates with the Ring 3 stack. If the process/thread stack 
  DT> overflows, normal exception processing applies. 
 
JP> You haven't thought about the kernel stack.  When the first call to 
JP> DosLoadModule or DosFreeModule calls the InitTerm function 
JP> in ring 3, it is several stack frames deep on the kernel 
JP> stack.  Even though the stack switches to the user stack 
JP> for the ring 3 callback, these stack frames on the kernel 
JP> stack *do not go away*.  They are there for the kernel to 
JP> continue.  When a nested DosLoadModule or DosFreeModule 
JP> happens in the InitTerm function, *further* stack frames 
JP> are pushed onto the kernel stack.  It is obvious that 
JP> eventually the kernel stack is going to overflow if this is 
JP> nested enough times.  

 Each thread has it's OWN Ring 0 stack (stored in the TSD). The 
default size is 8K (4K commited and 4K guard page). I have not checked
if additional stack would be allocated, or what the limits are beyond 
this. 
 This stack is ONLY used when operating in a thread context. It is NOT
used in kernel mode.
 When in Kmode, the system is non-preemptable, and will have returned
out of Kmode (stack cleaned up) before any appication context code is 
given control again (R3 or R0 in application context). 

JP> So to add the emphasis to the question I asked above:  How 
JP> does the kernel deal with the *kernel stack* overflow issue 
JP> that results ?

 If a thread overflows it's unique ring 0 stack, it is treated in much 
the same way that an invalid buffer passed to the kernel would be 
treated. IE: an exception pointing to the ring 3 IP *after* the API
call that caused the "application context" ring 0 code to trap. 

  DT> For deadlock issues, it is again a process related situation. The 
  DT> kernel is not affected. 
 
JP> Of course it is.  If the kernel needs to lock the system module table, or the 
JP> "per-process module table" (which there must be some form 
JP> of, in order to store the reference counts described above) 
JP> at the start of DosLoadModule or DosFreeModule, and unlock 
JP> it at the end, the kernel will deadlock itself if a thread 

 It does not update the reference count until the module has loaded. 
There are no calls to application code between obtaining the reference
count semaphore in the MTE and updating it. In fact, this happens in 
non-preemtable code, so the only place it needs a semaphore is on an 
SMP system (spinlock). 

JP> makes a recursive call into DosFreeModule or DosLoadModule 
JP> from an InitTerm function.  The only way around this is to 
JP> use a recursive mutex (as I hypothesised before) that 
JP> allows the *same thread* to recursively enter DosLoadModule 
JP> or DosFreeModule.  But if one chooses that route, one then 
JP> encounters the problem of the fact that the mutex is there 
JP> in the first place in order to prevent threads from seeing 
JP> the system or process module tables in an inconsistent 
JP> state.  If an InitTerm function makes a recursive call into 
JP> DosLoadModule or DosFreeModule, and that sort of recursion 
JP> is allowed, then the *nested* DosLoadModule or 
JP> DosFreeModule function will see the module tables in an 
JP> inconsistent state, because the outermost call, which 
JP> called the InitTerm function in the first place, will be 
JP> only partway through traversing the module graph, and thus 
JP> only partway through updating the reference counts.

 The updating of the reference counts are done on a module by module 
basis. *After* the module has been loaded and fixups applied. The 
loader will have traversed the tree of "load time DLLs" and updated
the reference counts as it "walks back up the tree" and before Init is
called in any of the modules. Init/Term is optional on a DLL by DLL 
basis (and that information is stored in the MTE).
 For "run time loading", the same kind of thing will happen (the DLL 
may have other DLL's referenced in *it's* exe header). 
 Likewise, Term will only be called before a DLL is "unloaded" from 
the process address space. If a DLL "loads itself" in Term, it's Init 
will NOT be called (and therefore can't recurse itself). Term is ONLY 
called just before the DLL is unloaded/unmapped from the process. 

 It will not hold a semaphore against the MTE during any Ring 3 
callbacks. 



   Denis       

 All opinions are my very own, IBM has no claim upon them
. 
. 
.
 

 






--- Maximus/2 3.01
* Origin: T-Board - (604) 277-4574 (1:153/908)
SEEN-BY: 396/1 632/0 371 633/210 260 267 270 371 635/506 728 639/252 670/218
@PATH: 153/908 8086 800 140/1 396/1 633/260 635/506 728 633/267

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.