Top Up Prev Next Bottom Contents Index Search

8.4 Linker implementation


For each port of Ptolemy to a particular release, the Linker is implemented in one of two styles: "ld -A" style or "dlopen()" style. We discuss each style below.

8.4.1 Shared Objects and dlopen() style linking

If a Ptolemy release on a platform supports dlopen style dynamic linking, then the ptcl link command can be called with either a .o file or a .so file. If the link ptcl command is passed a .o file, then a .so file will be generated. If link ptcl command is passed a .so file, then the .so file will be loaded. If the .so file does not exist, then an error message will be produced and the link will return. There are several ways to specify the path to a shared object.

1. Using just a file name link foo.so will not work unless LD_LIBRARY_PATH includes the directory where foo.so resides. The man pages for dlopen() and ld discuss LD_LIBRARY_PATH Interestingly, using putenv() to set LD_LIBRARY_PATH from within ptcl has no effect on the runtime loader.

2. 2If the file name begins with ./, then the current directory is searched. link ./foo.so should work, as will link ./mydir/foo.so.

3. If the file name is an absolute path name, then the shared object will be loaded. link /tmp/foo.so should work.

4. Dynamic programs can have a run path specified at link time. The run path is the path searched at runtime for shared object. (Under Solaris2.3, the -R option to ld controls the run path. Under Irix5.2, the -rpath option to ld controls the run path). If ptcl or pigiRpc has been compiled with a run path built in, and the shared object is in that path, then the shared object will be found. The Sun Linker Manual says: "To locate the shared object foo.so.1, the runtime linker will use any LD_LIBRARY_PATH definition presently in effect, followed by any runpath specified during the link-edit of prog and finally, the default location /usr/lib. If the file name had been specified ./foo.so.1, then the runtime linker would have searched for the file only in the present working directory."

8.4.2 Porting the Dynamic Linking capability

This section is intended to assist those that attempt to port the Linker module to other platforms. The Linker class is implemented in three files: Linker.h, specifying the class interface, Linker.cc, specifying the implementation, and Linker.sysdep.h, specifying all the machine dependent parts of the implementation. To turn on debugging, compile Linker.cc with the DEBUG flag defined. One way to do this would be:

cd $PTOLEMY/obj.$PTARCH/kernel; rm -f Linker.o; make OPTIMIZER=-DDEBUG 
The Linker class currently uses "ld -A" style dynamic linking on the Sun4 (Sparc) running SunOS4.1 and g++, the Sun4 (Sparc) running SunOS4.1 and Sun's cfront port, DECStations running Ultrix, HP-PA running g++ or HP's cfront port. The Linker class currently uses "dlopen()" style dynamic linking on the Sun4 (Sparc) running Solaris2.4 and g++, the Sun4 (Sparc) running Solaris2 and Sun's cfront port (Sun CC-3.0), the Sun4 (Sparc) running Solaris2 and Sun's native C++ compiler CC-4.0, and SGI Indigos running IRIX-5.2 and g++. The intent is to structure the code in such a way that no #ifdefs appear in Linker.cc; they should all be in Linker.sysdep.h.

8.4.3 ld -A Style Dynamic Linking

The linker reads all new code into a pre-existing large array, rather than creating blocks of the right size with new, because the right size is not known in advance but a starting location must, as a rule, be passed to the loader in advance. This means that there is a wired-in limit to how much code can be linked in. The symbol LINK_MEMORY, which is set to one megabyte by default, is easily changed if required. Here are the steps taken by the linker to do its work:

1. Align the memory as required.

2. Form the command line and execute the Unix linker. Only certain flags in the command line will be system-dependent.

3. Read in the object file. This is heavily system-dependent.

4. Make the read-in text executable. On most systems this is a do-nothing step. On some platforms (such as HP) it is necessary to flush the instruction cache and that would be done at this point.

5. Invoke constructors in the newly read in code. Constructors are found by use of the nm program; the output is parsed to search for constructor symbols, whose form depends on the compiler used.

6. If this is a permanent link, copy the linker output to file .pt_symtable; otherwise delete it.

8.4.4 dlopen() Style Dynamic Linking

Here's how we link in an object using dlopen() style linking.

1. Generate a list of files to be linked in. If we have not yet done a permanent link, then the list of files to be linked in will consist of only the files in this link or multilink command. If the link is a permanent link, then we save the object name. For each successive link, we check the name of the object to be linked in against the list of objects permanently linked for duplicate file names. For each link after a permanent link, we include the names of all the unique permanently linked in objects in the generation of a temporary shared object file.

2. Generate a shared object .so file from all the objects to be linked in. The .so file is created in /tmp.

3. Do a dlopen() on the shared object.

4. Most architectures use nm to search for constructors, which are then invoked. Currently, sol2.cfront does not need to search for, or invoke constructors. gcc-2.5.8 has patches that allow similar functionality, but apparently these patches are not in gcc-2.6.0. Shared libraries in the SVR4 implementation contain optional __init and __fini functions, called when the library is first connected to (at startup or dlopen()) and when the library is disconnected from (at dlclose() or program exit), respectively. Some C++ implementations can arrange for these __init and __fini functions to contain calls to all the global constructors or destructors. On platforms where this happens, such as sol2.cfront, there is no need for the Linker class to explicitly call the constructors, as this will happen automatically.



Top Up Prev Next Bottom Contents Index Search

Copyright © 1990-1997, University of California. All rights reserved.