1998-07-29 08:50:04 +02:00
|
|
|
<Chapter Id="dfunc">
|
1998-03-01 09:16:16 +01:00
|
|
|
<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
|
1998-04-28 16:54:24 +02:00
|
|
|
link-edit it in a special way. This section briefly
|
1998-03-01 09:16:16 +01:00
|
|
|
describes how to perform the compilation and
|
1998-04-28 16:54:24 +02:00
|
|
|
link-editing required before you can load your user-defined
|
1998-03-01 09:16:16 +01:00
|
|
|
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
|
1998-04-28 16:54:24 +02:00
|
|
|
files under ULTRIX. ULTRIX does not have any shared library
|
1998-03-01 09:16:16 +01:00
|
|
|
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
|
1998-04-28 16:54:24 +02:00
|
|
|
dynamically loaded into <ProductName>Postgres</ProductName>.
|
|
|
|
No additional loading or link-editing must be performed.
|
1998-03-01 09:16:16 +01:00
|
|
|
</Para>
|
|
|
|
</Sect1>
|
|
|
|
|
|
|
|
<Sect1>
|
|
|
|
<Title><Acronym>DEC OSF/1</Acronym></Title>
|
|
|
|
|
|
|
|
<Para>
|
|
|
|
Under DEC OSF/1, you can take any simple object file
|
1998-04-28 16:54:24 +02:00
|
|
|
and produce a shared object file by running the ld command
|
|
|
|
over it with the correct options. The commands to
|
1998-03-01 09:16:16 +01:00
|
|
|
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
|
1998-04-28 16:54:24 +02:00
|
|
|
is fine with <ProductName>Postgres</ProductName>
|
|
|
|
so long as you make sure that the correct
|
1998-03-01 09:16:16 +01:00
|
|
|
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
|
1998-04-28 16:54:24 +02:00
|
|
|
% cc +z +u -c foo.c
|
|
|
|
% ld -b -o foo.sl foo.o
|
1998-03-01 09:16:16 +01:00
|
|
|
</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
|
1998-04-28 16:54:24 +02:00
|
|
|
% cc -PIC -c foo.c
|
|
|
|
% ld -dc -dp -Bdynamic -o foo.so foo.o
|
1998-03-01 09:16:16 +01:00
|
|
|
</ProgramListing>
|
|
|
|
|
|
|
|
and the equivalent lines under Solaris 2.x are:
|
|
|
|
<ProgramListing>
|
|
|
|
# simple Solaris 2.x example
|
1998-04-28 16:54:24 +02:00
|
|
|
% cc -K PIC -c foo.c
|
|
|
|
% ld -G -Bdynamic -o foo.so foo.o
|
|
|
|
</ProgramListing>
|
|
|
|
or
|
|
|
|
<ProgramListing>
|
|
|
|
# simple Solaris 2.x example
|
|
|
|
% gcc -fPIC -c foo.c
|
|
|
|
% ld -G -Bdynamic -o foo.so foo.o
|
1998-03-01 09:16:16 +01:00
|
|
|
</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>
|