0.9.1.57: just how hard can "cvs add" be?
[sbcl.git] / doc / internals / foreign-linkage.texinfo
1 @node Foreign Linkage
2 @comment  node-name,  next,  previous,  up
3 @chapter Foreign Linkage
4
5 @menu
6 * Linkage-table::               
7 * Lazy Alien Resolution::       
8 * Callbacks::                   
9 @end menu
10
11 @node Linkage-table
12 @comment  node-name,  next,  previous,  up
13 @section Linkage-table
14
15 Linkage-table allows saving cores with foreign code loaded, and is
16 also utilized to allow references to as-of-yet unknown aliens.
17 @xref{Lazy Alien Resolution}.
18
19 The SBCL implementation is somewhat simplified from the CMUCL one by
20 Timothy Moore, but the basic idea and mechanism remains identical:
21 instead of having addresses from @code{dlsym(3)} in the core, we have
22 addresses to an mmapped memory area (@code{LINKAGE_TABLE_SPACE}) that
23 is initialized at startup to contain jumps & references to the correct
24 addresses, based on information stored on the lisp side in
25 @code{*LINKAGE-INFO*}.
26
27 @subsection Differences to CMUCL 
28
29 CMUCL does lazy linkage for code, keeps all foreign addresses in the
30 linkage-table, and handles the initialization from C. We do eager
31 linkage for everything, maintain a separate
32 @code{*STATIC-FOREIGN-SYMBOLS*} just like on non-linkage-table ports
33 (this allows more code sharing between ports, makes thread-safety
34 easier to achieve, and cuts one jump's worth of overhead from stuff
35 like closure_tramp), and do the initialization from lisp.
36
37 @subsection Nitty Gritty Details 
38
39 Symbols in @code{*STATIC-FOREIGN-SYMBOLS*} are handled the old
40 fashioned way: linkage-table is only used for symbols resolved with
41 @code{dlsym(3)}.
42
43 On system startup @code{FOREIGN-REINIT} iterates through the
44 @code{*LINKAGE-INFO*}, which is a hash-table mapping dynamic foreign
45 names to @code{LINKAGE-INFO} structures, and calls
46 @code{arch_write_linkage_table_jmp}@code{/ref} to write the
47 appropriate entries to the linkage-table.
48
49 When a foreign symbol is referred to, it is first looked for in the
50 @code{*STATIC-FOREIGN-SYMBOLS*}. If not found,
51 @code{ENSURE-FOREIGN-LINKAGE} is called, which looks for the
52 corresponding entry in @code{*LINKAGE-INFO*}, creating one and writing
53 the appropriate entry in the linkage table if necessary.
54
55 @code{FOREIGN-SYMBOL-ADDRESS} and
56 @code{FOREIGN-SYMBOL-ADDRESS-AS-INTEGER} take an optional datap
57 argument, used to indicate that the symbol refers to a variable. In
58 similar fashion there is a new kind of fixup and a new VOP:
59 @code{:FOREIGN-DATAREF} and @code{FOREIGN-SYMBOL-DATAREF-ADDRESS}. The
60 @code{DATAP} argument is automagically provided by the alien interface
61 for normal definitions, but is really needed only for dynamic foreign
62 variables. For those it indicates the need for the indirection either
63 within a conditional branch in @code{FOREIGN-SYMBOL-ADDRESS}, or via
64 @code{:FOREIGN-DATAREF} fixup and
65 @code{FOREIGN-SYMBOL-DATAREF-ADDRESS} VOP: "this address holds the
66 address of the foreign variable, not the variable itself". Within SBCL
67 itself (in the fixups manifest in various VOPs) this fixup type is
68 never used, as all foreign symbols used internally are static.
69
70 One thing worth noting is that @code{FOREIGN-SYMBOL-ADDRESS} and
71 friends now have the potential side-effect of entering information in
72 @code{*LINKAGE-INFO*} and the linkage-table proper: hence it's important to
73 use the correct datap argument even if calling these just to "check if
74 it's there" (like SB-POSIX does).
75
76 @subsection Porting
77
78 @subsubsection Porting to new operating systems 
79
80 Find a memory area for the linkage-table, and add it for the OS in
81 @file{src/compiler/target/parms.lisp} by defining
82 @code{SB!VM:LINKAGE-TABLE-SPACE-START} and
83 @code{SB!VM:LINKAGE-TABLE-SPACE-END}. See existing ports and CMUCL for
84 examples.
85
86 @subsubsection Porting to new architextures 
87
88 Write @code{arch_write_linkage_table_jmp} and  @code{arch_write_linkage_table_ref}.
89
90 Write @code{FOREIGN-SYMBOL-DATAREF} VOP.
91
92 Define correct @code{SB!VM:LINKAGE-TABLE-ENTRY-SIZE} in
93 @file{src/compiler/target/parms.lisp}.
94
95 @page
96 @node Lazy Alien Resolution
97 @comment  node-name,  next,  previous,  up
98 @section Lazy Alien Resolution
99
100 On linkage-table ports SBCL is able to deal with forward-references to
101 aliens -- which is to say, compile and load code referring to aliens
102 before the shared object containing the alien in question has been
103 loaded.
104
105 This is handled by @code{GET-DYNAMIC-FOREIGN-SYMBOL-ADDRESS}, which
106 first tries to resolve the address in the loaded shared objects, but
107 failing that records the alien as undefined and returns the address of
108 a read/write/execute protected guard page for variables, and address
109 of @code{undefined_alien_function} for routines. These are in turn
110 responsible for catching attempts to access the undefined alien, and
111 signalling the appropriate error.
112
113 These placeholder addresses get recorded in the linkage-table.
114
115 When new shared objects are loaded @code{UPDATE-LINKAGE-TABLE} is
116 called, which in turn attempts to resolve all currently undefined
117 aliens, and registers the correct addresses for them in the
118 linkage-table.
119
120 @page
121 @node Callbacks
122 @comment  node-name,  next,  previous,  up
123 @section Callbacks
124
125 SBCL is capable of providing C with linkage to Lisp -- the upshot of which is that
126 C-functions can call Lisp functions thru what look like function pointers to C.
127
128 These ``function pointers'' are called Alien Callbacks. An alien
129 callback sequence has 4 parts / stages / bounces:
130
131 @itemize
132 @item Assembler Wrapper
133
134 saves the arguments from the C-call according to the alien-fun-type of
135 the callback, and calls #'ENTER-ALIEN-CALLBACK with the index
136 indentifying the callback, a pointer to the arguments copied on the
137 stack and a pointer to return value storage. When control returns to
138 the wrapper it returns the value to C. There is one assembler wrapper
139 per callback.[1] The SAP to the wrapper code vector is what is passed
140 to foreign code as a callback.
141
142 The Assembler Wrapper is generated by
143 @code{ALIEN-CALLBACK-ASSEMBLER-WRAPPER}.
144
145 @item #'ENTER-ALIEN-CALLBACK
146
147 pulls the Lisp Trampoline for the given index, and calls it with the
148 argument and result pointers.
149
150 @item Lisp Trampoline
151
152 calls the Lisp Wrapper with the argument and result pointers, and the
153 function designator for the callback. There is one lisp trampoline per
154 callback.
155
156 @item Lisp Wrapper
157
158 parses the arguments from stack, calls the actual callback with the
159 arguments, and saves the return value at the result pointer. The lisp
160 wrapper is shared between all the callbacks having the same same
161 alien-fun-type.
162
163 @end itemize
164
165 [1] As assembler wrappers need to be allocated in static addresses and
166 are (in the current scheme of things) never released it might be worth
167 it to split it into two parts: per-callback trampoline that pushes the
168 index of the lisp trampoline on the stack, and jumps to the
169 appropriate assembler wrapper. The assembler wrapper could then be
170 shared between all the callbacks with the same alien-fun-type. This
171 would amortize most of the static allocation costs between multiple
172 callbacks.