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

📄 readelflib1.c

📁 linux下用PCMCIA无线网卡虚拟无线AP的程序源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Load an ELF sharable library into memory.   Copyright (C) 1993-1996, Eric Youngdale.   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2, or (at your option)   any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  *//* This file contains the helper routines to load an ELF sharable   library into memory and add the symbol table info to the chain. */#include <elf.h>#include "linuxelf.h"#include "string.h"#include "hash.h"#include "sysdep.h"#include "syscall.h"#include <sys/mman.h>#ifdef USE_CACHE#include "../config.h"#endifextern char *_dl_progname;#ifdef USE_CACHEstatic caddr_t _dl_cache_addr = NULL;static size_t _dl_cache_size = 0;int _dl_map_cache(void){	int fd;	struct stat st;	header_t *header;	libentry_t *libent;	int i, strtabsize;	if (_dl_cache_addr == (caddr_t) - 1)		return -1;	else if (_dl_cache_addr != NULL)		return 0;	if (_dl_stat(LDSO_CACHE, &st)		|| (fd = _dl_open(LDSO_CACHE, O_RDONLY)) < 0) {		_dl_dprintf(2, "%s: can't open cache '%s'\n", _dl_progname, LDSO_CACHE);		_dl_cache_addr = (caddr_t) - 1;	/* so we won't try again */		return -1;	}	_dl_cache_size = st.st_size;	_dl_cache_addr = (caddr_t) _dl_mmap(0, _dl_cache_size, PROT_READ, MAP_SHARED, fd, 0);	_dl_close(fd);	if (_dl_cache_addr == (caddr_t) - 1) {		_dl_dprintf(2, "%s: can't map cache '%s'\n", 			_dl_progname, LDSO_CACHE);		return -1;	}	header = (header_t *) _dl_cache_addr;	if (_dl_cache_size < sizeof(header_t) ||		_dl_memcmp(header->magic, LDSO_CACHE_MAGIC, LDSO_CACHE_MAGIC_LEN)		|| _dl_memcmp(header->version, LDSO_CACHE_VER, LDSO_CACHE_VER_LEN)		|| _dl_cache_size <		(sizeof(header_t) + header->nlibs * sizeof(libentry_t))		|| _dl_cache_addr[_dl_cache_size - 1] != '\0') 	{		_dl_dprintf(2, "%s: cache '%s' is corrupt\n", _dl_progname, 			LDSO_CACHE);		goto fail;	}	strtabsize = _dl_cache_size - sizeof(header_t) -		header->nlibs * sizeof(libentry_t);	libent = (libentry_t *) & header[1];	for (i = 0; i < header->nlibs; i++) {		if (libent[i].sooffset >= strtabsize || 			libent[i].liboffset >= strtabsize) 		{			_dl_dprintf(2, "%s: cache '%s' is corrupt\n", _dl_progname, LDSO_CACHE);			goto fail;		}	}	return 0;  fail:	_dl_munmap(_dl_cache_addr, _dl_cache_size);	_dl_cache_addr = (caddr_t) - 1;	return -1;}int _dl_unmap_cache(void){	if (_dl_cache_addr == NULL || _dl_cache_addr == (caddr_t) - 1)		return -1;#if 1	_dl_munmap(_dl_cache_addr, _dl_cache_size);	_dl_cache_addr = NULL;#endif	return 0;}#endif/* This function's behavior must exactly match that  * in uClibc/ldso/util/ldd.c */static struct elf_resolve * search_for_named_library(char *name, int secure, const char *path_list){	int i, count = 0;	char *path, *path_n;	char mylibname[2050];	struct elf_resolve *tpnt1;	/* We need a writable copy of this string */	path = _dl_strdup(path_list);	if (!path) {		_dl_dprintf(2, "Out of memory!\n");		_dl_exit(0);	}		/* Unlike ldd.c, don't bother to eliminate double //s */	/* Replace colons with zeros in path_list and count them */	for(i=_dl_strlen(path); i > 0; i--) {		if (path[i]==':') {			path[i]=0;			count++;		}	}	path_n = path;	for (i = 0; i < count; i++) {		_dl_strcpy(mylibname, path_n); 		_dl_strcat(mylibname, "/"); 		_dl_strcat(mylibname, name);		if ((tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0)) != NULL)		    return tpnt1;		path_n += (_dl_strlen(path_n) + 1);	}	return NULL;}/* * Used to return error codes back to dlopen et. al. */unsigned long _dl_error_number;unsigned long _dl_internal_error_number;struct elf_resolve *_dl_load_shared_library(int secure, 	struct elf_resolve *tpnt, char *full_libname){	char *pnt;	struct elf_resolve *tpnt1;	char *libname;	_dl_internal_error_number = 0;	/* quick hack to ensure mylibname buffer doesn't overflow.  don't 	   allow full_libname or any directory to be longer than 1024. */	if (_dl_strlen(full_libname) > 1024)		goto goof;	pnt = libname = full_libname;	while (*pnt) {		if (*pnt == '/')			libname = pnt + 1;		pnt++;	}	/* If the filename has any '/', try it straight and leave it at that.	   For IBCS2 compatibility under linux, we substitute the string 	   /usr/i486-sysv4/lib for /usr/lib in library names. */	if (libname != full_libname) {		tpnt1 = _dl_load_elf_shared_library(secure, full_libname, 0);		if (tpnt1)			return tpnt1;		goto goof;	}	/*	 * The ABI specifies that RPATH is searched before LD_*_PATH or	 * the default path of /usr/lib.  Check in rpath directories.	 */	for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {		if (tpnt->libtype == elf_executable) {			pnt = (char *) tpnt->dynamic_info[DT_RPATH];			if (pnt) {				pnt += (unsigned long) tpnt->loadaddr +					tpnt->dynamic_info[DT_STRTAB];				if ((tpnt1 = search_for_named_library(libname, secure, pnt)) != NULL) 				{				    return tpnt1;				}			}		}	}	/* Check in LD_{ELF_}LIBRARY_PATH, if specified and allowed */	if (_dl_library_path) {	    if ((tpnt1 = search_for_named_library(libname, secure, _dl_library_path)) != NULL) 	    {		return tpnt1;	    }	}	/*	 * Where should the cache be searched?  There is no such concept in the	 * ABI, so we have some flexibility here.  For now, search it before	 * the hard coded paths that follow (i.e before /lib and /usr/lib).	 */#ifdef USE_CACHE	if (_dl_cache_addr != NULL && _dl_cache_addr != (caddr_t) - 1) {		int i;		header_t *header = (header_t *) _dl_cache_addr;		libentry_t *libent = (libentry_t *) & header[1];		char *strs = (char *) &libent[header->nlibs];		for (i = 0; i < header->nlibs; i++) {			if ((libent[i].flags == LIB_ELF ||				 libent[i].flags == LIB_ELF_LIBC5) &&				_dl_strcmp(libname, strs + libent[i].sooffset) == 0 &&				(tpnt1 = _dl_load_elf_shared_library(secure, 				     strs + libent[i].liboffset, 0)))				return tpnt1;		}	}#endif	/* Lastly, search the standard list of paths for the library.	   This list must exactly match the list in uClibc/ldso/util/ldd.c */	if ((tpnt1 = search_for_named_library(libname, secure, 			UCLIBC_TARGET_PREFIX "/usr/lib:"			UCLIBC_TARGET_PREFIX "/lib:"			UCLIBC_DEVEL_PREFIX "/lib:"			UCLIBC_BUILD_DIR "/lib:"			"/usr/lib:"			"/lib")		    ) != NULL) 	{	    return tpnt1;	}  goof:	/* Well, we shot our wad on that one.  All we can do now is punt */	if (_dl_internal_error_number)		_dl_error_number = _dl_internal_error_number;	else		_dl_error_number = DL_ERROR_NOFILE;	return NULL;}/* * Read one ELF library into memory, mmap it into the correct locations and * add the symbol info to the symbol chain.  Perform any relocations that * are required. *///extern _elf_rtbndr(void);struct elf_resolve *_dl_load_elf_shared_library(int secure, 	char *libname, int flag){	elfhdr *epnt;	unsigned long dynamic_addr = 0;	unsigned long dynamic_size = 0;	Elf32_Dyn *dpnt;	struct elf_resolve *tpnt;	elf_phdr *ppnt;	int piclib;	char *status;

⌨️ 快捷键说明

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