📄 dynamic_lib.c
字号:
/* * dynamic_lib.c: Dynamic Library Initialization for Unix * Author: James Kempf * Created On: Fri Apr 5 08:34:47 1991 * Last Modified By: James Kempf * Last Modified On: Tue Aug 6 15:00:47 1991 * Update Count: 14 *//* Exports: * void _initialize_dynamic_libs() * void _finalize_dynamic_libs() * * In case of static linking these are just dummy functions. * In case of dynamic shared objects (libraries): * The dynamic shared objects are already linked with the main program and * control was passed from `start' (in `crt0.o') to `_main' and from that * to `__main' in `drt0.o'. * * The functions here have to do the _initialization_ and _finalization_ of * all the dynamic shared objects (the initialization and finalization of the * main program is done by the calling function). */#ifndef DYNAMIC_LIBS/* * static case */void _initialize_dynamic_libs() {}void _finalize_dynamic_libs() {}#else/* * dynamic case * * */#include <sys/types.h>#include <link.h>#include <dlfcn.h>#include <malloc.h>#include "dldefs.h"extern struct link_dynamic _DYNAMIC;/* Unix linker looks up global symbols in first one down the line (?? H.S.)*/const char CTOR_LIST_NAME[] = "___CTOR_LIST__";const char DTOR_LIST_NAME[] = "___DTOR_LIST__";extern int * __function_list_addr;/* "Handles" to the dynamic shared objects can be obtained via the _DYNAMIC * structure; but since be have to do finalization in the opposite direction * as initialization, we construct a doubly linked list of these handles. */struct _sll { struct _sll* next; struct _sll* prev; struct link_map* lmp;};#define NULLP (struct _sll*)0static struct _sll* _sll_head = NULLP;static struct _sll* _sll_tail = NULLP;static inlinevoid new(struct link_map* nlmp){ struct _sll * this = (struct _sll *) malloc (sizeof (struct _sll)); this->lmp = nlmp; this->next = NULLP; this->prev = NULLP; if( !_sll_head ) { _sll_head = this; _sll_tail = this; } else { this->prev = _sll_tail; _sll_tail->next = this; _sll_tail = this; }}staticvoid build_sll()/* * -- Build doubly linked list of dynamic libraries */{ /* extern struct link_dynamic _DYNAMIC; */ struct link_dynamic_2* ldd; struct link_map* lmp; ldd = _DYNAMIC.ld_un.ld_2; for( lmp = ldd->ld_loaded; lmp; lmp = lmp->lm_next ) { new (lmp); }}staticvoid delete_sll()/* * -- Delete doubly linked list of dynamic libraries */{ struct _sll * this = _sll_tail; struct _sll * prev; while ( this ) { prev = this->prev; free ( this); this = prev; }}staticvoid __do_dynamic_lib( struct _sll * sllp, char * fname, const char* lname, int forwardp )/* * -- Fake out dlsym() into giving me the names of any initialization or * finalization functions and call them. */{ struct _sll * p = sllp; void * dobj; void_fn f; while( p ) { /* Set up the dl_object first */ dobj = dlopen( p->lmp->lm_name, 1 ); /* Call dlsym() looking for the function symbol. */ f = (void_fn)dlsym( dobj, fname); /* * Because the Unix dynamic linker resolves global * symbols in the shared library to symbols in main, * we need to use this kludge to get the address of * the function list to the initialization and * finalization functions. If there is no symbol * for the CTOR or DTOR lists, we call the function * anyway, because the library creator may have written their * own initialization function. */ __function_list_addr = (int*)dlsym((void*)dobj,lname); /* If nonnull, call the function. */ if( f ) { f(); } /*Increment to next list entry, depending on flag.*/ p = ( forwardp ? p->next : p->prev); }} void _initialize_dynamic_libs()/* _initialize_dynamic_libs * * -- Initialize the dynamically linked libraries. */{ build_sll(); __do_dynamic_lib( _sll_tail, INIT_FUN_NAME, CTOR_LIST_NAME, 0); delete_sll();}void _finalize_dynamic_libs()/* * _finalize_dynamic_libs * * -- Finalize the dynamically linked libraries. */{ /* Have to rebuild sll list, the user may have added something */ _sll_head = _sll_tail = NULLP; build_sll(); __do_dynamic_lib( _sll_head, FINI_FUN_NAME, DTOR_LIST_NAME, 1); delete_sll();}#endif /* DYNAMIC_LIBS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -