Megalextoria
Retro computing and gaming, sci-fi books, tv and movies and other geeky stuff.

Home » Archive » Atari MiNT Mailing List » shared libraries for MiNT
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
shared libraries for MiNT [message #6994] Tue, 30 March 1993 14:21 Go to next message
Anonymous
Karma:
Originally posted by: ersmith@netcom.com (Eric R. Smith)

A Proposal for Implementing Shared Libraries

I think I've finally figured out a "good" way to implement shared
libraries (i.e. low overhead, doesn't need VM, requires few changes
to existing applications). Here's my proposal; please let me know what
you think. (In case it isn't obvious, this is *very* far from being
cast in stone :-). I do think we need to do shared libraries soon,
though.)

A shared library will be implemented as a DRI format object file, with
the GST long name symbol table. A program linked with shared libraries
will have the same format, but with an additional header prepended
which gives the names and version numbers of the shared libraries it
requires.

Both the libraries and the programs will be compiled to use
register A5 as a base register (e.g. when compiled with gcc they will
be compiled with -mbaserel). They need not be position independent;
the libraries will appear at the same virtual address (determined at
load time) in every process, and programs will be relocated at load
time by the kernel.

The data and bss segments of a given shared library will always be
located at the same (relative) offset in the data/bss area of
a program using that library. (Note that I'm going to call the
"data/bss area" just the "data segment" from here on in, because the
bss is just a special part of the data segment from the kernel's point
of view.)

For example, let's consider 2 programs, BAR and FOO. BAR uses libraries A,
B, and C; FOO uses A, C, and D.

BAR's data segment will look like this: (assuming that A, B, C, and D are
the first 4 libraries loaded, and were loaded in that order)

------------------------------------------------------------ ------------------
| A's data | B's data | C's data | BAR's data |
------------------------------------------------------------ ------------------

FOO's data segment will look like this:

------------------------------------------------------------ ------------------
| A's data | FOO's data | C's data | D's data | more of FOO's data |
------------------------------------------------------------ ------------------

Note that FOO's data segment is split up. This is because library C expects
its data to come at a certain offset (after A's and B's), and so C's data
segment in process FOO must start at that offset. Since FOO doesn't use
library B, the part of its data segment that B would normally use is
available for FOO's use. The kernel will be responsible for finding
such "holes" and taking advantage of them where possible. (This may
actually turn out to be tricky, since arrays will have to be contiguous.)
We also may want to provide a way to specify that certain libraries are
mutually exclusive. In the example above, if libraries B and D were
mutually exclusive, then D's data could occupy the same offsets as B's
(or a subset thereof, if D has less data).

Does this make sense? The key thing is that since everyone is using
register A5 as a base register, the libraries can always find their
data (at the particular fixed offset into the data segment assigned to
them).

The disadvantage of this scheme is that once more than 64K of data is
filled up, libraries and/or programs that use 16 bit offsets will be
in trouble. There are ways around this, of course.

Another disadvantage is that program load times will be longer, since
the kernel is going to have to do the relocation and symbol resolving.

An alternative would be to use something like Sun's global offset table.
That scheme is slower, though, since it adds another layer of indirection
to variable references.

Please let me know your thoughts on this matter.

Eric




Re: shared libraries for MiNT [message #6995 is a reply to message #6994] Tue, 30 March 1993 16:35 Go to previous message
Anonymous
Karma:
Originally posted by: hyc@hanauma.Jpl.Nasa.Gov


A Proposal for Implementing Shared Libraries

I think I've finally figured out a "good" way to implement shared
libraries (i.e. low overhead, doesn't need VM, requires few changes
to existing applications). Here's my proposal; please let me know what
you think. (In case it isn't obvious, this is *very* far from being
cast in stone :-). I do think we need to do shared libraries soon,
though.)

A shared library will be implemented as a DRI format object file, with
the GST long name symbol table. A program linked with shared libraries
will have the same format, but with an additional header prepended
which gives the names and version numbers of the shared libraries it
requires.

I really think we need to have an object format that includes separate
segments for blockdata, blockbss, and maybe even blocktext for constant
arrays & structures. That's the only way to insure enough breathing space
while using 16 bit offsets.

Both the libraries and the programs will be compiled to use
register A5 as a base register (e.g. when compiled with gcc they will
be compiled with -mbaserel). They need not be position independent;
the libraries will appear at the same virtual address (determined at
load time) in every process, and programs will be relocated at load
time by the kernel.

Just a minor note, a5 is unusable for this purpose because it is zeroed
by Supexec. The current baserel stuff uses a4.

The data and bss segments of a given shared library will always be
located at the same (relative) offset in the data/bss area of
a program using that library. (Note that I'm going to call the
"data/bss area" just the "data segment" from here on in, because the
bss is just a special part of the data segment from the kernel's point
of view.)

I don't understand how this can be enforced without collisions. Is the load
address & size of the data section stored in the respective library? What
happens if the library is revised and the data section changes in size? Also,
it seems that trying to deal with gaps from unused libraries will be messy...
Finally, what about library code referencing data symbols that are external
to the library? (I think e.g. curses references some of termcap's variables...)
Is this scheme going to only support Atari-generated libraries, or will anyone
be able to write a shared library?

Does this make sense? The key thing is that since everyone is using
register A5 as a base register, the libraries can always find their
data (at the particular fixed offset into the data segment assigned to
them).

It certainly has that advantage. My previous scheme involved resetting the
base register on a per-library basis, but I couldn't figure out how to cope
with libraries that called each other, or called back into user code (like
bsearch or qsort, for example...).

The disadvantage of this scheme is that once more than 64K of data is
filled up, libraries and/or programs that use 16 bit offsets will be
in trouble. There are ways around this, of course.

Another disadvantage is that program load times will be longer, since
the kernel is going to have to do the relocation and symbol resolving.

Meaning that executables must never be stripped, as well, right? And, just
to clarify, this is not an attempt at providing dynamic loading and linking
as well, is it? (Oh, I see, you can strip any resolved symbols, of course,
and only leave the unresolved ones in a program file...)

An alternative would be to use something like Sun's global offset table.
That scheme is slower, though, since it adds another layer of indirection
to variable references.

Please let me know your thoughts on this matter.

Perhaps if we ate up yet another address register for a per-library base
register. Allow the data segment to be sized and located dynamically, with
the location stored in the main program's data region, and passed into (say)
a3 before entering a library routine. This pretty much requires stub routines
to be linked into every program, as well as any library that calls another
library. The stub will pull the correct base pointer to use from the main
program's a4 base, and restore the old register before returning. The easiest
way to deal with this is to assign fixed offsets from the program's base
pointer for each library's private base pointer. Still can't get away from
assigning some kind of fixed resource to each library, I guess.

Something else to establish that could help this discussion - is gnulib.a
treated as a single library, or does it get broken up into smaller functional
groups?
-- Howard

  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: Re: wanted: ARGV standard extension
Next Topic: fork.c
Goto Forum:
  

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Thu Apr 18 12:50:10 EDT 2024

Total time taken to generate the page: 0.03220 seconds