<<Index>>
The role of the XFLAT shared library support is: To provide support for share-able libraries for the MMU-less platform while minimizing visibility to the programming. This this case, it is what you don't see that improves the implementation.
The basic shared library support is provided through the XFLAT dynamic shared library, ld-xflat.so. This dynamic loader is analogous to the ELF dynamic loader, ld.so that you find on you Linux workstation under /lib. In that ELF environment, these "transparent" features of ld.so are augmented by several user-visible interfaces provided in the companion shared library libdl.so (also found under /lib on your PC). This ELF shared library is highly integrated with ld.so and provides user accessible interfaces as defined in the header file dlfcn.h.
The XFLAT shared library package supports an extended subset of the interfaces provided by the standard, Linux, ELF dlfcn.h. The XFLAT interfaces are described below.
Prototype:
void *dlopen(const char *filename, int flag);
Description: dlopen() loads a dynamic library from the file named by the null-terminated string filename and returns an opaque "handle" for the dynamic library. If the library is already loaded, dlopen returns a reference to the existing library. If filename is not an absolute path (i.e., it does not contain a '/), then the file is searched for in a default* set of paths. The flags (RTLD_LAZY, RTLD_GLOBAL, and RTLD_NOW are ignored).
Prototype:
const char *dlerror(void);
Description: dlerror() is NOT supported in the current XFLAT implementation! The purpose of dlerror is to provide human readable string describing the most recent error that occurred from any of the dl routines.
Prototype:
void *dlsym(void *handle, const char *symbol);
Description: dlsym() takes a "handle" of a dynamic library returned by dlopen and the null-terminated symbol name, and returns the address where that symbol is loaded. If the symbol is not found, dlsym returns NULL.
Prototype:
int dlclose (void *handle);
Description: dlclose() is NOT supported in the current XFLAT implementation! The purpose of dlcose is unload shared libraries that are no longer needed by a process. This capability requires: (1) logic to track the shared libraries loaded by a shared library (and of the libraries loaded by those libraries, etc.), (2) reference counting to determine if there are still references to a shared library, and (3) logic to clean up the resources consumed by the shared library. These capabilities are not included in XFLAT at this writing.
Prototype:
void *dlmodule(void *fcnptr);
Description: dlmodule() is a NON-standard, internal dlfcn.h interface! Given the raw address of a function (a function pointer), dlmodule returns a handle to the module that exports the function symbol. If the module containing the function address is not found, dlmodule() will return NULL. The primary usage of dlmodule() is for XFLAT function pointer support through the non-standard, dlinitdesc() or dlmkdesc() inline functions described below.
Prototype:
void *dlfcncall(struct dlfcndesc *fcndesc, void *arg, ...);
Description: dlfcncall() is a NON-standard dlfcn.h interface! Give an instance of the dlfcndesc structure, dlfcncall() will perform the intermodule function call. The return value of dlfcncall() is the return value of the called function (dlfnccall() will assert any failures). dlfcncall() can only be used with pointers to functions that conform to the requirements of type dlfcnptr_t:
struct dlfcndesc { dlfcnptr_t fcnptr; /* The address of the function */ void *module; /* Handle to the module that exports the function */ };
The fcnptr is simply the value of the function pointer as it is know to the code at compile time. module is the handle to the module as would be obtained from dlmodule() at runtime. The inline helper functions, dlinitdesc() or dlmkdesc() are provided to simplify construction of the dlfcndesc structure.
dlfcncall() will call the function pointer as though it were the following type:
typedef void * (*dlfcnptr_t)(void *arg1, void *arg2, void *arg3, void *arg4);
Prototype:
static inline void dlinitdesc(void *fcnptr, struct dlfcndesc *fcndesc)
Description: dlinitdesc() is a NON-standard in-line function! Given a static reference to a struct dlfcndesc and a function address, this helper function will initialize the structure suitable for use with dlfcncall. For example:
void foo(int (*fcndesc)(int arg));
int bar(int arg)
struct dlfcndesc foothunk; dlinitdesc(bar, &foothunk); foo((void*)foothunk);
Warning: dlinitdesc() may return a NULL value for the struct dlfcndesc value on failure conditions.
Prototype:
static inline struct dlfcndesc * dlmkdesc(void *fcnptr)
Description: dlmkdesc() is another NON-standard in-line function! This helper function is very similar to dlinitdesc(), but supports a slightly differ usage model: dlmkdesc() will allocate a function pointer structure (using malloc), initialize it, and return a reference to the structure. This inline function could be used as follows.
void foo(int (*fcndesc)(int arg));
int bar(int arg)
foo((void*)dlmkdesc(bar));
dlmkdesc() will return NULL on any failures.
Prototype:
static inline void dlfreedesc(struct dlfcndesc *fcndesc)
Description: dlmkdesc) is a NON-standard in-line function! dlfreedesc() releases a function description structure allocated by dlmkdesc. Use of dlfreedesc() (vs. calling free()) is recommended in case a different allocator is used in the future.
<<Index>>
Copyright 2002 by Cadenux, LLC. All rights reserved.