forrest@blia.BLI.COM (Jon Forrest) (07/17/87)
This is something that's been on my mind for a while. I'd like to talk this through to see if any of you can find something wrong in what I'm thinking. The software product my group produces consists partially of shareable images. Most system managers and users expect shareable images they receive to be upward compatable, that is, they don't expect to have to relink with new shareable images when a new version of a software product arrives. This is because most shareable images begin with a series of transfer vectors which allow new versions of shareable images to replace old ones without relinking for reasons that are documented in the LINKER manual. Transfer vectors work fine as long as the only difference between shareable images is the size of the code size of the routines in the shareable image. What concerns me is the effect of a change in the size of any global data structures represented by universal symbols. It appears to me that such changes would result in incorrect addresses being used when data appearing after the enlarged structure is referenced. For example, let's say that a sharable image contains variable A which is 10 bytes long and begins at location 100 and variable B which is 20 bytes long and begins at location 110. We can assume both are universal symbols. The user links an application program that references both variables with this sharable image. Everything works fine. Meanwhile, the software developer who sold the user the shareable image modifies variable A so that it now is 20 bytes long. This means that variable A begins at 100, as before, but now variable B now begins at location 120. Then, the user receives this new shareable image and, much to his consternation, finds that his program bombs every time he references location B. The answer to this problem is probably that the major G.S. match id should be incremented whenever such a situation occurrs. This, of course, would require that the application be relinked, which negates one of the primary benefits of sharable images. Indeed, my company doesn't even bother with transfer vectors because keeping track of the sizes of all data structures for which universal symbols exist is simply too difficult. Unfortunately, users of our software must relink with each release. What is actually needed is a "transfer vector" for universal symbols in addition to entry points. If such a thing were to exist then universal data could be modified at will. Unfortunately, I can't think of a way to implement transfer vectors for data without major modification of the linker. Have any of you faced this problem? If so, what did you do? One person I discussed this problem with recommended that universal symbols never be used directly but instead, a function would be created whose job it is to return the address of a universal symbol. This function could be called in a initialization routine at the beginning of an application so that pointers to universal symbols could be set before they are used later in the program. I'd like to hear anyone's response to this problem. Jon Forrest forrest@blia.BLI.COM ucbvax!mtxinu!blia!forrest {pyramid|voder}!blia!forrest
rcb@rti.UUCP (Random) (07/17/87)
In article <2961@blia.BLI.COM> forrest@blia.BLI.COM (Jon Forrest) writes: >For example, let's say that a sharable image contains variable A which >is 10 bytes long and begins at location 100 and variable B which is >20 bytes long and begins at location 110. We can assume both are >universal symbols. The user links an application program that references >both variables with this sharable image. Everything works fine. >Meanwhile, the software developer who sold the user the shareable >image modifies variable A so that it now is 20 bytes long. This >means that variable A begins at 100, as before, but now variable >B now begins at location 120. Then, the user receives this new >shareable image and, much to his consternation, finds that his >program bombs every time he references location B. The solution is really simple. Have a section of code that will always be at a fixed address and will contain pointers to the data structures. The pointers will always be 4 bytes and the addresses won't change. You can change the size of the structure and you could even change it at run time and the program won't care since it always accesses it through the pointer that is in a known location. -- Randy Buckland Research Triangle Institute rcb@rti.rti.org [128.109.139.2] {decvax,ihnp4,seismo}!mcnc!rti-sel!rcb
F1142S30%unika2@germany.CSNET (Juergen Renz) (07/21/87)
In article <2961@blia.BLI.COM> forrest@blia.BLI.COM (Jon Forrest) writes: >For example, let's say that a sharable image contains variable A which >is 10 bytes long and begins at location 100 and variable B which is >20 bytes long and begins at location 110. We can assume both are >universal symbols. The user links an application program that references >both variables with this sharable image. Everything works fine. >Meanwhile, the software developer who sold the user the shareable >image modifies variable A so that it now is 20 bytes long. This >means that variable A begins at 100, as before, but now variable >B now begins at location 120. Then, the user receives this new >shareable image and, much to his consternation, finds that his >program bombs every time he references location B. Randy Buckland answers: >The solution is really simple. Have a section of code that will >always be at a fixed address and will contain pointers to the data structures. >The pointers will always be 4 bytes and the addresses won't change. You >can change the size of the structure and you could even change it >at run time and the program won't care since it always accesses it through >the pointer that is in a known location. Your wrong Randy ! One transfer vector takes up to 8 bytes (entry routine): .transfer routine .mask routine jmp L^routine+2 or at least 2 bytes (subroutine): .transfer subroutine bsb subroutine ! this is not recommended mostly it takes 6 bytes for subroutines: .transfer subroutine jmp L^subroutine Refer to the MACRO reference manual for the complete information. The great advantage of transfer vectors is: You need not recompile your programs, if a new version of the shared library is build, because the location of the vectors doesn't change. The location of the routines will mostly change. Juergen Renz Universitaet Karlsruhe Falkengarten 7 Institut fuer Informatik IV D-7530 Pforzheim West-Germany
rcb@rti.UUCP (Random) (07/22/87)
In article <8707220428.AA22024@ucbvax.Berkeley.EDU> F1142S30%unika2@germany.CSNET (Juergen Renz) writes: >In article <2961@blia.BLI.COM> forrest@blia.BLI.COM (Jon Forrest) writes: >Randy Buckland answers: >>... >>The pointers will always be 4 bytes and the addresses won't change. ... > >Your wrong Randy ! >One transfer vector takes up to 8 bytes (entry routine): > > .transfer routine > .mask routine > jmp L^routine+2 > >or at least 2 bytes (subroutine): > > .transfer subroutine > bsb subroutine ! this is not recommended > >mostly it takes 6 bytes for subroutines: > > .transfer subroutine > jmp L^subroutine Next time, try reading the article before flaming. I was not talking about normal transfer vectors. I was talking about pointers doing the same kind of job for global data in a shared image that transfer vectors do for procedures. An example follows: .transfer routine1 .mask routine1 jmp routine1+2 .transfer routine2 .mask routine2 jmp routine2+2 data1_ptr:: .address data1 data2_ptr:: .address data2 data3_ptr:: .address data3 .transfer routine3 .mask routine3 jmp routine3+3 This is not as easy as transfer vectors, but it will work. The transfer vector for routine3 should probably have an ".align quad" in front of it, but it is not needed. Then, in you code, you can simply use globalref int *data1_ptr; foo = *data1_ptr; I hope this make things a little clearer. -- Randy Buckland Research Triangle Institute rcb@rti.rti.org [128.109.139.2] {decvax,ihnp4,seismo}!mcnc!rti-sel!rcb
bengtb@erix.UUCP (Bengt Baeverman) (07/25/87)
Keywords: The easiest thing I can think of is using a vector, just like the transfer vector, to access the data. All the UNIVERSAL symbols are really pointers to the symbols you want to access. This could be done with (macro) code looking like this: datavector: data1:: .address _data1 ; Pointer to _data1 data2:: .address _data2 ; Pointer to _data2 . . . .blkb 512 - < . - datavector > ; Fill a full page _data1: .long 200 _data2: .long 100 This is much more efficient than using a routinecall for every data access. Bengt Baverman bengtb@erix.se
MCGUIRE@GRIN2.BITNET (07/27/87)
> Date: 25 Jul 87 16:34:27 GMT > From: Bengt Baeverman <mcvax!enea!erix!bengtb@seismo.css.gov> > Subject: Re: Are Transfer Vectors Truly Useful When Creating Shareable > Images? > > The easiest thing I can think of is using a vector, just like the transfer > vector, to access the data. All the UNIVERSAL symbols are really pointers to > the symbols you want to access. In fact, you can even maintain compatibility if the data types change, if you point to a descriptor instead of a data object. For example, if you decide to change a word to a longword in your shareable code, you can maintain backward compatibility by supporting word arguments as long as you like, even while writing new applications that pass longwords. Of course, this requires you to perform conditional branches and conversions based on the data type in the descriptor. Ed McGuire Systems Coordinator Grinnell College MCGUIRE@GRIN2.BITNET