How some Unixes did shared libraries in the old days

September 4, 2011

Yesterday I wrote about how mmap() is the core of modern shared libraries. As it happens some Unixes had shared libraries even before mmap() was created, which raises the question of how they did it.

As I mentioned yesterday, the real challenge with shared libraries is the relocation issue, how you deal with the same shared library having to be mapped at different addresses in different processes. The trick answer is not to do that. You may have heard of prelinking; the extreme version of prelinking is to 'prelink' all shared libraries by assigning each of them a static load address (and relocating them for that address), and then always load them at that address in every process. This completely eliminates the need to do any run-time relocation.

Figuring out the load address of each shared library is where it gets interesting. If you're only doing this on a handful of libraries, you can give each of them their own dedicated chunk of address space. If you have more than that, you have to start looking at executables to identify libraries that are never loaded together and so can have address space assignments that conflict with each other.

(If an executable later comes along that has a load address conflict because it uses two libraries that were previously never seen together, it loses; the kernel will refuse to run it or it will probably crash shortly after it starts running. This is one reason that this approach is somewhat of a hack.)

This is clearly not a very general or scalable solution. Typically it was adopted in a desperate attempt to reduce disk space and memory usage on small Unix systems, and so only really had to work for a small number of libraries (libc, libm, perhaps termcap and/or curses, and perhaps the X libraries on systems with X). If you could get it to work for your package's shared library, that was great; if not, well, you got to statically link your library into your programs and use up more disk space and memory.

(The Unix machine I remember seeing this on was the AT&T 3B1. I believe that similar hacks were done on other obscure early attempts to fit a full Unix setup on small personal computers.)

Written on 04 September 2011.
« The core of modern Unix shared libraries
Why true asynchronous file IO is hard, at least for reads »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sun Sep 4 00:37:30 2011
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.