home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / unix / bsd / 10228 < prev    next >
Encoding:
Text File  |  1992-12-15  |  11.9 KB  |  220 lines

  1. Newsgroups: comp.unix.bsd
  2. Path: sparky!uunet!spool.mu.edu!darwin.sura.net!ra!tantalus.nrl.navy.mil!eric
  3. From: eric@tantalus.nrl.navy.mil (Eric Youngdale)
  4. Subject: Re: Shared lib benchmarks, and experiences
  5. Message-ID: <BzAEnE.GKq@ra.nrl.navy.mil>
  6. Sender: usenet@ra.nrl.navy.mil
  7. Organization: Naval Research Laboratory
  8. References: <1992Dec12.235116.7484@rwwa.COM> <1giendINNgku@life.ai.mit.edu> <1992Dec14.231025.12627@rwwa.COM>
  9. Distribution: usa
  10. Date: Tue, 15 Dec 1992 06:14:01 GMT
  11. Lines: 207
  12.  
  13. In article <1992Dec14.231025.12627@rwwa.COM> witr@rwwa.com writes:
  14. >| >  1) The two librarys must have identical ``assigned'' addresses, and
  15. >| >  2) The two librarys must be substantially identical.
  16. >| 
  17. >|     The first point is correct.  I should point out that there is no reason
  18. >| why we cannot have two different libraries assigned to the same address - you
  19. >| just will not be able to use both at the same time in the same process.
  20. >
  21. >The reason why I bring this up is that I suspect that it is difficult to
  22. >assign ``compatible'' ``assigned'' addresses except in the case where the
  23. >libraries are ``substantially identical''.  For example, if the latter library
  24. >has twice as many entrypoints as the former, this is likely to be a difficult,
  25. >problem and probably has no general solution.
  26.  
  27.     Offhand, I do not see why the number of entry points represents a
  28. problem.  The general structure of a sharable library under linux is that we
  29. start with the jump table itself.  This is usually padded to some large size to
  30. accomodate future expansion.  Directly after this comes the global data, and
  31. everything is fixed at specific addresses. After this comes the regular text
  32. and data sections.  As long as you do not overfill the section of memory that
  33. was set aside for jump vectors, there will not be a problem.  The first time
  34. you build a sharable library, you select how much memory you want for the jump
  35. vectors - a wise maintainer will always allow a lot of room for future
  36. expansion if there is *any* possibility that they will be needed.  There is no
  37. reason a priori that we even need to use up the jump vector slots in any
  38. particular order.  We could use them randomly if we wanted to, although it
  39. would serve no useful purpose to do so.
  40.  
  41. >
  42. >| The second one depends upon how you define "substantially".
  43. >[...]
  44. >| As a rule of thumb, as long as you can provide identical
  45. >| assigned addresses, you can generate plug compatible libraries.  The
  46. >| limitations have less to do with the design of the library itself, but have
  47. >| more to do with the tools that we have available to ensure that the various
  48. >| addresses remain the same from one version to the next.
  49. >
  50. >This is the caveat that worries me.  How do you handle the following
  51. >situations?
  52. >
  53. >  1) Second library has (many) more entrypoints than former library.
  54.  
  55.     This I have already discussed above.
  56.  
  57. >  2) The ordering of the entrypoints in the objects is different.
  58.  
  59.     We have complete freedom to select whatever ordering of entry points
  60. that we wish when we first build the library.  If there are two libraries that
  61. are supposed to share the same interface, then you simply have to provide
  62. identical lists of functions to the program that generates the jump vector
  63. module. 
  64.  
  65. >  3) There is changed inter- and intra-calling relationships between
  66. >     routines in this and other libraries.
  67.  
  68.     An example of this might be our X libraries.  Naturally the X libraries
  69. require various functions in libc, and since the X libraries are linked to the
  70. sharable jump-table version of libc, we can simply replace libc if there is a
  71. new version, and the sharable X libraries will automatically use the new
  72. version.  Inter-calling (calls within the library) are all resolved by the
  73. linker without having to even look at the jump table.  If the inter-calling
  74. relationships change, it will not be a problem, as long as the external
  75. interface remains fixed (i.e. the jump vectors and global data all remain at
  76. the same address). 
  77.  
  78.     There are some things that could break a sharable library, such as a
  79. change in the number of arguments for a given function.  In the past we have
  80. treated this in the following fashion: We leave the older N-argument function
  81. in the library with it's jump vector in the jump-table, but we fix things so
  82. that anytime we link to the library, the linker will only see the new N+1
  83. version of the function.  The N+1 version of the function has it's own distinct
  84. slot in the jump table, so there is never confusion about which function we are
  85. talking about.  Naturally, the header file changes at the same time we change
  86. the library.  The advantage of doing this is that we can allow a gradual
  87. changeover to the new way of doing things without suddenly breaking a lot of
  88. different programs all at one time.  After a suitable period of time, and
  89. perhaps after some warnings have been posted, the old version of the function
  90. will be deleted and the jump slot would be changed to point to a routine that
  91. would simply tell you that you must recompile.  We did something similar when
  92. we went from 16 bit inode numbers to 32 bit inode numbers in the stat
  93. structure (yet another minixism that bit the dust).
  94.  
  95.     We do this kind of stuff to avoid breaking peoples binaries, but
  96. it is a bit of a nuisance to do this kind of thing.  The more mature
  97. the library is to begin with, the better the chance that you will never have to
  98. even worry about this sort of thing.  I am not sure at all how easy or clean it
  99. would be to try and treat this sort of situation with dynamic linking.
  100.  
  101. >  4) What about run-time library loading, as is done with resolvers
  102. >     on SVR4.
  103.  
  104.     I do not know how SVR4 does it (even though I use it at work).  The way
  105. it is handled under linux is that there is a special data element in the binary
  106. which contains the following bits of info:
  107.  
  108.     1) The full path of the library to be loaded.
  109.     2) An ascii string which is more descriptive that the pathname.
  110.     3) The version number of the sharable library.
  111.     4) The virtual address at which it should be loaded.
  112.  
  113. This is spotted by crt0 (in this respect, it is similar to a global constructor
  114. under c++), and it basically does some checking (i.e. it makes sure that the
  115. version number of the library linked against is consistent with the version
  116. number of the library found at the pathname, and that the virtual address that
  117. we are requesting the library be loaded be the same as what the library itself
  118. wants to be loaded).  I am not sure, but I think that it simply amounts to some
  119. kind of mmap, and the pages are demand loaded as required.  If you wanted to
  120. know for sure, you would have to ask Linus about this.
  121.  
  122. >
  123. >| As I recall the biggest drawbacks to the dynamic linking were
  124. >| the need for a new assembler and linker, the need for more extensive kernel
  125. >| mods, larger binaries and more overhead to load a program. 
  126. >
  127. >Let's handle these in turn.
  128. >
  129. >1) Need for new assembler and linker:  If you mean that you need a compilation
  130. >system that can generate PI code, then yes, you need these.  Since the GCC
  131. >system generates PI code, I don't see why this is a problem.
  132.  
  133.     The compiler is not the problem.  The assembler, gas, does not
  134. understand (yet) the special syntax that GCC generates when writing PI code.
  135. Out of curiousity I tried compiling something with PIC, and I got gobs of
  136. assembler errors.  As I recall, this was probably the most formidable stumbling
  137. block, although in retrospect we probably could have solve the problem by
  138. running some kind of postprocessor on the assembly code.  We are also using the
  139. GNU ld, and depending upon how you do the implementation, changes may have to
  140. be made here as well.
  141.  
  142.     There was another objection that has been raised in the past by various
  143. people, and that is that in the 3/486 architecture there are relatively few
  144. machine registers compared to something like a VAX.  The PI code that I have
  145. seen GCC generate always seems to use up one register as a reference pointer of
  146. some kind or another, and when you reserve this register (usually ebx) for this
  147. purpose, it is not available to the compiler for other uses, and this could
  148. lead to poorer performance.  I have not seen any numbers to back this up,
  149. but the objection has been raised.
  150.  
  151. >If you mean that you have to extensively modify the compilation system
  152. >in other ways, this is not correct.  You can handle all the needed functions
  153. >in the CRTL startup code.  You may want to have the linker do other things
  154. >for efficiency reasons, but it is not otherwise required.
  155.  
  156.     Ah, yes, but we probably would want to have the linker do other things
  157. for efficiency reasons - if you were to compare a quick and dirty dynamic
  158. linking implementation to the linux style fixed-address libraries, the fixed
  159. address libraries would come out looking quite good indeed.  In a proper
  160. implementation of dynamic linking we would probably want the list of external
  161. symbols arranged in such a way that they take up a minimum amount of space in
  162. each binary and in such a way that the externals are easy to resolve quickly.
  163. If efficiency were no concern, we could probably just use the output from "ld
  164. -r" and build a mini-linker into crt0 to finish the job.
  165.  
  166. >2) Kernel mods.  Dynamic shared libs can be done without kernel mods
  167. >depending on how code space is protected.  Or you can use a mmap primitive
  168. >to speed things up.  Or you can add additional kernel code to make it 
  169. >all more efficient.  Extensive kernel mods are not *required*.
  170.  
  171.     I had of course forgotten that the linking could be done by crt0.
  172. Nonetheless, there is some programming involved, either in the kernel or in
  173. crt0 before you can start to use dynamic linking.
  174.  
  175. >
  176. >3) Larger binaries:  Not significantly, and, perhaps, not at all.  It depends
  177. >on the details.  This should be weighed against the benefits.
  178.  
  179.     I doubt that there would be any binaries that would be no larger with
  180. dynamic linking, but I have no doubt that you could achieve something where
  181. the additional space was not very much.
  182.  
  183. >4) More overhead to load a program.  This also depends on the details.
  184. >On my SVR4 system the additional time varys depending on whether the library
  185. >has already been accessed by another process.  For X programs, which access
  186. >about a dozen shared librarys, the time seems to be swamped by other factors,
  187. >such as widget creation.  I don't notice it.
  188.  
  189.     Again, I don't know the grungy details on how things work under SVR4.
  190. I use it at work, and it seems fast enough to me, so it is obviously possible
  191. to do dynamic linking in a workable way.  The question always boils down to the
  192. tradoffs involved, and to what tools need to be developed in order to implement
  193. one scheme or the other.  The biggest technical obstacle at the time for us was
  194. probably the assembler, although I think that we probably would have wanted to
  195. muck with the linker as well for efficiency.  There were some people who felt
  196. that we should try and use the off-the-shelf as and ld from FSF instead of
  197. trying to maintain our own variant version.
  198.  
  199.     There was a fairly long debate about the whole thing, and in the end we
  200. realized that it would not be that tough to implement the fixed address type of
  201. libraries.  Compatibility from one version to the next has always been the hard
  202. part about this type of implementation, and this is where we have been spending
  203. most of our effort to refine the process.  In contrast, with dynamic linking I
  204. would imagine that most of the refinement would be in making it efficient,
  205. since version to version compatibility is relatively easy to provide once you
  206. had a basic operating principle that is functional.
  207.  
  208.     Anyway, we have been refining the concept for about 6 months, and we
  209. now have it to a point where the drawbacks are quite minimal.  Given the proper
  210. tools it is not that tough to actually build a sharable jump-table type of
  211. library, although it may be true that is is a little easier to generate a
  212. dynamic linking type of library instead (this depends a lot on the
  213. implementation as well).  If we had decided to go with dynamic linking in one
  214. way or another, we would have probably needed to spend more time upfront before
  215. we would have gotten anything out the door.
  216.  
  217. -Eric
  218. -- 
  219. Eric Youngdale
  220.