I'm having a little difficulty understanding how dlls actually work. I know that one copy of a dll is loaded into memory and all applications that use it have the dll mapped onto their own space. But what I don't understand is how that dll runs in that memory space. Most of the code should run as is, but long jumps and calls would need to be adjusted like in dos EXEs. This doesn't make sense to me since the actual code would have to be modified for a specific process and it wouldn't work for any of the other processes. Can someone please clarify this for me?
DDL's and PE (both are PE EXE's in fact) have a relocation map attached to them that shows all points (adresses) that have to be changed based on loading address. When windows loads a DLL or a PE it makes the changes for you... More then that 386/Pentium procesors are able to make a program belive he works at any convenient adress (say 0000.0000 or 4000.0000h) even if the program is physicaly loaded at 0A23.BFFFh) With DLL things are alittle more complicated because yes they are mapped (code) for each programm but data zones must be diffrent for each program they link to. Because of this DLL structure is more complicated and a "Startup" standard exported function (call back style)has to be called to do this nedded data inits at every link to a program PE also have links to the used DLL functions and when a PE is loaded it's links to the DLL are "filled up" by the OS with the "real" curent addres of DLL functions PE will use Note that where this functions are loaded, may (or may not) change at every OS startup... hence the name Dynamic Linking Library or DLL This message was edited by BogdanOntanu, on 4/9/2001 5:02:27 AM
But a relocation map modifies the code (adds some value to long jumps and calls). If it modifies the code, then how can the code be shared between processes? Because each process would load the dll in a different position would it not? or does windows map the same dll in the same position for every process?
As an optimation, windows attempts to use the same copy of the dll .code segments, loaded to the same address, with multiple processes. If it can't, it doesn't, and loads em multiple times. It will even split them if it gets surprised by one process writing to the .code segment (so it may keep the others 'unchanged.' As a programmer, you really need not worry about this. Just write your dll as if only a single process will ever use it (just like you may write an application as if it was the sole runner on the machine).
Thanks a lot for clearing that up for me. I know that it probably will not affect any of my code. I just bothered me. I often think about how windows does certain things cause it's interesting. I was wondering why windows doesn't just keep the data segment relative to the calling process and move the code segment relative to the start address of the called dll so no relocation would be required. But I guess if it only has to relocate once most of the time then it should be better.