⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dlib.c

📁 linux下用PCMCIA无线网卡虚拟无线AP的程序源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * libdl.c *  * Functions required for dlopen et. al. */#include <stdlib.h>#include <features.h>#include "dlfcn.h"#include "sysdep.h"#include "syscall.h"#include "hash.h"#include "string.h"#include "linuxelf.h"extern int _dl_error_number;extern struct r_debug *_dl_debug_addr;extern void *(*_dl_malloc_function) (size_t size);static int do_fixup(struct elf_resolve *tpnt, int flag);static int do_dlclose(void *, int need_fini);void *_dlopen(char *filename, int flag);const char *_dlerror(void);void *_dlsym(void *, char *);int _dlclose(void *);int _dladdr(void *__address, Dl_info * __dlip);static const char *dl_error_names[] = {	"",	"File not found",	"Unable to open /dev/zero",	"Not an ELF file",#if defined (__i386__)	"Not i386 binary",#elif defined (__sparc__)	"Not sparc binary",#elif defined (__mc68000__)	"Not m68k binary",#else	"Unrecognized binary type",#endif	"Not an ELF shared library",	"Unable to mmap file",	"No dynamic section",#ifdef ELF_USES_RELOCA	"Unable to process REL relocs",#else	"Unable to process RELA relocs",#endif	"Bad handle",	"Unable to resolve symbol"};static void dl_cleanup(void) __attribute__ ((destructor));static void dl_cleanup(void){	struct dyn_elf *d;	for (d = _dl_handles; d; d = d->next_handle)		if (d->dyn->libtype == loaded_file && d->dyn->dynamic_info[DT_FINI]) {			(* ((int (*)(void)) (d->dyn->loadaddr + d->dyn->dynamic_info[DT_FINI]))) ();			d->dyn->dynamic_info[DT_FINI] = 0;		}}void *_dlopen(char *libname, int flag){	struct elf_resolve *tpnt, *tfrom;	struct dyn_elf *rpnt;	struct dyn_elf *dyn_chain;	struct dyn_elf *dpnt;	static int dl_init = 0;	char *from;	void (*dl_brk) (void);	int (*dl_elf_init) (void);	from = __builtin_return_address(0);	/* Have the dynamic linker use the regular malloc function now */	if (!dl_init) {		dl_init++;		_dl_malloc_function = malloc;	}	/* Cover the trivial case first */	if (!libname)		return _dl_symbol_tables;#ifdef USE_CACHE	_dl_map_cache();#endif	/*	 * Try and locate the module we were called from - we	 * need this so that we get the correct RPATH.  Note that	 * this is the current behavior under Solaris, but the	 * ABI+ specifies that we should only use the RPATH from	 * the application.  Thus this may go away at some time	 * in the future.	 */	tfrom = NULL;	for (dpnt = _dl_symbol_tables; dpnt; dpnt = dpnt->next) {		tpnt = dpnt->dyn;		if (tpnt->loadaddr < from			&& (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr))			tfrom = tpnt;	}	if (!(tpnt = _dl_load_shared_library(0, tfrom, libname))) {#ifdef USE_CACHE		_dl_unmap_cache();#endif		return NULL;	}	tpnt->usage_count++;	dyn_chain = rpnt = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));	_dl_memset(rpnt, 0, sizeof(*rpnt));	rpnt->dyn = tpnt;	rpnt->flags = flag;	if (!tpnt->symbol_scope)		tpnt->symbol_scope = dyn_chain;	rpnt->next_handle = _dl_handles;	_dl_handles = rpnt;	/*	 * OK, we have the requested file in memory.  Now check for	 * any other requested files that may also be required.	 */	  {	    struct elf_resolve *tcurr;	    struct elf_resolve * tpnt1;	    Elf32_Dyn * dpnt;	    char * lpnt;	    tcurr = tpnt;	    do{	      for(dpnt = (Elf32_Dyn *) tcurr->dynamic_addr; dpnt->d_tag; dpnt++)		{	  		  if(dpnt->d_tag == DT_NEEDED)		    {		      lpnt = tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] + 			dpnt->d_un.d_val;		      if(!(tpnt1 = _dl_load_shared_library(0, tcurr, lpnt)))			goto oops;		      rpnt->next = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));		      _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));		      rpnt = rpnt->next;		      tpnt1->usage_count++;		      if (!tpnt1->symbol_scope) tpnt1->symbol_scope = dyn_chain;		      rpnt->dyn = tpnt1;		    };		}	      	      tcurr = tcurr->next;	    } while(tcurr);	  }	 	/*	 * OK, now attach the entire chain at the end	 */	rpnt->next = _dl_symbol_tables;	if (do_fixup(tpnt, flag)) {		_dl_error_number = DL_NO_SYMBOL;		goto oops;	}	dl_brk = (void (*)()) _dl_debug_addr->r_brk;	if (dl_brk != NULL) {		_dl_debug_addr->r_state = RT_ADD;		(*dl_brk) ();		_dl_debug_addr->r_state = RT_CONSISTENT;		(*dl_brk) ();	}	for (rpnt = dyn_chain; rpnt; rpnt = rpnt->next) {		tpnt = rpnt->dyn;		/* Apparently crt1 for the application is responsible for handling this.		 * We only need to run the init/fini for shared libraries		 */		if (tpnt->libtype == elf_executable)			continue;		if (tpnt->init_flag & INIT_FUNCS_CALLED)			continue;		tpnt->init_flag |= INIT_FUNCS_CALLED;		if (tpnt->dynamic_info[DT_INIT]) {			dl_elf_init = (int (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]);			(*dl_elf_init) ();		}	}#ifdef USE_CACHE	_dl_unmap_cache();#endif	return (void *) dyn_chain;  oops:	/* Something went wrong.  Clean up and return NULL. */#ifdef USE_CACHE	_dl_unmap_cache();#endif	do_dlclose(dyn_chain, 0);	return NULL;}static int do_fixup(struct elf_resolve *tpnt, int flag){	int goof = 0;	if (tpnt->next)		goof += do_fixup(tpnt->next, flag);	if (tpnt->dynamic_info[DT_REL]) {#ifdef ELF_USES_RELOCA		goof++;#else		if (tpnt->init_flag & RELOCS_DONE)			return goof;		tpnt->init_flag |= RELOCS_DONE;		goof += _dl_parse_relocation_information(tpnt, 			tpnt->dynamic_info[DT_REL], tpnt->dynamic_info[DT_RELSZ], 0);#endif	}	if (tpnt->dynamic_info[DT_RELA]) {#ifdef ELF_USES_RELOCA		if (tpnt->init_flag & RELOCS_DONE)			return goof;		tpnt->init_flag |= RELOCS_DONE;		goof += _dl_parse_relocation_information(tpnt, 			tpnt->dynamic_info[DT_RELA], tpnt->dynamic_info[DT_RELASZ], 0);#else		goof++;#endif	}	if (tpnt->dynamic_info[DT_JMPREL]) {		if (tpnt->init_flag & JMP_RELOCS_DONE)			return goof;		tpnt->init_flag |= JMP_RELOCS_DONE;		if (flag == RTLD_LAZY)			_dl_parse_lazy_relocation_information(tpnt, 				tpnt->dynamic_info[DT_JMPREL], 				tpnt->dynamic_info[DT_PLTRELSZ], 0);		else			goof += _dl_parse_relocation_information(tpnt, 				tpnt->dynamic_info[DT_JMPREL], 				tpnt->dynamic_info[DT_PLTRELSZ], 0);	};	return goof;}void *_dlsym(void *vhandle, char *name){	struct elf_resolve *tpnt, *tfrom;	struct dyn_elf *handle;	char *from;	struct dyn_elf *rpnt;	void *ret;	handle = (struct dyn_elf *) vhandle;	/* First of all verify that we have a real handle	   of some kind.  Return NULL if not a valid handle. */	if (handle == NULL)		handle = _dl_symbol_tables;	else if (handle != RTLD_NEXT && handle != _dl_symbol_tables) {		for (rpnt = _dl_handles; rpnt; rpnt = rpnt->next_handle)			if (rpnt == handle)				break;		if (!rpnt) {			_dl_error_number = DL_BAD_HANDLE;			return NULL;		}	} else if (handle == RTLD_NEXT) {		/*		 * Try and locate the module we were called from - we		 * need this so that we know where to start searching		 * from.  We never pass RTLD_NEXT down into the actual		 * dynamic loader itself, as it doesn't know		 * how to properly treat it.		 */		from = __builtin_return_address(0);		tfrom = NULL;		for (rpnt = _dl_symbol_tables; rpnt; rpnt = rpnt->next) {			tpnt = rpnt->dyn;			if (tpnt->loadaddr < from				&& (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr)) {				tfrom = tpnt;				handle = rpnt->next;			}		}	}	ret = _dl_find_hash(name, handle, 1, NULL, 1);	/*	 * Nothing found.	 */	if (!ret)		_dl_error_number = DL_NO_SYMBOL;	return ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -