hbetel@watserv1.uwaterloo.ca (Heather Betel) (05/24/91)
First off, I have to appologize to the guy who suggested putting the library into the kernel. My message reads like a flame, and I didn't want that. Anyhow, please don't take offense, and I'll try not to write follow-ups while I am still over- reacting :-). To the issue at hand. The best place to start is to de- fine some goals. The shared library is a way to: 1) minimize wasted space on disk from duplication of binaries. 2) minimize wasted memory from duplication of binaries. Obviously, we want to have all processes share the same memory image of the libraries, which is loaded from a single file. This is where we all agree, but every one seems to have stopped here at defining golas. There is one more issue: MMUs. (3)The final solution should not *REQUIRE* an MMU, but (4) it should take advantage of one, if it is available. Rather than find a solution for non-MMU systems, then try to adapt it, I think we should find an MMU-friendly solution, and adapt IT to the non-MMU systems. I have a solution in mind, but I am not sure I like it. It works beautifully on MMU systems (I think), and is probably pretty good on the 68k, but it seems impossible, sick, or both for the 8086. What I think we should do is put in another system call that is passed the file name of a library. It will return a pointer to the start of the library. On an MMU system, the loaded library can be mapped into the process'es addressing space, and can also be shared between programs (I *THINK* all MMUs let you share pages between two processes). On the 68K, this is exactly the same, except every pro- cess gets the same pointer. On the 8086, however, this isn't much good. We either have to do a far call, or tack the libraries onto the end of the code segment. The former won't work with the existing compiler, and the latter does not meet goal number 2. So there you are. That is my solution. With the 8086, I would get someone to rewrite the C compiler. Actually, that's my summer project. Its my first compiler, and since all I have is lots of reference books to go on, it won't be great, but it should be very readable. It SHOULD be an ANSI C compiler for any- thing I want, but that may end up being too ambitious, so I can say that it'll start out for the 8086, and I hope to move it over to the 88k, and maybe the 68k on the way... Lastly, I should point out why *I* don't want the li- braries in the kernel: a) it doesn't achieve goal #4. To me, that says it is not a very well thought out solution. Mine goes a step further, and works for most hardware, including some that DON'T have an MMU, so I can state that THERE is a better solution than putting li- braries in kernel. b) How do parameters get passed? The library MUST have access to all processes' data space (can you feel your stomach churn?) On an MMU, this means all dataspaces for all processes are mapped into the lib server's dataspace! c) How do you select which lib function you want? This could very well end up looking like the IOCTL call, with about 200 functions being hung off a single integer. d) where do you draw the line between what is put in these libraries, and what isn't? The pascal runtime library is just as important as the C libraries. Are you going to put in both? How about the LISP, FORTH, ADA, etc libraries. How about C libraries that aren't in libc.a? (eg:curses) The list could go on forever... e) The original suggestion talks about putting in another trap. Why do that when messages work? If we are going to use message passing, we should use it all the way. Otherwise, we might as well just start mapping all the system calls onto the various interrupts available. That gives us about 246 possible system calls on the PC, or 16 on the 68k. Richard Betel ------------------------------------------------------------------------- In a world of steel and ferroconcrete, it takes a stainless steel rat to hide between the walls. -------------------------------------------------------------------------
hp@vmars.tuwien.ac.at (Peter Holzer) (05/24/91)
hbetel@watserv1.uwaterloo.ca (Heather Betel) writes: > To the issue at hand. The best place to start is to de- >fine some goals. The shared library is a way to: > 1) minimize wasted space on disk from duplication of > binaries. > 2) minimize wasted memory from duplication of binaries. > Obviously, we want to have all processes share the same >memory image of the libraries, which is loaded from a single >file. > This is where we all agree, but every one seems to have >stopped here at defining golas. There is one more issue: MMUs. >(3)The final solution should not *REQUIRE* an MMU, but (4) it >should take advantage of one, if it is available. Agreed. > Rather than find a solution for non-MMU systems, then try >to adapt it, I think we should find an MMU-friendly solution, and >adapt IT to the non-MMU systems. Agreed. > I have a solution in mind, but I am not sure I like it. >It works beautifully on MMU systems (I think), and is probably >pretty good on the 68k, but it seems impossible, sick, or both >for the 8086. I think it is just the other way round (although you have to change the compiler on the 80x86) > What I think we should do is put in another system call >that is passed the file name of a library. It will return a >pointer to the start of the library. > On an MMU system, the loaded library can be mapped into >the process'es addressing space, and can also be shared between >programs (I *THINK* all MMUs let you share pages between two >processes). > On the 68K, this is exactly the same, except every pro- >cess gets the same pointer. How do you decide where to map your library into the processes' address space? If you have two libraries and three processes, one of which uses library A, one B, and one both, do A and B start at the same address in all processes that use them? You will get large holes this way (which doesn't matter much if you use paging anyway), and worse, your program might grow beyond the address that is reserved for the first library. On the other hand, if you use a different start address for the library for every process you might have to relocate the library for each process and thus you can't share the text image between processes. You won't conserve memory space this way, only disk space. On the 80x86 this is not a problem if you use far pointers for passing data between libraries and far calls, and near pointers/calls if you stay within a library, and on other machines you can simulate this with base pointers, but I guess this makes either writing shared libraries awkward or you have to play nasty tricks with the compiler/linker (I once wrote a shared library for OS/2 -- yuck). How are these problems solved on existing UNIXes with shared libraries? -- | _ | Peter J. Holzer | Think of it | | |_|_) | Technical University Vienna | as evolution | | | | | Dept. for Real-Time Systems | in action! | | __/ | hp@vmars.tuwien.ac.at | Tony Rand |
adamd@rhi.hi.is (Adam David) (05/25/91)
hbetel@watserv1.uwaterloo.ca (Heather [actually Richard] Betel) writes: > b) How do parameters get passed? The library MUST have >access to all processes' data space (can you feel your stomach >churn?) On an MMU, this means all dataspaces for all processes >are mapped into the lib server's dataspace! The library must have access to the dataspace of the current process. This is essentially the same as if the library routine is included in the codespace of the process like we use now. > d) where do you draw the line between what is put in >these libraries, and what isn't? The pascal runtime library is >just as important as the C libraries. Are you going to put in >both? How about the LISP, FORTH, ADA, etc libraries. How about C >libraries that aren't in libc.a? (eg:curses) The list could go on >forever... What about a general purpose standard library which various language libraries then use. Most of the primitives and other general operations could be shared between different language libraries. Libraries can be categorised: system, application, user libraries. It is a good idea to standardise the interface to the libraries so that people can write custom libraries for their own use or for distribution which use the same library handling routines as the system does. > e) The original suggestion talks about putting in another >trap. Why do that when messages work? It is a question of efficiency. It is not desireable for a library routine which is called often in a tight inner loop to require a message rendevous each time it is called. It is only the first time, if the library section is not already present, that a message call is necessary so that the library section can be brought in from disk. -- Adam David. adamd@rhi.hi.is
windy@shiva.informatik.rwth-aachen.de (Andrew John Stuart Miller) (05/27/91)
hbetel@watserv1.uwaterloo.ca (Heather Betel) writes: > First off, I have to appologize to the guy who suggested . . (stuff about shared libraries deleted) . . >various interrupts available. That gives us about 246 possible >system calls on the PC, or 16 on the 68k. Try looking at the manuals for SunOS 4.X or OS9 or Helios. These operatin systems use different methods to perform such a task, nut for different reasons OS9 to save memory, so that all processes can be guaranteed to be memory for real time response. (No VM - better that way?) there is a cost in terms of restricting the addressing modes which the compiler can generate/ programmer can use. Helios to save memory, to prevent the poor user having to fit more than 1..2MB per transputer in order to run the compiler or do any other work. The transputer (stack machine) has even fewer registers that an 80x86, but the addressing modes available more than make up for this. This scheme is the most flexible from the compiler writers point of view. SunOS 4 to reduce paging traffic (uses VM to do this) This has to run on 68020s with suns own MMU 68030s sparcs Then you will know all the problems that might await you and the ways to avoid them. Andy Tannenbaum will probably object to the whole idea though. I have been wanting to do this for a long time, but never seem to get round to it Happy hacking! Andrew Miller -- -------------------------------------------------------------------------------- email: windy@strange.informatik.rwth-aachen.de snail: Ruetscherstr 165 D-5100 Aachen voice: 0049 (0)241 894-355 or 8021122
hbetel@watserv1.waterloo.edu (Heather Betel) (05/28/91)
In article <3186@krafla.rhi.hi.is> adamd@rhi.hi.is (Adam David) writes: >hbetel@watserv1.uwaterloo.ca (Heather [actually Richard] Betel) writes: > >> b) How do parameters get passed? The library MUST have >>access to all processes' data space (can you feel your stomach >>churn?) On an MMU, this means all dataspaces for all processes >>are mapped into the lib server's dataspace! > >The library must have access to the dataspace of the current process. >This is essentially the same as if the library routine is included >in the codespace of the process like we use now. > Its different. A library server runs in its own space, but to access your parameters, it has to map in YOUR memory as well. This is NOT essentially the same as before. IN the nonshared system, the library functions are in your code space, but then, they also aren't shared!(the whole point of the argument) >> d) where do you draw the line between what is put in >>these libraries, and what isn't? The pascal runtime library is >>just as important as the C libraries. Are you going to put in >>both? How about the LISP, FORTH, ADA, etc libraries. How about C >>libraries that aren't in libc.a? (eg:curses) The list could go on >>forever... > >What about a general purpose standard library which various >language libraries then use. Most of the primitives and other >general operations could be shared between different language >libraries. > >Libraries can be categorised: system, application, user libraries. >It is a good idea to standardise the interface to the libraries so >that people can write custom libraries for their own use or for >distribution which use the same library handling routines as the >system does. > A) PASCAL uses different calling semantics than C. Standardise that! :-) B) C uses a completely different system for formatted io than PASCAL. It is probably quite a task to reconcile the two. But if you manage that, then try to then reconcile the two with FORTRAN! If you can do that, why are you using minix? You should be able to make your fortunes in AI or something... >> e) The original suggestion talks about putting in another >>trap. Why do that when messages work? > >It is a question of efficiency. It is not desireable for a library >routine which is called often in a tight inner loop to require a >message rendevous each time it is called. It is only the first time, >if the library section is not already present, that a message call >is necessary so that the library section can be brought in from disk. > Like a trap is any better. Instead of trapping, then copying data, you just trap, then copy data! No matter how you cut it, there will be a form of message passing with minix. Chack out how a serial interrupt is handled. This won't be faster. Richard
tsarna@polar.bowdoin.edu (Tyler Sarna) (05/29/91)
Heather Betel didn't write: > > What I think we should do is put in another system call > that is passed the file name of a library. It will return a > pointer to the start of the library. > On an MMU system, the loaded library can be mapped into > the process'es addressing space, and can also be shared between > programs (I *THINK* all MMUs let you share pages between two > processes). > On the 68K, this is exactly the same, except every pro- > cess gets the same pointer. This is actually an almost perfect description of how shared libraries work under Exec, the hunk of Amiga OS that deals with multitasking and so forth. The Exec scheme is slightly fancier, but the basic concept is the same. This scheme is very attractive from a efficiency standpoint. It also allows the library to be unloaded when no processes that use it are running. > On the 8086, however, this isn't much good. We either This is the main stumbling point. I don't see a clean way to dit it on the 8086. IMHO, the solution is to rid the world of 8086's, but I don't think that suggestion will go over well here :-) > c) How do you select which lib function you want? This > could very well end up looking like the IOCTL call, with about > 200 functions being hung off a single integer. A much simpler solution is to just have the functions at a well-known offset from the lib pointer. > d) where do you draw the line between what is put in > these libraries, and what isn't? The pascal runtime library is > just as important as the C libraries. Are you going to put in > both? How about the LISP, FORTH, ADA, etc libraries. How about C > libraries that aren't in libc.a? (eg:curses) The list could go on > forever... You've overlooked one ofthe main advantages of your own scheme! The library name is specified at runtime. Pascal (LISP, Draco, whatever) programs simply open the appropriate library by name. If noone else is using it, the library is loaded. When the program closes the library (as part of _exit), the library is unloaded if the use count is zero. Unneeded libraries can be removed from the system, and new ones added when required. New versions of old libraries can be installed without recompiling the programs that use them, too. > e) The original suggestion talks about putting in another > trap. Why do that when messages work? If we are going to use > message passing, we should use it all the way. Otherwise, we The reason for not doing this is the large performance hit involved in copying the messages. -- Tyler "Ty" Sarna tsarna@polar.bowdoin.edu "Death therapy, Bob. It's a guaranteed cure."
adamd@rhi.hi.is (Adam David) (05/31/91)
hbetel@watserv1.waterloo.edu (Heather [actually Richard] Betel) writes: >In article <3186@krafla.rhi.hi.is> adamd@rhi.hi.is (Adam David) writes: >>The library must have access to the dataspace of the current process. >>This is essentially the same as if the library routine is included >>in the codespace of the process like we use now. >> > Its different. A library server runs in its own space, but to >access your parameters, it has to map in YOUR memory as well. This is >NOT essentially the same as before. IN the nonshared system, the >library functions are in your code space, but then, they also aren't >shared!(the whole point of the argument) I was not clear enough. I meant conceptual sameness in the operation of the program code (what gets done, not how it gets done), I am aware that the implementation mechanism is markedly different and carries with it some non-trivial issues. The library server has temporary access to the dataspace of the client which initiated the library call, because the library routine is executed with the user and group ID of the client. The client process has temporary access to the library codespace in order to access the library routine. In fact an implementation is conceivable where all the server has to do is notify the MM that the access is a valid library call and therefore to be allowed. By restricting the codespace access to the current library section during each library call, there is little to no danger of one process treading all over another one due to a badly written library routine. This would seem to require full message-passing though, unless the interaction between library server and MM is very special. > A) PASCAL uses different calling semantics than C. Standardise >that! :-) > B) C uses a completely different system for formatted io than >PASCAL. It is probably quite a task to reconcile the two. But if you >manage that, then try to then reconcile the two with FORTRAN! I am talking about fundamental operations, and not calling conventions. The language-dependent part is in the language-specific library and the part which can be shared between languages is in the general (utility) library. > Like a trap is any better. Instead of trapping, then copying >data, you just trap, then copy data! No matter how you cut it, there >will be a form of message passing with minix. Check out how a serial >interrupt is handled. This won't be faster. Maybe I misunderstood. I was under the impression that the trap handler was guaranteed maximum priority which would be higher than normal IPC messages. >Richard Adam
hbetel@watserv1.waterloo.edu (Heather Betel) (06/01/91)
In article <54886@nigel.ee.udel.edu> tsarna@polar.bowdoin.edu (Tyler Sarna) writes: > >This is the main stumbling point. I don't see a clean way to dit >it on the 8086. IMHO, the solution is to rid the world of >8086's, but I don't think that suggestion will go over well here :-) > I beg to differ. If you'll just chip in to help me upgrade from my 286 to , say, an 040 :-) > >[Misunderstanding Deleted] My discussion of IOCTL like calls and asking about which libraries to include was to refute someone else\'s suggestion for implementing shared libraries in what I beleive was a broken way. Read my original post again. I think you were probably reading too fast (or was I typing too fast?) Richard (Not Heather) Betel. (I am not a sibling! I am a free man!)
hbetel@watserv1.waterloo.edu (Heather Betel) (06/01/91)
In article <3216@krafla.rhi.hi.is> adamd@rhi.hi.is (Adam David) writes: >hbetel@watserv1.waterloo.edu (Heather [actually Richard] Betel) writes: > >The library server has temporary access to the dataspace of the client >which initiated the library call, because the library routine is executed >with the user and group ID of the client. The client process has temporary >access to the library codespace in order to access the library routine. > My point is that this must happen even on MMU systems. On the 8086, your model is fairly simple, but under, say, an 040, the library server is a different process, with a completely different memory space. Mapping in the client's space, doing the work, then mapping it out, for every call is expensive. > >I am talking about fundamental operations, and not calling conventions. >The language-dependent part is in the language-specific library and the >part which can be shared between languages is in the general (utility) >library. > Then what is the difference between the library functions and system calls? You are just putting in another level of indirection! >> Like a trap is any better. Instead of trapping, then copying >>data, you just trap, then copy data! No matter how you cut it, there >>will be a form of message passing with minix. Check out how a serial >>interrupt is handled. This won't be faster. > >Maybe I misunderstood. I was under the impression that the trap handler >was guaranteed maximum priority which would be higher than normal IPC >messages. The harddrive controller uses IPC. Are you going to give the library server higher priority than the harddrive? Richard (Not Heather) Betel I am not just a Sibling! I am a free man!
klamer@mi.eltn.utwente.nl (Klamer Schutte) (06/03/91)
In <1991Jun1.043438.17038@watserv1.waterloo.edu> hbetel@watserv1.waterloo.edu (Heather Betel) writes: > My point is that this must happen even on MMU systems. On the >8086, your model is fairly simple, but under, say, an 040, the library >server is a different process, with a completely different memory >space. Mapping in the client's space, doing the work, then mapping it >out, for every call is expensive. Either i don't understand the problem, Richards idea of an MMU is too simple, or my idea of an MMU is too complex ;-) It should be possible for an MMU (040 type) to have more than 3 segments allowed to one process at one time. The segments which need to be in current address space, and not causing a trap are (IMHO): 1) user program. text, data (incuding bbs) and stack. 2) trap handler. At least text. Perhaps data. Stack? 3) Shared library code. At least text. Perhaps read-only data. This makes 5-8 segments. The standard m68k MMU (Not on chip! ;-) has 16 segments (from memory, from structured computer organisation, Dr Tanenbaum, first edition). So no remapping on every call should be needed! > The harddrive controller uses IPC. Are you going to give the >library server higher priority than the harddrive? I hope so. The kernel harddrive driver might call library routines as well... Klamer -- Klamer Schutte Tel: +31-53-892786 Fax: +31-53-340045 Faculty of electrical engineering -- University of Twente, The Netherlands preferred: klamer@mi.eltn.utwente.nl SMTP: klamer@utelmi01.el.utwente.nl
evans@syd.dit.CSIRO.AU (Bruce.Evans) (06/03/91)
In article <klamer.675935632@mi.eltn.utwente.nl> klamer@mi.eltn.utwente.nl (Klamer Schutte) writes: >In <1991Jun1.043438.17038@watserv1.waterloo.edu> hbetel@watserv1.waterloo.edu (Heather Betel) writes: > >>... >>space. Mapping in the client's space, doing the work, then mapping it >>out, for every call is expensive. > >Either i don't understand the problem, Richards idea of an MMU is too >simple, or my idea of an MMU is too complex ;-) > >It should be possible for an MMU (040 type) to have more than 3 segments >allowed to one process at one time. The segments which need to be in >current address space, and not causing a trap are (IMHO): >1) user program. text, data (incuding bbs) and stack. >2) trap handler. At least text. Perhaps data. Stack? >3) Shared library code. At least text. Perhaps read-only data. With a decent MMU, the library code can be mapped into all processes at the same time at some convenient address such as 0xC0000000. It is easy to set up direct calls from user code to library code. With a 68000 and no MMU, the same scheme will work (for calls) using some less convenient (small) address. Even with an 8086, far calls could be used (near calls to stub routines that make far calls - there is the major inconvenience that the code segment will mess up the stack frame). Relocation of data is much more difficult. How can shared code handle different data addresses? Pointers take care of many cases. But what happens deep in an fprintf call when a buffer has to be mallocated? malloc needs a global variable to start from, and it is too much trouble to add it to the fprintf interface. On systems with an MMU and on 8086's, such variables can be put at conventional locations in low memory, e.g., at 0x40000000, 0x40000004, ... for the MMU case and 0, 4, ... for the segmented (split I&D) case. For 68000 systems with no MMU, I don't see a good way to tell where the are. -- Bruce Evans evans@syd.dit.csiro.au
tim@proton.amd.com (Tim Olson) (06/04/91)
In article <klamer.675935632@mi.eltn.utwente.nl> klamer@mi.eltn.utwente.nl (Klamer Schutte) writes: | In <1991Jun1.043438.17038@watserv1.waterloo.edu> hbetel@watserv1.waterloo.edu (Heather Betel) writes: | | > My point is that this must happen even on MMU systems. On the | >8086, your model is fairly simple, but under, say, an 040, the library | >server is a different process, with a completely different memory | >space. Mapping in the client's space, doing the work, then mapping it | >out, for every call is expensive. | | Either i don't understand the problem, Richards idea of an MMU is too | simple, or my idea of an MMU is too complex ;-) | | It should be possible for an MMU (040 type) to have more than 3 segments | allowed to one process at one time. The segments which need to be in | current address space, and not causing a trap are (IMHO): | 1) user program. text, data (incuding bbs) and stack. | 2) trap handler. At least text. Perhaps data. Stack? | 3) Shared library code. At least text. Perhaps read-only data. The two of you appear to be looking at two slightly different ways to support shared libraries with an MMU. The big difference between them is whether the compiler/linker supports PIC (Position Independant Code) and Data, or not. If PIC is supported (most commonly through PC-relative branches and references in the code sections and base-register+offset addressing in the data sections), then a single physical copy of the library code could be mapped to any virtual address and still run correctly. The shared library code could then be mapped at runtime. This appears to be the method Mr. Schutte is discussing. Mr. (Not Heather!?) Betel, on the other hand, appears to assume non-PIC code/data. One solution to this kind of library is to map it into its own virtual address space, much like MM and FS, and create a library server process out of it. This would entail quite a bit of overhead for sending messages to the server and/or copying data in and out of the calling process' memory. Another (albeit grungy!) possibility for non-PIC systems is to fix the library's virtual addresses to well-known, otherwise unused virtual memory locations, and compile the library to use those addresses (e.g. printf() exists at 0xa0001234 in every process' address space). Then, the one physical copy of the library gets mapped to the same virtual address in each process at runtime. However, this type of shared-library mapping quickly becomes impossible to use when frequent changes to the libraries occur. -- -- Tim Olson Advanced Micro Devices (tim@amd.com)
feustel@netcom.COM (David Feustel) (06/04/91)
And the only simple solution to this problem is those damn segment registers on the 386/486! -- David Feustel, 1930 Curdes Ave, Fort Wayne, IN 46805, (219) 482-9631 EMAIL: feustel@netcom.com or feustel@cvax.ipfw.indiana.edu
peterc@suite.sw.oz.au.sw.oz.au (Peter Chubb,-x27,6982322,3982735) (06/05/91)
From article <1991Jun4.041033.20792@dvorak.amd.com>, by tim@proton.amd.com (Tim Olson): > > Another (albeit grungy!) possibility for non-PIC systems is to fix the > library's virtual addresses to well-known, otherwise unused virtual > memory locations, and compile the library to use those addresses (e.g. > printf() exists at 0xa0001234 in every process' address space). Then, > the one physical copy of the library gets mapped to the same virtual > address in each process at runtime. However, this type of > shared-library mapping quickly becomes impossible to use when frequent > changes to the libraries occur. Alternatively, have a vector of addresses of routines at some standard place in the system -- rather like the way AmigaDOS does things now. It goes (almost) without saying that the shared library code itself has to be written to be reentrant. The data area used has to be that appropriate for the process calling the function. In a MMU-based system that's easy: data virtual addresses can start at zero (separate i/d); in a non-MMU based system, the calling convention will have to include setting a pointer to the base of the process's data segment. All data references by the library routine will then have to be indirected off this pointer, preferably automatically by the compiler. Regards, - Peter Chubb Softway Pty Ltd, P.O. Box 305, Strawberry Hills, NSW 2012, AUSTRALIA Phone: +61 2 698 2322; Fax: +61 2 699 9174; Telex: AA27987 Internet: peterc@softway.oz.au UUCP: ...!uunet!softway.oz!peterc
PAZZINI%BRUFSM@cunyvm.cuny.edu (Marcelo Pazzini) (06/12/91)
On Tue, 4 Jun 91 09:10:33 GMT Tim Olson said: >In article <klamer.675935632@mi.eltn.utwente.nl> klamer@mi.eltn.utwente.nl >(Klamer Schutte) writes: >hbetel@watserv1.waterloo.edu (Heather Betel) writes: >| It should be possible for an MMU (040 type) to have more than 3 segments >| allowed to one process at one time. The segments which need to be in >| current address space, and not causing a trap are (IMHO): >| 1) user program. text, data (incuding bbs) and stack. >| 2) trap handler. At least text. Perhaps data. Stack? >| 3) Shared library code. At least text. Perhaps read-only data. I worked at a company which used a 68030 as the main processor, performing its own Unix-like OS. It had up to 16 segments for each program. They use one for text, one for data & stack, others for shared memmory, including libraries. I guess it works fine. >The two of you appear to be looking at two slightly different ways to >support shared libraries with an MMU. The big difference between them (stuff about position independant compiler) >address and still run correctly. The shared library code could then >be mapped at runtime. This appears to be the method Mr. Schutte is >discussing. Well, I only propose my method for a MMU based hardware. I guess it is not a good idea to add offsets at runtime. I would also say relocations at load time isn't good, but it cannot be avoided without hardware memmory control, say, in an 8088 (bleargh). I have the same problem on moving Minix for Transputers because they have no MMU, no segment control, nothing! >Another (albeit grungy!) possibility for non-PIC systems is to fix the >library's virtual addresses to well-known, otherwise unused virtual >memory locations, and compile the library to use those addresses (e.g. >printf() exists at 0xa0001234 in every process' address space). Then, >the one physical copy of the library gets mapped to the same virtual >address in each process at runtime. However, this type of >shared-library mapping quickly becomes impossible to use when frequent >changes to the libraries occur. It will not happen if you use a jump table at the top of the library. And you can relocate it using a real Unix-like ld, with a scriptfile to do this. Hope it be useful for you, because I am not implementing this stuff. ;-) Marcelo Pazzini (pazzini@brufsm.BITNET) DELC - CT The child is grown, UFSM Campus The dream is gone, Santa Maria, RS And I have become, 97119 COMFORTABLY... TEACHER. BRASIL (BRAZIL if you're out of here!) (D.Gilmour, diff by me)