The default base address for an .exe built in Visual Studio is 0x00400000.
The default base address for d3dx9_30.dll and odbcint.dll (which both live in %windir%\system32) is also 0x00400000. So by default, exes that link to either of these dlls will have a runtime address collision. The OS automatically relocates the dll to a different base addresses and fixes up pointers as needed, and I can see this happening when I attach the VS debugger: The relocated module gets an exclamation icon overlay.
Rebasing system DLLs is a really bad idea, not to mention nearly impossible to do on user systems. So I have decided to rebase my exes to prevent this address collision and thus prevent runtime rebasing.
If I change my client EXE to a different base address to move it out of d3dx9_30.dll's way, it works fine: no address collision, no relocation, no fixups.
But if I change my server EXEs to a different base address to move them out of odbcint.dll's way, it does not work.
odbcint.dll is 0x17000 bytes in memory and prefers base address 0x00400000. I tried basing my EXEs at 0x00420000, then at 0x00660000. Still odbcint.dll gets relocated at runtime. I profiled with depends.exe, which showed that there is no other module attempting to claim this address before odbcint.dll loads.
Does anyone have a theory explaining why I can't get odbcint.dll to load at its preferred address?
Update:
vadump shows that by the time I enter main() the memory at 0x00400000-0x00470000 is claimed as 'UNKNOWN_MAPPED'. I have been unable to find more information about what exactly this means. I presume that some system dll is reserving this memory at load time; my debugging-fu is not strong enough to discover which, why, or precisely when.