This is the mail archive of the
mailing list for the Cygwin project.
Re: cygwin Digest 25 Sep 2005 20:51:19 -0000 Issue 4542
- From: Brian Dessent <brian at dessent dot net>
- To: cygwin at cygwin dot com
- Date: Wed, 28 Sep 2005 15:22:43 -0700
- Subject: Re: cygwin Digest 25 Sep 2005 20:51:19 -0000 Issue 4542
- References: <email@example.com> <firstname.lastname@example.org>
- Reply-to: cygwin at cygwin dot com
Fred Smith wrote:
> Which leads me to the dumb question (patience would be appreciated :)
> What is rebase? what does it do? under what circumstances would I
> want/need to do it?
When created, every DLL has a base address which is the location in the
virtual memory space that it was intended to be loaded into. The DLL
can be loaded elsewhere, but doing so requires modifying any stored
addresses that are not relative. This relocation takes a bit of time at
startup, and it also decreases the overall efficiency of the shared
library system. Normally all processes that use a particular DLL can
share one copy of it in physical memory, but if it was relocated a copy
must be made.
To help alleviate this, the MS tools have a system whereby the image
base for a DLL is assigned based on some kind of hash signature of the
DLL. (I believe they also have a kind of internal central registry of
image bases for the core system DLLs, but I'm not sure about that since
the load addresses of even core DLLs varies by OS version and even
serive pack version.)
Gcc/binutils also has a similar mechanism, but it is not turned on by
default at present. This means that DLLs created by Cygwin gcc all have
an image base of 0x10000000. There is nothing wrong with this, as the
DLLs can be relocated as needed. However, the system decides where to
relocate these DLLs, and this apparently is not always a deterministic
operation -- especially if DLLs are dynamically loaded by the program
with dlopen / LoadLibrary. The Cygwin fork emulation code relies on
being able to recreate the same[*] memory layout in the child as the
parent, and if DLLs load into different locations in the child you will
get a fatal error from Cygwin, normally something along the lines of
"Unable to remap...."
The rebase tool can change the base address of a DLL on disk, so that
the relocation is permanent. When you run rebaseall, it generates a
list of all the Cygwin DLLs, and then assigns each of them a unique
location that does not overlap with any of the other DLLs in the list
(based on their sizes.) This is analogous to defragmenting a hard
drive. It causes the memory layout to be deterministic as there is no
need for relocation, and fixes the problems with fork errors.
At the end of the day it would be cleaner to enable the automatic image
base assignment in ld, but I believe there were some problems associated
with this -- they may be fixed now. But until then, rebaseall is fairly
simple and straightforward.
As to when to use it, just run it any time you get an "unable to map" or
"MapViewOfFileEx failed" or similar fatal error. If you don't see any
fatal errors you don't need to worry.
[*] Cygwin can do fixups on its own data structures so that they can be
relocated, so the layouts aren't always exactly the same.
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html