Path: utzoo!attcan!uunet!husc6!mailrus!cornell!uw-beaver!apollo!oj From: oj@apollo.COM (Ellis Oliver Jones) Newsgroups: comp.sys.apollo Subject: Re: Dynamic loading summarized Summary: -pic performance penalty is very small Message-ID: <40b9f17f.d5b2@apollo.COM> Date: 7 Jan 89 18:52:00 GMT References: <685@cadillac.CAD.MCC.COM> Reply-To: oj@canyon.UUCP (Ellis Oliver Jones) Organization: Apollo Computer, Chelmsford, MA Lines: 68 In article <685@cadillac.CAD.MCC.COM> beihl@cadillac.CAD.MCC.COM (Gary Beihl) writes: >[To be dynamically loaded...] the .o file to be >loaded has to be compiled with the >"-pic" (position-independent code) option. This can be done >under BSD by specifying -W0,-pic to /bin/cc. I believe some >performance penalty is paid when using this option due to >an extra level of indirection. There's no big performance penalty. All the library code is compiled this way, so the generated code when you specify -pic is in no way second class. >The rub comes when the new object tries to reference symbols >in the original executable. You can't (by default). We often solve this kind of problem by formalizing the interface between separate executables in the form of an entry point vector (epv). An epv is an array of procedure pointers. If module A dynamically loads module B, we then arrange to pass the entry point vector (or a pointer to it) from module A to module B. Then when B calls back to A, it calls through the epv. Obviously, you have to alter the structure of your application to use this technique, so it may not help you. >It seems to me that a better solution to this problem is to >have an incremental option on the linker. The BSD interface >does not provide one. Object modules and executables are indistinguishable. It is possible to link any pair of modules together via either /bin/ld or /com/bind . It's also unnecessary to use /bin/ld or /com/bind at all on self-contained programs; the C runtime library and most other "system subroutines" live in global libraries, and therefore are present in your address space already. Just run the .o or .bin file! You might exploit the uniformity of objects and executables by using a shell script to link together your "main" module and one of several optional modules, then execute the result, then delete it when you're done executing it. This could give you what you're looking for. Beware: you CAN'T bind together two cmpexe files to produce a third. You may also be able to use custom libraries to advantage. A library is any object code compiled -pic . You can use the /com/inlib command to install a library into a process. You can also create a global library, and have it loaded at node-boot time by calling it /lib/userlib.global . (In global libraries, beware; all read-write static data is initialized to zero, regardless of what kind of initialization you ask for.) Global libraries save much space and time when the same code is running in many different processes. They're quite painful to debug, though, so be careful. If you're interested in dynamic code loading, you should take a look at the "Extensible Streams Toolkit" manual as well. You should also look at that manual if you're curious about the purpose of all the stuff in /sys/mgrs . On another subject, I understand that the next release of the PRISM (DN10000) operating system will have a maximum process count of at least 150, and will use substantially less than 1/2 megabyte of backing store (disk space) per process. The current numbers are 56 (user processes) and approx. 5 megabytes, so this is a big improvement. /Ollie Jones (speaking for myself, not necessarily for Apollo Computer, Inc.) (get the details right! check the manuals before trying any of this!)