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

📄 readelflib1.c

📁 linux下用PCMCIA无线网卡虚拟无线AP的程序源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	int flags;	char header[4096];	unsigned long dynamic_info[24];	int *lpnt;	unsigned long libaddr;	unsigned long minvma = 0xffffffff, maxvma = 0;	int i;	int infile;	/* If this file is already loaded, skip this step */	tpnt = _dl_check_hashed_files(libname);	if (tpnt)		return tpnt;	/* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD),	   we don't load the library if it isn't setuid. */	if (secure) {		struct stat st;		if (_dl_stat(libname, &st) || !(st.st_mode & S_ISUID))			return NULL;	}	libaddr = 0;	infile = _dl_open(libname, O_RDONLY);	if (infile < 0) {#if 0		/*		 * NO!  When we open shared libraries we may search several paths.		 * it is inappropriate to generate an error here.		 */		_dl_dprintf(2, "%s: can't open '%s'\n", _dl_progname, libname);#endif		_dl_internal_error_number = DL_ERROR_NOFILE;		return NULL;	}	_dl_read(infile, header, sizeof(header));	epnt = (elfhdr *) header;	if (epnt->e_ident[0] != 0x7f ||		epnt->e_ident[1] != 'E' || 		epnt->e_ident[2] != 'L' || 		epnt->e_ident[3] != 'F') 	{		_dl_dprintf(2, "%s: '%s' is not an ELF file\n", _dl_progname,					 libname);		_dl_internal_error_number = DL_ERROR_NOTELF;		_dl_close(infile);		return NULL;	};	if ((epnt->e_type != ET_DYN) || (epnt->e_machine != MAGIC1 #ifdef MAGIC2		    && epnt->e_machine != MAGIC2#endif		)) 	{		_dl_internal_error_number = 		    (epnt->e_type != ET_DYN ? DL_ERROR_NOTDYN : DL_ERROR_NOTMAGIC);		_dl_dprintf(2, "%s: '%s' is not an ELF executable for " ELF_TARGET 			"\n", _dl_progname, libname);		_dl_close(infile);		return NULL;	};	ppnt = (elf_phdr *) & header[epnt->e_phoff];	piclib = 1;	for (i = 0; i < epnt->e_phnum; i++) {		if (ppnt->p_type == PT_DYNAMIC) {			if (dynamic_addr)				_dl_dprintf(2, "%s: '%s' has more than one dynamic section\n", 					_dl_progname, libname);			dynamic_addr = ppnt->p_vaddr;			dynamic_size = ppnt->p_filesz;		};		if (ppnt->p_type == PT_LOAD) {			/* See if this is a PIC library. */			if (i == 0 && ppnt->p_vaddr > 0x1000000) {				piclib = 0;				minvma = ppnt->p_vaddr;			}			if (piclib && ppnt->p_vaddr < minvma) {				minvma = ppnt->p_vaddr;			}			if (((unsigned long) ppnt->p_vaddr + ppnt->p_memsz) > maxvma) {				maxvma = ppnt->p_vaddr + ppnt->p_memsz;			}		}		ppnt++;	};	maxvma = (maxvma + 0xfffU) & ~0xfffU;	minvma = minvma & ~0xffffU;	flags = MAP_PRIVATE /*| MAP_DENYWRITE */ ;	if (!piclib)		flags |= MAP_FIXED;	status = (char *) _dl_mmap((char *) (piclib ? 0 : minvma), 		maxvma - minvma, PROT_NONE, flags | MAP_ANONYMOUS, -1, 0);	if (_dl_mmap_check_error(status)) {		_dl_dprintf(2, "%s: can't map '/dev/zero'\n", _dl_progname);		_dl_internal_error_number = DL_ERROR_MMAP_FAILED;		_dl_close(infile);		return NULL;	};	libaddr = (unsigned long) status;	flags |= MAP_FIXED;	/* Get the memory to store the library */	ppnt = (elf_phdr *) & header[epnt->e_phoff];	for (i = 0; i < epnt->e_phnum; i++) {		if (ppnt->p_type == PT_LOAD) {			/* See if this is a PIC library. */			if (i == 0 && ppnt->p_vaddr > 0x1000000) {				piclib = 0;				/* flags |= MAP_FIXED; */			}			if (ppnt->p_flags & PF_W) {				unsigned long map_size;				char *cpnt;				status = (char *) _dl_mmap((char *) ((piclib ? libaddr : 0) + 					(ppnt->p_vaddr & 0xfffff000)), (ppnt->p_vaddr & 0xfff) 					+ ppnt->p_filesz, LXFLAGS(ppnt->p_flags), flags, infile, 					ppnt->p_offset & 0x7ffff000);				if (_dl_mmap_check_error(status)) {					_dl_dprintf(2, "%s: can't map '%s'\n", 						_dl_progname, libname);					_dl_internal_error_number = DL_ERROR_MMAP_FAILED;					_dl_munmap((char *) libaddr, maxvma - minvma);					_dl_close(infile);					return NULL;				};				/* Pad the last page with zeroes. */				cpnt = (char *) (status + (ppnt->p_vaddr & 0xfff) +							  ppnt->p_filesz);				while (((unsigned long) cpnt) & 0xfff)					*cpnt++ = 0;				/* I am not quite sure if this is completely				 * correct to do or not, but the basic way that				 * we handle bss segments is that we mmap				 * /dev/zero if there are any pages left over				 * that are not mapped as part of the file */				map_size = (ppnt->p_vaddr + ppnt->p_filesz + 0xfff) & 0xfffff000;				if (map_size < ppnt->p_vaddr + ppnt->p_memsz)					status = (char *) _dl_mmap((char *) map_size + 						(piclib ? libaddr : 0), 						ppnt->p_vaddr + ppnt->p_memsz - map_size, 						LXFLAGS(ppnt->p_flags), flags | MAP_ANONYMOUS, -1, 0);			} else				status = (char *) _dl_mmap((char *) (ppnt->p_vaddr & 0xfffff000) 					+ (piclib ? libaddr : 0), (ppnt->p_vaddr & 0xfff) + 					ppnt->p_filesz, LXFLAGS(ppnt->p_flags), flags, 					infile, ppnt->p_offset & 0x7ffff000);			if (_dl_mmap_check_error(status)) {				_dl_dprintf(2, "%s: can't map '%s'\n", _dl_progname, libname);				_dl_internal_error_number = DL_ERROR_MMAP_FAILED;				_dl_munmap((char *) libaddr, maxvma - minvma);				_dl_close(infile);				return NULL;			};			/* if(libaddr == 0 && piclib) {			   libaddr = (unsigned long) status;			   flags |= MAP_FIXED;			   }; */		};		ppnt++;	};	_dl_close(infile);	/* For a non-PIC library, the addresses are all absolute */	if (piclib) {		dynamic_addr += (unsigned long) libaddr;	}	/* 	 * OK, the ELF library is now loaded into VM in the correct locations	 * The next step is to go through and do the dynamic linking (if needed).	 */	/* Start by scanning the dynamic section to get all of the pointers */	if (!dynamic_addr) {		_dl_internal_error_number = DL_ERROR_NODYNAMIC;		_dl_dprintf(2, "%s: '%s' is missing a dynamic section\n", 			_dl_progname, libname);		return NULL;	}	dpnt = (Elf32_Dyn *) dynamic_addr;	dynamic_size = dynamic_size / sizeof(Elf32_Dyn);	_dl_memset(dynamic_info, 0, sizeof(dynamic_info));	for (i = 0; i < dynamic_size; i++) {		if (dpnt->d_tag > DT_JMPREL) {			dpnt++;			continue;		}		dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;		if (dpnt->d_tag == DT_TEXTREL || SVR4_BUGCOMPAT)			dynamic_info[DT_TEXTREL] = 1;		dpnt++;	};	/* If the TEXTREL is set, this means that we need to make the pages	   writable before we perform relocations.  Do this now. They get set back	   again later. */	if (dynamic_info[DT_TEXTREL]) {		ppnt = (elf_phdr *) & header[epnt->e_phoff];		for (i = 0; i < epnt->e_phnum; i++, ppnt++) {			if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))				_dl_mprotect((void *) ((piclib ? libaddr : 0) + 					    (ppnt->p_vaddr & 0xfffff000)), 					(ppnt->p_vaddr & 0xfff) + (unsigned long) ppnt->p_filesz, 					PROT_READ | PROT_WRITE | PROT_EXEC);		}	}	tpnt = _dl_add_elf_hash_table(libname, (char *) libaddr, dynamic_info, 		dynamic_addr, dynamic_size);	tpnt->ppnt = (elf_phdr *) (tpnt->loadaddr + epnt->e_phoff);	tpnt->n_phent = epnt->e_phnum;	/*	 * OK, the next thing we need to do is to insert the dynamic linker into	 * the proper entry in the GOT so that the PLT symbols can be properly	 * resolved. 	 */	lpnt = (int *) dynamic_info[DT_PLTGOT];	if (lpnt) {		lpnt = (int *) (dynamic_info[DT_PLTGOT] + ((int) libaddr));		INIT_GOT(lpnt, tpnt);	};	return tpnt;}/* Ugly, ugly.  Some versions of the SVr4 linker fail to generate COPY   relocations for global variables that are present both in the image and   the shared library.  Go through and do it manually.  If the images   are guaranteed to be generated by a trustworthy linker, then this   step can be skipped. */int _dl_copy_fixups(struct dyn_elf *rpnt){	int goof = 0;	struct elf_resolve *tpnt;	if (rpnt->next)		goof += _dl_copy_fixups(rpnt->next);	else		return 0;	tpnt = rpnt->dyn;	if (tpnt->init_flag & COPY_RELOCS_DONE)		return goof;	tpnt->init_flag |= COPY_RELOCS_DONE;#ifdef ELF_USES_RELOCA	goof += _dl_parse_copy_information(rpnt, 		tpnt->dynamic_info[DT_RELA], tpnt->dynamic_info[DT_RELASZ], 0);#else	goof += _dl_parse_copy_information(rpnt, tpnt->dynamic_info[DT_REL], 		tpnt->dynamic_info[DT_RELSZ], 0);#endif	return goof;}

⌨️ 快捷键说明

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