![]() |
![]() |
![]() |
libcapsule Reference Manual | ![]() |
---|---|---|---|---|
Top | Description |
struct capsule; typedef capsule_addr; void capsule_close (capsule cap
); void * capsule_external_dlopen (const char *file
,int flag
); void * capsule_external_dlsym (void *handle
,const char *symbol
); char * capsule_get_prefix (const char *dflt
,const char *soname
); capsule capsule_init (const char *soname
); struct capsule_item; struct capsule_metadata; return capsule_shim_dlopen (cap Param1
,filename Param2
,flag Param3
); void capsule_shim_free (const capsule cap
,void *ptr
); return capsule_shim_realloc (cap Param1
,ptr Param2
,size Param3
);
struct capsule { void *dl_handle; struct { ptr_list *all; ptr_list *some; } seen; capsule_metadata *meta; capsule_namespace *ns; capsule_item internal_wrappers[7]; };
A handle returned by capsule_init: A required parameter for all other capsule calls.
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.
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.
|
a capsule handle as returned by capsule_init()
|
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.
|
A soname, filename or path as passed to dlopen()
|
|
The dl flags, as per dlopen()
|
Returns : |
The handle returned by `dlopen` |
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.
|
A dl handle, as passed to dlsym()
|
|
A symbol name, as passed to dlsym()
|
Returns : |
The address associated with symbol (as if for `dlsym`), or NULL
|
char * capsule_get_prefix (const char *dflt
,const char *soname
);
|
A default capsule prefix path |
|
The soname of the library we are encapsulating |
Returns : |
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. |
capsule capsule_init (const char *soname
);
|
the soname of the target library |
Returns : |
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. |
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 NULL entry. [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 name is NULL . [array zero-terminated=1]
|
Implementation of the same API as `dlopen` | |
void capsule_shim_free (const capsule cap
,void *ptr
);
Tries to safely route an allocated pointer to the correct free()
implementation.
|
The capsule from which `free` was called |
|
The pointer to be freed |