2000-03-31 05:27:42 +02:00
|
|
|
<!--
|
|
|
|
$Header: /cvsroot/pgsql/doc/src/sgml/dfunc.sgml,v 1.9 2000/03/31 03:27:40 thomas Exp $
|
|
|
|
-->
|
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<chapter id="dfunc">
|
|
|
|
<title id="dfunc-title">Linking Dynamically-Loaded Functions</title>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-10-09 04:26:52 +02:00
|
|
|
<para>
|
|
|
|
|
1999-07-22 17:11:05 +02:00
|
|
|
<!--
|
|
|
|
.SH "Compiling Dynamically-Loaded C Functions"
|
|
|
|
.PP
|
|
|
|
Different operating systems require different procedures for compiling
|
|
|
|
C source files so that Postgres can load them dynamically. This section
|
|
|
|
discusses the required compiler and loader options on each system.
|
|
|
|
.PP
|
|
|
|
Under Linux ELF, object files can be generated by specifing the compiler
|
|
|
|
flag -fpic.
|
|
|
|
.PP
|
|
|
|
Under Ultrix, all object files that Postgres is expected to load
|
|
|
|
dynamically must be compiled using
|
|
|
|
.IR /bin/cc
|
|
|
|
with the \*(lq-G 0\*(rq option turned on. The object file name in the
|
|
|
|
.IR as
|
|
|
|
clause should end in \*(lq.o\*(rq.
|
|
|
|
.PP
|
|
|
|
Under HP-UX, DEC OSF/1, AIX and SunOS 4, all object files must be
|
|
|
|
turned into
|
|
|
|
.IR "shared libraries"
|
|
|
|
using the operating system's native object file loader,
|
|
|
|
.IR ld(1).
|
|
|
|
.PP
|
|
|
|
Under HP-UX, an object file must be compiled using the native HP-UX C
|
|
|
|
compiler,
|
|
|
|
.IR /bin/cc ,
|
|
|
|
with both the \*(lq+z\*(rq and \*(lq+u\*(rq flags turned on. The
|
|
|
|
first flag turns the object file into \*(lqposition-independent
|
|
|
|
code\*(rq (PIC); the second flag removes some alignment restrictions
|
|
|
|
that the PA-RISC architecture normally enforces. The object file must
|
|
|
|
then be turned into a shared library using the HP-UX loader,
|
|
|
|
.IR /bin/ld .
|
|
|
|
The command lines to compile a C source file, \*(lqfoo.c\*(rq, look
|
|
|
|
like:
|
|
|
|
.nf
|
|
|
|
cc <other flags> +z +u -c foo.c
|
|
|
|
ld <other flags> -b -o foo.sl foo.o
|
|
|
|
.fi
|
|
|
|
The object file name in the
|
|
|
|
.BR as
|
|
|
|
clause should end in \*(lq.sl\*(rq.
|
|
|
|
.PP
|
|
|
|
An extra step is required under versions of HP-UX prior to 9.00. If
|
|
|
|
the Postgres header file
|
|
|
|
.nf
|
|
|
|
include/c.h
|
|
|
|
.fi
|
|
|
|
is not included in the source file, then the following line must also
|
|
|
|
be added at the top of every source file:
|
|
|
|
.nf
|
|
|
|
#pragma HP_ALIGN HPUX_NATURAL_S500
|
|
|
|
.fi
|
|
|
|
However, this line must not appear in programs compiled under HP-UX
|
|
|
|
9.00 or later.
|
|
|
|
.PP
|
|
|
|
Under DEC OSF/1, an object file must be compiled and then turned
|
|
|
|
into a shared library using the OSF/1 loader,
|
|
|
|
.IR /bin/ld .
|
|
|
|
In this case, the command lines look like:
|
|
|
|
.nf
|
|
|
|
cc <other flags> -c foo.c
|
|
|
|
ld <other flags> -shared -expect_unresolved '*' -o foo.so foo.o
|
|
|
|
.fi
|
|
|
|
The object file name in the
|
|
|
|
.BR as
|
|
|
|
clause should end in \*(lq.so\*(rq.
|
|
|
|
.PP
|
|
|
|
Under SunOS 4, an object file must be compiled and then turned into a
|
|
|
|
shared library using the SunOS 4 loader,
|
|
|
|
.IR /bin/ld .
|
|
|
|
The command lines look like:
|
|
|
|
.nf
|
|
|
|
cc <other flags> -PIC -c foo.c
|
|
|
|
ld <other flags> -dc -dp -Bdynamic -o foo.so foo.o
|
|
|
|
.fi
|
|
|
|
The object file name in the
|
|
|
|
.BR as
|
|
|
|
clause should end in \*(lq.so\*(rq.
|
|
|
|
.PP
|
|
|
|
Under AIX, object files are compiled normally but building the shared
|
|
|
|
library requires a couple of steps. First, create the object file:
|
|
|
|
.nf
|
|
|
|
cc <other flags> -c foo.c
|
|
|
|
.fi
|
|
|
|
You must then create a symbol \*(lqexports\*(rq file for the object
|
|
|
|
file:
|
|
|
|
.nf
|
|
|
|
mkldexport foo.o `pwd` > foo.exp
|
|
|
|
.fi
|
|
|
|
Finally, you can create the shared library:
|
|
|
|
.nf
|
|
|
|
ld <other flags> -H512 -T512 -o foo.so -e _nostart \e
|
|
|
|
-bI:.../lib/postgres.exp -bE:foo.exp foo.o \e
|
|
|
|
-lm -lc 2>/dev/null
|
|
|
|
.fi
|
|
|
|
You should look at the Postgres User's Manual for an explanation of this
|
|
|
|
procedure.
|
|
|
|
-->
|
|
|
|
|
1999-10-04 17:18:54 +02:00
|
|
|
After you have created and registered a user-defined
|
1999-10-09 04:26:52 +02:00
|
|
|
function, your work is essentially done.
|
|
|
|
<productname>Postgres</productname>,
|
|
|
|
however, must load the object code
|
|
|
|
(e.g., a <literal>.o</literal> file, or
|
1999-10-04 17:18:54 +02:00
|
|
|
a shared library) that implements your function. As
|
1999-10-09 04:26:52 +02:00
|
|
|
previously mentioned, <productname>Postgres</productname>
|
|
|
|
loads your code at
|
1999-10-04 17:18:54 +02:00
|
|
|
runtime, as required. In order to allow your code to be
|
|
|
|
dynamically loaded, you may have to compile and
|
|
|
|
link-edit it in a special way. This section briefly
|
|
|
|
describes how to perform the compilation and
|
|
|
|
link-editing required before you can load your user-defined
|
1999-10-09 04:26:52 +02:00
|
|
|
functions into a running <productname>Postgres</productname> server.
|
|
|
|
Note that
|
1999-10-04 17:18:54 +02:00
|
|
|
this process has changed as of Version 4.2.
|
1999-10-09 04:26:52 +02:00
|
|
|
</para>
|
1999-10-04 17:18:54 +02:00
|
|
|
|
|
|
|
<!--
|
|
|
|
<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
|
1999-10-09 04:26:52 +02:00
|
|
|
<productname>Postgres</productname> dynamic loading mechanism
|
|
|
|
has been rewritten to use
|
1999-10-04 17:18:54 +02:00
|
|
|
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
|
1999-10-09 04:26:52 +02:00
|
|
|
postprocessed a bit before it can be loaded into
|
|
|
|
<productname>Postgres</productname>. We
|
1999-10-04 17:18:54 +02:00
|
|
|
hope that the large increase in speed and reliability will
|
|
|
|
make up for the slight decrease in convenience.
|
|
|
|
</para>
|
|
|
|
</tip>
|
|
|
|
</para>
|
|
|
|
-->
|
|
|
|
|
|
|
|
<para>
|
|
|
|
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.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
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.
|
1999-07-22 17:11:05 +02:00
|
|
|
<productname>Postgres</productname> does this using
|
1999-10-04 17:18:54 +02:00
|
|
|
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>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-10-04 17:18:54 +02:00
|
|
|
<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.
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-10-04 17:18:54 +02:00
|
|
|
<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>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-10-04 17:18:54 +02:00
|
|
|
<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>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<sect1>
|
|
|
|
<title><acronym>ULTRIX</acronym></title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
It is very easy to build dynamically-loaded object
|
|
|
|
files under ULTRIX. ULTRIX does not have any shared library
|
|
|
|
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>
|
1998-03-01 09:16:16 +01:00
|
|
|
# simple ULTRIX example
|
|
|
|
% cc -G 0 -c foo.c
|
1999-10-04 17:18:54 +02:00
|
|
|
</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>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-10-04 17:18:54 +02:00
|
|
|
<sect1>
|
|
|
|
<title><acronym>DEC OSF/1</acronym></title>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-10-04 17:18:54 +02:00
|
|
|
<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>
|
1998-03-01 09:16:16 +01:00
|
|
|
# simple DEC OSF/1 example
|
|
|
|
% cc -c foo.c
|
|
|
|
% ld -shared -expect_unresolved '*' -o foo.so foo.o
|
1999-10-04 17:18:54 +02:00
|
|
|
</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.
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-10-04 17:18:54 +02:00
|
|
|
<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>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-10-04 17:18:54 +02:00
|
|
|
If the file you specify is
|
|
|
|
not a shared object, the backend will hang!
|
|
|
|
</para>
|
|
|
|
</sect1>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-10-04 17:18:54 +02:00
|
|
|
<sect1>
|
|
|
|
<title>
|
|
|
|
<acronym>SunOS 4.x</acronym>, <acronym>Solaris 2.x</acronym> and
|
1999-07-22 17:11:05 +02:00
|
|
|
<acronym>HP-UX</acronym></title>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-10-04 17:18:54 +02:00
|
|
|
<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>
|
1998-03-01 09:16:16 +01:00
|
|
|
# simple HP-UX example
|
1998-10-18 00:02:21 +02:00
|
|
|
% cc +z +u -c foo.c
|
|
|
|
% ld -b -o foo.sl foo.o
|
1999-10-04 17:18:54 +02:00
|
|
|
</programlisting>
|
|
|
|
</para>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-10-04 17:18:54 +02:00
|
|
|
<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>
|
1998-03-01 09:16:16 +01:00
|
|
|
# simple SunOS 4.x example
|
1998-10-18 00:02:21 +02:00
|
|
|
% cc -PIC -c foo.c
|
|
|
|
% ld -dc -dp -Bdynamic -o foo.so foo.o
|
1999-10-04 17:18:54 +02:00
|
|
|
</programlisting>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-10-04 17:18:54 +02:00
|
|
|
and the equivalent lines under Solaris 2.x are:
|
|
|
|
<programlisting>
|
1998-03-01 09:16:16 +01:00
|
|
|
# simple Solaris 2.x example
|
1998-10-18 00:02:21 +02:00
|
|
|
% cc -K PIC -c foo.c
|
|
|
|
% ld -G -Bdynamic -o foo.so foo.o
|
1999-10-04 17:18:54 +02:00
|
|
|
</programlisting>
|
1998-04-28 16:54:24 +02:00
|
|
|
or
|
1999-10-04 17:18:54 +02:00
|
|
|
<programlisting>
|
1998-04-28 16:54:24 +02:00
|
|
|
# simple Solaris 2.x example
|
1998-10-18 00:02:21 +02:00
|
|
|
% gcc -fPIC -c foo.c
|
|
|
|
% ld -G -Bdynamic -o foo.so foo.o
|
1999-10-04 17:18:54 +02:00
|
|
|
</programlisting>
|
|
|
|
</para>
|
1998-03-01 09:16:16 +01:00
|
|
|
|
1999-10-04 17:18:54 +02:00
|
|
|
<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>
|
1999-07-22 17:11:05 +02:00
|
|
|
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
|
|
Local variables:
|
2000-03-31 05:27:42 +02:00
|
|
|
mode:sgml
|
1999-07-22 17:11:05 +02:00
|
|
|
sgml-omittag:nil
|
|
|
|
sgml-shorttag:t
|
|
|
|
sgml-minimize-attributes:nil
|
|
|
|
sgml-always-quote-attributes:t
|
|
|
|
sgml-indent-step:1
|
|
|
|
sgml-indent-data:t
|
|
|
|
sgml-parent-document:nil
|
|
|
|
sgml-default-dtd-file:"./reference.ced"
|
|
|
|
sgml-exposed-tags:nil
|
2000-03-31 05:27:42 +02:00
|
|
|
sgml-local-catalogs:("/usr/lib/sgml/catalog")
|
1999-07-22 17:11:05 +02:00
|
|
|
sgml-local-ecat-files:nil
|
|
|
|
End:
|
|
|
|
-->
|