Top | ![]() |
![]() |
![]() |
![]() |
capsule | capsule_init () |
return | capsule_shim_dlopen () |
void * | capsule_external_dlsym () |
void * | capsule_external_dlopen () |
void | capsule_close () |
char * | capsule_get_prefix () |
void | capsule_shim_free () |
return | capsule_shim_realloc () |
capsule
capsule_init (const char *soname
);
a capsule handle.
Does any initialisation necessary to use libcapsule’s functions.
Initialises internal accounting structures within the capsule
and triggers the metadata setup if this caspsule has been
acquired via dlopen()
, and finishes registering the capsule
proxy with libcapsule itself.
void * capsule_external_dlsym (void *handle
,const char *symbol
);
An implementation of dlsym
, used when it is called by the executable
or by a library outside the capsule.
Some libraries have a use pattern in which their caller/user
uses dlsym()
to obtain symbols rather than using those symbols
directly in its own code (libGL is an example of this).
Since the target library may have a different symbol set than the
one the libcapsule proxy shim was generated from we can’t rely on
dlsym()
finding those symbols in the shim’s symbol table.
Instead we must intercept dlsym()
calls made outside the capsule
and attempt to look for the required symbol in the namespace defined
by the active capsules first - If the required symbol is found there
AND is from one of the DSO names present in the exported list then that
symbol is returned. If either of those conditions is not met then
a normal dlsym call with the passed handle is made.
This function provides the functionality described above, and is normally used automatically by libcapsule. It is exposed as API in case a libcapsule proxy library needs to provide its own specialised symbol lookup mechanism.
void * capsule_external_dlopen (const char *file
,int flag
);
An implementation of dlopen
, used when it is called by the executable
or by a library outside the capsule.
This wrapper is meant to be replace normal calls to dlopen()
made by the
main program or a non-capsule library - it is necessary because en ELF
object loaded by dlopen()
may need us to trigger the _capsule_relocate()
operation in order to make sure its GOT entries are correctly updated.
This wrapper carries out a normal dlopen()
and then re-triggers the
initial _capsule_relocate()
call immediately, before returning
the same value that dlopen()
would have, given the same file
and flag
arguments.
void
capsule_close (capsule cap
);
This function should be called from a capsule proxy library’s destructor:
Its job is to clean up capsule-specific allocated memory and metadata when
a capsule proxy is discarded via dlclose()
, and ensure that libproxy itself
won’t try to access any related invalidated memory afterwards.
char * capsule_get_prefix (const char *dflt
,const char *soname
);
A newly allocated char * pointing to the prefix path
libcapsule provides a proxy to a library, potentially from a foreign filesystem tree (found at, for example, ‘/host’).
Since it is useful for this location to be overrideable at startup on a per-target-library basis this function standardises the prefix selection algorithm as follows:
An environment variable based on soname
:
libGL.so.1 would map to CAPSULE_LIBGL_SO_1_PREFIX
If that is unset, the CAPSULE_PREFIX environment variable
Next: The default to the value passed in dflt
And if all that failed, NULL (which is internally equivalent to "/")
The environment variables are ignored if the process is privileged (setuid, setgid, given special capabilities, or marked as privileged by a LSM), or if libcapsule was compiled against a glibc version older than 2.17.
Although the value is newly allocated it will typically be cached in a structure that needs to survive the entire lifespan of the running program, so freeing it is unlikely to be a concern.
void capsule_shim_free (const capsule cap
,void *ptr
);
Tries to safely route an allocated pointer to the correct free()
implementation.
typedef ElfW(Addr) capsule_addr;
Identical to an ElfW(Addr) from libelf. You may treat this as equivalent to a void * when assigning to it.
typedef struct _capsule *capsule;
A handle returned by capsule_init: A required parameter for all other capsule calls.
struct capsule_item { const char *name; capsule_addr real; capsule_addr shim; };
real
and shim
may typically be left empty by the shim library.
Both slots will typically hold the correct values after a successful capsule… call. While this is sometimes important internally it is not usually of interest to the caller (except maybe for debugging)
The name of the symbol to be relocated |
||
capsule_addr |
address of the ‘real’ symbol in the target library |
|
capsule_addr |
address of the ‘fake’ symbol in the proxy library |
struct capsule_metadata { const int capsule_abi; const char *soname; const char *default_prefix; const char **exclude; const char **export; capsule_item *items; void *(*int_dlopen) (const char *filename, int flag); void (*int_free) (void *ptr); void *(*int_realloc) (void *ptr, size_t size); };
This struct allows libcapsule proxy libraries to statically declare metadata about themselves that libcapsule needs at link time in order to function properly.
The capsule_item entries in items
need only specify the symbol
name: The shim and real fields will be populated automatically if they
are not pre-filled (this is the normal use case, as it would be unusual
to know these value in advance).
Version of the libcapsule ABI implmented by this struct |
||
The soname of the encapsulated library |
||
The default root location of the filesystem from which the encapsulated library should be loaded |
||
an array of char *, each
specifying a DSO not to load, terminated by a |
[array zero-terminated=1] | |
an array of char *, each specifying a DSO whose symbols should be exported from this capsule. |
[array zero-terminated=1] | |
capsule_item * |
Array of capsule_item
specifying which symbols to export, terminated by a
capsule_item whose |
[array zero-terminated=1] |
Implementation of the same API as |
||