Cygwin Python/PIL TCL/TK fork rebase solution

Brian Dessent
Tue Jan 16 18:49:00 GMT 2007

Ross Patterson wrote:

> I'd still like to understand how one chooses base address and offset
> values for rebase, seeing as I was just shooting in the dark until
> something said "OWW!"  :)

Well normally you don't really choose anything.  There are two ways to
assign the base address.  And again keep in mind that for a lot of
users, this won't matter; it tends to only comes into play in the
presence of dynamically loaded modules.

If you run rebaseall, it just takes a list of all known Cygwin DLLs on
the system (based on the /etc/setup/*.lst.gz files created by setup) and
starting at some address near the top of memory (currently 0x70000000
but this might have been 0x68000000 in the recent past) it assigns them
in back to back slots, in descending order.  This should fix most
problems as it ensures that every known DLL loads to a unique spot in
virtual memory.

But it requires the user to run rebaseall, which in turn requires that
all DLLs be not in use so they can be modified, and it requires that
once this has been done the first that it be repeated any time a new
DLL-containing package is installed. 

It also fails if the program you're running tries to use a DLL not known
by setup.exe, such as a user-compiled binary, or something that loads a
DLL not managed by setup.exe.  In that case you're supposed to supply a
list of any such extra DLLs to rebaseall with -T so that it can include
them in the assignment.

In other words, this is the "guarantee that it works but requires a lot
of effort" method.

The other way, which is a lot better in general, is to just let the
linker assign a base address it when it creates the DLL.  If you pass
--enable-auto-image-base to ld (thus, "-Wl,--enable-auto-image-base" as
option to gcc/g++) then it will use a hash function to assign the base
address based on the filename of the DLL.  That function is currently:

static unsigned long
compute_dll_image_base (const char *ofile)
  unsigned long hash = strhash (ofile);
  return 0x61300000 + ((hash << 16) & 0x0FFC0000);

..which means it will end up somewhere between 0x61300000 and
0x712C0000.  This does not guarantee that there are no overlapping DLLs
since it's only just a simple hash, but it is much more convenient as
the package creator can do this once when compiling the package and it
will be set for all users.  I don't know whether ld defaults to
--enable-auto-image-base being enabled or not, but I do know that if you
use e.g. libtool it will automatically add this option for you. 
Ideally, if all packages were compiled this way we would not need
rebase/rebaseall at all.  


Unsubscribe info:
Problem reports:

More information about the Cygwin mailing list