aboutsummaryrefslogtreecommitdiff
path: root/doc/src/sgml/dfunc.sgml
blob: 6ee05db813c07851175e1201d811d34c760ab2b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
 <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.
  </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.
      <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:
-->