Link to home
Start Free TrialLog in
Avatar of itsmeandnobodyelse
itsmeandnobodyelseFlag for Germany

asked on

How to use /BASE (Base Address) linker option with VC compiler/linker

We have a big VC6 (and MFC) application including one executable and about 50 dlls. Some of these dlls were loaded statically at start of application. Most dlls were loaded dynamically at runtime which mostly causes more than one dll to get loaded at a time because of dependencies.

We now try to prevent the application from relocating the dlls. I got the sizes of the executables and all dlls including system dlls that were loaded with the executable. I also have the names and sizes of all dlls that might get loaded dynamically. I could create a text file like

app.exe        0x00040000 0x00500000        
dll1.dll          0x20000000 0x00300000
dll2.dll          0x20300000 0x00100000
dll3.dll          0x20400000 0x00200000
...

but I have some questions on that:

1. Do I have to include all system dlls such as mfc42.dll or user32.dll?
2. Is there any difference between the dlls loaded with the application and the dlls dynamically loaded?
3. Is the order of the dlls somehow important?
4. Which address is the best to start with the dlls?
  - I read somewhere that one should go down from 0x67d00000 -
5. Are there any disadvantages if the address assignment was done generously?
6. If there are some dlls that were loaded rarely, should I put them to the list or not?
7. Do I have to assign the /BASE option only when linking the executable or need
   all dlls get linked accordingly?

Regards, Alex

Avatar of AlexFM
AlexFM

It looks like you need to use rebase program:
http://www.codeproject.com/dll/rebase.asp

>> Most dlls were loaded dynamically at runtime which mostly causes more than one dll to get loaded at a time because of dependencies.
This doesn't happen, every Dll is loaded only once, LoadLibrary uses reference counting.
Avatar of itsmeandnobodyelse

ASKER

>>>> This doesn't happen, every Dll is loaded only once

Sorry, I explained it poorly. I meant that some dlls are loading some of the other dlls because they are included in the list of object/library modules of the dll.

So, most of the dlls were explicitly loaded by the executable but some because they are needed in a dll.
You can rebase all your own libraries with executable, both if they are direct exe dependencies or not.
Select start address for rebasing by such way, that memory region occupied by your libraries doesn't intersect with any system and third-party library.
I found the following rebase command in the link above (unfortunately I can't download as I am on a customer machine where downloads from Internet were not allowed).

-@rebase.exe -b 0x60000000 Server1.dll Server2.dll

Could you explain how rebase can find the applications's executable by that statement?

The base address list shown by dependency walker is strange. The executable *and* msvcirt.dll have same base address 0x00400000. Then, private and system dlls follow immediately using base addresses below 0x10000000 what would have been the expected  base start address for dlls. Then, there is a huge gap between 0x01770000 and 0x5D450000 where COMCTL32.dll was located. Then, a gap from 0x5D900000 to 0x71A00000. Finally a bunch of 24 system dlls including mfc43, ntkernel, user32, and so on...

If I would relocate comctl32.dll the region from 0x10000000 to 0x70000000 would be free for my private dlls, right?

Regards, Alex




ASKER CERTIFIED SOLUTION
Avatar of AlexFM
AlexFM

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Recommended place for rebasing is project makefile, since libraries size can be changed in ebery build.
>>>> it just sets starting address in the libraries

Bingo, that was the missing link. I always thought I have to specify the base addresses of the dlls when linking the executable ...

But what happens if a dll is used by different executables? And what happens with gaps? Do they have any influence on the size of the executable in memory?

Regards, Alex
Dll used by different executables is problem which has no solution (maybe using your own rebased copy of this Dll). System libraries use predefined range. If you use third-party libraries which are distributed with your program, you can rebase them as well. If you use third-party libraries which are not part of your distribution, I don't see acceptable solution.
>>>> Dll used by different executables is problem which has no solution

I just wondered. It's not actually a problem cause there are only tools which are using the same application dlls.

>>>> If you use third-party libraries which are distributed with your program, you can rebase them as well

Yes, I rebased all dlls in the start directory (118 files) and it worked. Beside of the executable, an OCX and ComCtl32.dll (???) there was no dll based below 0x621d0000. I used

    rebase -b 0x68000000 -d dll1.dll dll2.dll ...

from the commandline where I created the list of dlls by modifying a file list and added it via clipboard.

The output of the above command was

    REBASE: Total Size of mapping 0x05e30000
    REBASE: Range 0x621d0000 -0x68000000

Regards and thanks for your help

Alex