[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Shared libs.



Hi there,

I've also been following with interest the discussion on shared libs.

I will add some remarks below, too, but the big question is whether
anyone would be willing to implement some design if we can come up
with one.  Evan, would you?

In the following, I'll try to summarize the ideas we've seen so far.

-   A shared library's code needs to use base relative addressing for
    data in DATA and BSS segments or it cannot be shared. :-)

-   Changing lots of existing library code just to be able to make a
    shared library from it is not desirable.  (I think this rules out
    Evan's original proposal, using lots of #defines.)

-   We want to be able to access static data in a shared library, not
    just functions.

-   Shared libraries have their own DATA and BSS ranges which need to
    be instantiated for every process using them.

Problems:

1. Linkage between programs and shared libraries:

(a) (Statically) link against shared library stubs and startup code which 
    (1) traps into (or otherwise invokes) a shared library manager
	which takes care of loading the respective library and
	dereferencing its functions/data (Evan, Scott)
    and/or
    (2) at load time, allocates/loads the library's DATA and BSS
	segments and stores their base address in the program's BSS so
	that library functions can find it (Stephen)
    or
    (3) reserves space for the library's DATA/BSS segments at link
        time. (Wolfgang)

    Comments: I think that the static nature of (a.2) and (a.3)
    defeats a very desirable feature of shared libraries: the ability
    to replace a shared library with another one which has the same
    interface (but may have different memory requirements).

    I share Scott's opinion that there wouldn't exist a re-entrance
    problem with (a.2).

    Of course, we would want to create these stubs automatically; this
    would probably require changes to the linker.  Also, some shared
    library manager would need to be implemented.

(b) I think the ``natural'' way would be to implement something like
    SunOS shared libraries: Shared libraries are somewhat like
    programs in that they have their own segments and startup code
    (which can initialize their data segments).  These libraries can
    be dynamically linked by a runtime linker, `ld.so', which uses a
    special system call, mmap(), to map files into memory.  `ld.so'
    itself is also a shared library which is mmap()'d by the C
    library's startup code.

    mmap() can map regions of a file read-only (in which case they can
    be shared; used for the TEXT segment) or read-write (in the MiNT
    case, this would probably mean that we have to fetch that part of
    the file from disk; used for the DATA segment); in Unix, it can
    also map anonymous memory (which is the equivalent of malloc()ing
    it, only that you can specify the virtual address).

    Now, the funny thing is that we already have a system call which
    is perfectly capable of mapping an executable into memory (and
    also taking care of relocating the TEXT segment if it's not been
    loaded before): Pexec(4,..).  (I'm not sure if Pexec(4,..)
    currently supports shared text executables well enough, but this
    should not be the problem.)

    The only thing missing is a suitable runtime linker.  Changes to
    `ld' would also be required to be able to create shared libraries
    and programs which use shared libraries.


2. Base-relative addressing a shared library's DATA and BSS segments:

I think every instance of a shared library needs its own base
register.  This could be either

(a) the same register as usual (a6?) (Chris)
or
(b) another register, e.g. a5.

Both options would probably require changes to the compiler.  When
using (a), we could perhaps even get away without compiler
modifications: What's needed is some general wrapper that saves a6 on
the stack, loads the library's base register and invokes the called
library function via a jumptable.  This wrapper could be part of the
shared library's startup code.


3. Deallocation of shared libraries' DATA/BSS segments:

Not a problem when these segments are always allocated when the
library code runs in some process' context, or when using Pexec(4,..).


4. Access from shared library to variables in the main program's DATA
   segment: (Scott raised this question)

I believe we can just forbid this.  At least, I can't think of any
useful example right now. :-)


Michael
-- 
Email: hohmuth@inf.tu-dresden.de
WWW:   http://www.inf.tu-dresden.de/~mh1/