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

📄 dl-elf.c

📁 Axis 221 camera embedded programing interface
💻 C
📖 第 1 页 / 共 2 页
字号:
	libaddr = 0;	infile = _dl_open(libname, O_RDONLY, 0);	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 = LD_ERROR_NOFILE;		return NULL;	}	header = _dl_mmap((void *) 0, _dl_pagesize, PROT_READ | PROT_WRITE,			MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);	if (_dl_mmap_check_error(header)) {		_dl_dprintf(2, "%s: can't map '%s'\n", _dl_progname, libname);		_dl_internal_error_number = LD_ERROR_MMAP_FAILED;		_dl_close(infile);		return NULL;	};	_dl_read(infile, header, _dl_pagesize);	epnt = (ElfW(Ehdr) *) (intptr_t) 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 = LD_ERROR_NOTELF;		_dl_close(infile);		_dl_munmap(header, _dl_pagesize);		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 ? LD_ERROR_NOTDYN : LD_ERROR_NOTMAGIC);		_dl_dprintf(2, "%s: '%s' is not an ELF executable for " ELF_TARGET				"\n", _dl_progname, libname);		_dl_close(infile);		_dl_munmap(header, _dl_pagesize);		return NULL;	};	ppnt = (ElfW(Phdr) *)(intptr_t) & 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;		};		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 + ADDR_ALIGN) & ~ADDR_ALIGN;	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 %s\n", _dl_progname, libname);		_dl_internal_error_number = LD_ERROR_MMAP_FAILED;		_dl_close(infile);		_dl_munmap(header, _dl_pagesize);		return NULL;	};	libaddr = (unsigned long) status;	flags |= MAP_FIXED;	/* Get the memory to store the library */	ppnt = (ElfW(Phdr) *)(intptr_t) & header[epnt->e_phoff];	for (i = 0; i < epnt->e_phnum; i++) {		if (ppnt->p_type == PT_GNU_RELRO) {			relro_addr = ppnt->p_vaddr;			relro_size = ppnt->p_memsz;		}		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 & PAGE_ALIGN)), (ppnt->p_vaddr & ADDR_ALIGN)						+ ppnt->p_filesz, LXFLAGS(ppnt->p_flags), flags, infile,						ppnt->p_offset & OFFS_ALIGN);				if (_dl_mmap_check_error(status)) {					_dl_dprintf(2, "%s: can't map '%s'\n",							_dl_progname, libname);					_dl_internal_error_number = LD_ERROR_MMAP_FAILED;					_dl_munmap((char *) libaddr, maxvma - minvma);					_dl_close(infile);					_dl_munmap(header, _dl_pagesize);					return NULL;				};				/* Pad the last page with zeroes. */				cpnt = (char *) (status + (ppnt->p_vaddr & ADDR_ALIGN) +						ppnt->p_filesz);				while (((unsigned long) cpnt) & ADDR_ALIGN)					*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 + ADDR_ALIGN) & PAGE_ALIGN;				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 & PAGE_ALIGN)						+ (piclib ? libaddr : 0), (ppnt->p_vaddr & ADDR_ALIGN) +						ppnt->p_filesz, LXFLAGS(ppnt->p_flags), flags,						infile, ppnt->p_offset & OFFS_ALIGN);			if (_dl_mmap_check_error(status)) {				_dl_dprintf(2, "%s: can't map '%s'\n", _dl_progname, libname);				_dl_internal_error_number = LD_ERROR_MMAP_FAILED;				_dl_munmap((char *) libaddr, maxvma - minvma);				_dl_close(infile);				_dl_munmap(header, _dl_pagesize);				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 = LD_ERROR_NODYNAMIC;		_dl_dprintf(2, "%s: '%s' is missing a dynamic section\n",				_dl_progname, libname);		_dl_munmap(header, _dl_pagesize);		return NULL;	}	dpnt = (Elf32_Dyn *) dynamic_addr;	_dl_memset(dynamic_info, 0, sizeof(dynamic_info));	_dl_parse_dynamic_info(dpnt, dynamic_info, NULL);	/* 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]) {#ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__		ppnt = (ElfW(Phdr) *)(intptr_t) & 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 & PAGE_ALIGN)),						(ppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) ppnt->p_filesz,						PROT_READ | PROT_WRITE | PROT_EXEC);		}#else		_dl_dprintf(_dl_debug_file, "Can't modify %s's text section. Use GCC option -fPIC for shared objects, please.\n",libname);		_dl_exit(1);#endif	}	tpnt = _dl_add_elf_hash_table(libname, (char *) libaddr, dynamic_info,			dynamic_addr, 0);	tpnt->relro_addr = relro_addr;	tpnt->relro_size = relro_size;	tpnt->ppnt = (ElfW(Phdr) *)(intptr_t) (tpnt->loadaddr + epnt->e_phoff);	tpnt->n_phent = epnt->e_phnum;	/*	 * Add this object into the symbol chain	 */	if (*rpnt) {		(*rpnt)->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));		_dl_memset((*rpnt)->next, 0, sizeof(struct dyn_elf));		(*rpnt)->next->prev = (*rpnt);		*rpnt = (*rpnt)->next;		(*rpnt)->dyn = tpnt;		tpnt->symbol_scope = _dl_symbol_tables;	}	tpnt->usage_count++;	tpnt->libtype = elf_lib;	/*	 * 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 = (unsigned long *) dynamic_info[DT_PLTGOT];	if (lpnt) {		lpnt = (unsigned long *) (dynamic_info[DT_PLTGOT] +				((int) libaddr));		INIT_GOT(lpnt, tpnt);	};#if defined (__SUPPORT_LD_DEBUG__)	if(_dl_debug) {		_dl_dprintf(2, "\n\tfile='%s';  generating link map\n", libname);		_dl_dprintf(2, "\t\tdynamic: %x  base: %x\n",				dynamic_addr, libaddr);		_dl_dprintf(2, "\t\t  entry: %x  phdr: %x  phnum: %x\n\n",				epnt->e_entry + libaddr, tpnt->ppnt, tpnt->n_phent);	}#endif	_dl_munmap(header, _dl_pagesize);	return tpnt;}/* now_flag must be RTLD_NOW or zero */int _dl_fixup(struct dyn_elf *rpnt, int now_flag){	int goof = 0;	struct elf_resolve *tpnt;	unsigned long reloc_size;	if (rpnt->next)		goof += _dl_fixup(rpnt->next, now_flag);	tpnt = rpnt->dyn;#if defined (__SUPPORT_LD_DEBUG__)	if(_dl_debug && !(tpnt->init_flag & RELOCS_DONE)) 		_dl_dprintf(_dl_debug_file,"\nrelocation processing: %s\n", tpnt->libname);#endif	if (unlikely(tpnt->dynamic_info[UNSUPPORTED_RELOC_TYPE])) {#if defined (__SUPPORT_LD_DEBUG__)		if(_dl_debug) {			_dl_dprintf(2, "%s: can't handle %s relocation records\n",					_dl_progname, UNSUPPORTED_RELOC_STR);		}#endif		goof++;		return goof;	}	reloc_size = tpnt->dynamic_info[DT_RELOC_TABLE_SIZE];/* On some machines, notably SPARC & PPC, DT_REL* includes DT_JMPREL in its   range.  Note that according to the ELF spec, this is completely legal! */#ifdef ELF_MACHINE_PLTREL_OVERLAP	reloc_size -= tpnt->dynamic_info [DT_PLTRELSZ];#endif	if (tpnt->dynamic_info[DT_RELOC_TABLE_ADDR] &&	    !(tpnt->init_flag & RELOCS_DONE)) {		tpnt->init_flag |= RELOCS_DONE;		goof += _dl_parse_relocation_information(rpnt,				tpnt->dynamic_info[DT_RELOC_TABLE_ADDR],				reloc_size);	}	if (tpnt->dynamic_info[DT_BIND_NOW])		now_flag = RTLD_NOW;	if (tpnt->dynamic_info[DT_JMPREL] &&	    (!(tpnt->init_flag & JMP_RELOCS_DONE) ||	     (now_flag && !(tpnt->rtld_flags & now_flag)))) {		tpnt->rtld_flags |= now_flag; 		tpnt->init_flag |= JMP_RELOCS_DONE;		if (!(tpnt->rtld_flags & RTLD_NOW)) {			_dl_parse_lazy_relocation_information(rpnt,					tpnt->dynamic_info[DT_JMPREL],					tpnt->dynamic_info [DT_PLTRELSZ]);		} else {			goof += _dl_parse_relocation_information(rpnt,					tpnt->dynamic_info[DT_JMPREL],					tpnt->dynamic_info[DT_PLTRELSZ]);		}	}	return goof;}/* Minimal printf which handles only %s, %d, and %x */void _dl_dprintf(int fd, const char *fmt, ...){	int num;	va_list args;	char *start, *ptr, *string;	static char *buf;	buf = _dl_mmap((void *) 0, _dl_pagesize, PROT_READ | PROT_WRITE,			MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);	if (_dl_mmap_check_error(buf)) {		_dl_write(fd, "mmap of a spare page failed!\n", 29);		_dl_exit(20);	}	start = ptr = buf;	if (!fmt)		return;	if (_dl_strlen(fmt) >= (_dl_pagesize - 1)) {		_dl_write(fd, "overflow\n", 11);		_dl_exit(20);	}	_dl_strcpy(buf, fmt);	va_start(args, fmt);	while (start) {		while (*ptr != '%' && *ptr) {			ptr++;		}		if (*ptr == '%') {			*ptr++ = '\0';			_dl_write(fd, start, _dl_strlen(start));			switch (*ptr++) {				case 's':					string = va_arg(args, char *);					if (!string)						_dl_write(fd, "(null)", 6);					else						_dl_write(fd, string, _dl_strlen(string));					break;				case 'i':				case 'd':					{						char tmp[22];						num = va_arg(args, int);						string = _dl_simple_ltoa(tmp, num);						_dl_write(fd, string, _dl_strlen(string));						break;					}				case 'x':				case 'X':					{						char tmp[22];						num = va_arg(args, int);						string = _dl_simple_ltoahex(tmp, num);						_dl_write(fd, string, _dl_strlen(string));						break;					}				default:					_dl_write(fd, "(null)", 6);					break;			}			start = ptr;		} else {			_dl_write(fd, start, _dl_strlen(start));			start = NULL;		}	}	_dl_munmap(buf, _dl_pagesize);	return;}char *_dl_strdup(const char *string){	char *retval;	int len;	len = _dl_strlen(string);	retval = _dl_malloc(len + 1);	_dl_strcpy(retval, string);	return retval;}void _dl_parse_dynamic_info(Elf32_Dyn *dpnt, unsigned long dynamic_info[], void *debug_addr){	__dl_parse_dynamic_info(dpnt, dynamic_info, debug_addr);}#ifdef __USE_GNU#if ! defined LIBDL || (! defined PIC && ! defined __PIC__)int__dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, size_t size, void *data), void *data){	struct elf_resolve *l;	struct dl_phdr_info info;	int ret = 0;	for (l = _dl_loaded_modules; l != NULL; l = l->next) {		info.dlpi_addr = l->loadaddr;		info.dlpi_name = l->libname;		info.dlpi_phdr = l->ppnt;		info.dlpi_phnum = l->n_phent;		ret = callback (&info, sizeof (struct dl_phdr_info), data);		if (ret)			break;	}	return ret;}strong_alias(__dl_iterate_phdr, dl_iterate_phdr);#endif#endif

⌨️ 快捷键说明

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