diff options
Diffstat (limited to 'doc/src/sgml/dfunc.sgml')
-rw-r--r-- | doc/src/sgml/dfunc.sgml | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/doc/src/sgml/dfunc.sgml b/doc/src/sgml/dfunc.sgml new file mode 100644 index 00000000000..7a719b7ed3e --- /dev/null +++ b/doc/src/sgml/dfunc.sgml @@ -0,0 +1,242 @@ +<Chapter> +<Title>Linking Dynamically-Loaded Functions</Title> + +<Para> + After you have created and registered a user-defined + function, your work is essentially done. <ProductName>Postgres</ProductName>, + however, must load the object code (e.g., a <FileName>.o</FileName> file, or + a shared library) that implements your function. As + previously mentioned, <ProductName>Postgres</ProductName> loads your code at + runtime, as required. In order to allow your code to be + dynamically loaded, you may have to compile and + linkedit it in a special way. This section briefly + describes how to perform the compilation and + linkediting required before you can load your user-defined + functions into a running <ProductName>Postgres</ProductName> server. Note that + this process has changed as of Version 4.2. +<Tip> +<Para> +The old <ProductName>Postgres</ProductName> dynamic +loading mechanism required +in-depth knowledge in terms of executable format, placement +and alignment of executable instructions within memory, etc. +on the part of the person writing the dynamic loader. Such +loaders tended to be slow and buggy. As of Version 4.2, the +<ProductName>Postgres</ProductName> dynamic loading mechanism has been rewritten to use +the dynamic loading mechanism provided by the operating +system. This approach is generally faster, more reliable and +more portable than our previous dynamic loading mechanism. +The reason for this is that nearly all modern versions of +UNIX use a dynamic loading mechanism to implement shared +libraries and must therefore provide a fast and reliable +mechanism. On the other hand, the object file must be +postprocessed a bit before it can be loaded into <ProductName>Postgres</ProductName>. We +hope that the large increase in speed and reliability will +make up for the slight decrease in convenience. +<Para> +</Tip> + You should expect to read (and reread, and re-reread) the + manual pages for the C compiler, cc(1), and the link + editor, ld(1), if you have specific questions. In + addition, the regression test suites in the directory + <FileName>PGROOT/src/regress</FileName> contain several + working examples of this process. If you copy what these + tests do, you should not have any problems. + The following terminology will be used below: +<ItemizedList> +<ListItem> +<Para> + <FirstTerm>Dynamic loading</FirstTerm> + is what <ProductName>Postgres</ProductName> does to an object file. The + object file is copied into the running <ProductName>Postgres</ProductName> + server and the functions and variables within the + file are made available to the functions within + the <ProductName>Postgres</ProductName> process. <ProductName>Postgres</ProductName> does this using + the dynamic loading mechanism provided by the + operating system. +</Para> +</ListItem> +<ListItem> +<Para> + <FirstTerm>Loading and link editing</FirstTerm> + is what you do to an object file in order to produce + another kind of object file (e.g., an executable + program or a shared library). You perform + this using the link editing program, ld(1). +</Para> +</ListItem> +</ItemizedList> +</Para> + +<Para> + The following general restrictions and notes also apply + to the discussion below: +<ItemizedList> +<ListItem> +<Para> +Paths given to the create function command must be + absolute paths (i.e., start with "/") that refer to + directories visible on the machine on which the + <ProductName>Postgres</ProductName> server is running. +<Tip> +<Para> +Relative paths do in fact work, +but are relative to +the directory where the database resides (which is generally +invisible to the frontend application). Obviously, it makes +no sense to make the path relative to the directory in which +the user started the frontend application, since the server +could be running on a completely different machine! +</Para> +</Tip> +</Para> +</ListItem> +<ListItem> +<Para> +The <ProductName>Postgres</ProductName> user must be able to traverse the path + given to the create function command and be able to + read the object file. This is because the <ProductName>Postgres</ProductName> + server runs as the <ProductName>Postgres</ProductName> user, not as the user + who starts up the frontend process. (Making the + file or a higher-level directory unreadable and/or + unexecutable by the "postgres" user is an extremely + common mistake.) +</Para> +</ListItem> +<ListItem> +<Para> +Symbol names defined within object files must not + conflict with each other or with symbols defined in + <ProductName>Postgres</ProductName>. +</Para> +</ListItem> +<ListItem> +<Para> +The GNU C compiler usually does not provide the special + options that are required to use the operating + system's dynamic loader interface. In such cases, + the C compiler that comes with the operating system + must be used. +</Para> +</ListItem> +</ItemizedList> + +<Sect1> +<Title><Acronym>ULTRIX</Acronym></Title> + +<Para> + It is very easy to build dynamically-loaded object + files under ULTRIX. ULTRIX does not have any sharedlibrary + mechanism and hence does not place any restrictions on + the dynamic loader interface. On the other + hand, we had to (re)write a non-portable dynamic loader + ourselves and could not use true shared libraries. + Under ULTRIX, the only restriction is that you must + produce each object file with the option -G 0. (Notice + that that's the numeral ``0'' and not the letter + ``O''). For example, +<ProgramListing> +# simple ULTRIX example +% cc -G 0 -c foo.c +</ProgramListing> + produces an object file called foo.o that can then be + dynamically loaded into <ProductName>Postgres</ProductName>. No additional loading or link-editing must be performed. +</Para> +</Sect1> + +<Sect1> +<Title><Acronym>DEC OSF/1</Acronym></Title> + +<Para> + Under DEC OSF/1, you can take any simple object file + and produce a shared object file by running the ld command over it with the correct options. The commands to + do this look like: +<ProgramListing> +# simple DEC OSF/1 example +% cc -c foo.c +% ld -shared -expect_unresolved '*' -o foo.so foo.o +</ProgramListing> + + The resulting shared object file can then be loaded + into <ProductName>Postgres</ProductName>. When specifying the object file name to + the create function command, one must give it the name + of the shared object file (ending in .so) rather than + the simple object file. +<Tip> +<Para> +Actually, <ProductName>Postgres</ProductName> does not care +what you name the +file as long as it is a shared object file. If you prefer +to name your shared object files with the extension .o, this +is fine with <ProductName>Postgres</ProductName> so long as you make sure that the correct +file name is given to the create function command. In +other words, you must simply be consistent. However, from a +pragmatic point of view, we discourage this practice because +you will undoubtedly confuse yourself with regards to which +files have been made into shared object files and which have +not. For example, it's very hard to write Makefiles to do +the link-editing automatically if both the object file and +the shared object file end in .o! +</Para> +</Tip> + +If the file you specify is + not a shared object, the backend will hang! +</Para> +</Sect1> + +<Sect1> +<Title> +<Acronym>SunOS 4.x</Acronym>, <Acronym>Solaris 2.x</Acronym> and <Acronym>HP-UX</Acronym></Title> + +<Para> + Under SunOS 4.x, Solaris 2.x and HP-UX, the simple + object file must be created by compiling the source + file with special compiler flags and a shared library + must be produced. + The necessary steps with HP-UX are as follows. The +z + flag to the HP-UX C compiler produces so-called + "Position Independent Code" (PIC) and the +u flag + removes + some alignment restrictions that the PA-RISC architecture + normally enforces. The object file must be turned + into a shared library using the HP-UX link editor with + the -b option. This sounds complicated but is actually + very simple, since the commands to do it are just: +<ProgramListing> +# simple HP-UX example + % cc +z +u -c foo.c + % ld -b -o foo.sl foo.o +</ProgramListing> +</Para> + +<Para> + As with the .so files mentioned in the last subsection, + the create function command must be told which file is + the correct file to load (i.e., you must give it the + location of the shared library, or .sl file). + Under SunOS 4.x, the commands look like: +<ProgramListing> +# simple SunOS 4.x example + % cc -PIC -c foo.c + % ld -dc -dp -Bdynamic -o foo.so foo.o +</ProgramListing> + + and the equivalent lines under Solaris 2.x are: +<ProgramListing> +# simple Solaris 2.x example + % cc -K PIC -c foo.c + or + % gcc -fPIC -c foo.c + % ld -G -Bdynamic -o foo.so foo.o +</ProgramListing> +</Para> + +<Para> + When linking shared libraries, you may have to specify + some additional shared libraries (typically system + libraries, such as the C and math libraries) on your ld + command line. +</Para> +</Sect1> +</Chapter> |