[ Home ]
SBCL Internals

The pages on this CLiki-driven site can be edited by anybody at any time. No warranty of any kind can therefore be made; any implied warranties of merchantability or fitness for a particular purpose are expressly disclaimed
[ Home ] [ Recent Changes ] [ About CLiki ] [ Text Formatting ]

Overview

Linkage-table allows saving cores with foreign code loaded.

The SBCL implementation is somewhat simplified from the CMUCL one by T. Moore, but the basic idea and mechanism remains identical: instead of having addresses from dlsym in the core/fasls, we have addresses to an mmapped memory area (LINKAGE_TABLE_SPACE) that is initialized at startup to contain jumps & references to the correct addresses, based on information stored on the lisp side in *LINKAGE-INFO*.

Differences to CMUCL

CMUCL does lazy linkage for code, keeps all foreign addresses in the linkage-table, and handles the initialization from C. We do eager linkage for everything, maintain a separate *STATIC-FOREIGN-SYMBOLS* just like on non-linkage-table ports (this allows more code sharing, makes thread-safety easier to achieve, and cuts one jump's worth of overhead from stuff like closure_tramp), and do the initialization from lisp.

Nitty gritty details

Symbols in *STATIC-FOREIGN-SYMBOLS* are handled the old fashioned way: linkage-table is only used for symbols resolved with dlsym.

On system startup FOREIGN-REINIT iterates through the *LINKAGE-INFO*, which is a hash-table mapping dynamic foreign names to LINKAGE-INFO structures, and calls arch_write_linkage_table_jmp/ref to write the appropriate entries to the linkage-table.

When a foreign symbol is referred to, it is first looked for in the *STATIC-FOREIGN-SYMBOLS*. If not found, ENSURE-FOREIGN-LINKAGE is called, which looks for the corresponding entry in *LINKAGE-INFO*, creating one and writing the appropriate entry in the linkage table if necessary.

FOREIGN-SYMBOL-ADDRESS and FOREIGN-SYMBOL-ADDRESS-AS-INTEGER take an optional datap argument, used to indicate that the symbol refers to a variable. In similar fashion there is a new kind of fixup and a new VOP: :FOREIGN-DATAREF and FOREIGN-SYMBOL-DATAREF-ADDRESS. The datap argument is automagically provided by the alien interface for normal definitions, but is really needed only for dynamic foreign variables. For those it indicates the need for the indirection either within a conditional branch in FOREIGN-SYMBOL-ADDRESS, or via :FOREIGN-DATAREF fixup and FOREIGN-SYMBOL-DATAREF-ADDRESS VOP: "this address holds the address of the foreign variable, not the variable itself". Within SBCL itself (in the fixups manifest in various VOPs) this fixup type is never used, as all foreign symbols used internally are static.

One thing worth noting is that FOREIGN-SYMBOL-ADDRESS and friends now have the potential side-effect of entering information in *LINKAGE-INFO* and the linkage-table proper: hence it's important to use the correct datap argument even if calling these just to "check if it's there" (like SB-POSIX does).

Existing ports

Porting to new operating systems

Porting to new architextures

Future Work

Despite the benefits of keeping *STATIC-FOREIGN-SYMBOLS* around it would simplify other parts of SBCL-as-a-whole if we went always thru the linkage table when calling C. One relatively simple way to do this would be to reserve space from the start of linkage table for static symbols, and initialize these from C. So that the C-side would not have to look in the core to know what to link and where we could output eg. a header file containing the names and linkage table entry numbers of the static symbols during genesis.

Personally, I (NS) would prefer to delay such stuff till all the ports, or at least all dlopen ports support linkage table, in order to avoid keeping duplicate mechanisms around.


This page is linked from: Darwin   One Point Zero  

CLiki pages can be edited by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively