 <chapter id="dfunc">
  <title id="dfunc-title">Linking Dynamically-Loaded Functions</title>

<!--
.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.
-->

<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  
     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
     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>
</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.
     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>
</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>
# 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
% 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
</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>

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
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
sgml-local-catalogs:"/usr/lib/sgml/CATALOG"
sgml-local-ecat-files:nil
End:
-->
