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

📄 ldso.c

📁 Axis 221 camera embedded programing interface
💻 C
📖 第 1 页 / 共 2 页
字号:
		preload = (caddr_t) _dl_mmap(0, st.st_size + 1,					     PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);		_dl_close(fd);		if (preload == (caddr_t) -1) {			_dl_dprintf(2, "%s: can't map file '%s'\n",				    _dl_progname, LDSO_PRELOAD);			break;		}		/* convert all separators and comments to spaces */		for (cp = preload; *cp; /*nada */ ) {			if (*cp == ':' || *cp == '\t' || *cp == '\n') {				*cp++ = ' ';			} else if (*cp == '#') {				do {					*cp++ = ' ';				} while (*cp != '\n' && *cp != '\0');			} else {				cp++;			}		}		/* find start of first library */		for (cp = preload; *cp && *cp == ' '; cp++)			/*nada */ ;		while (*cp) {			/* find end of library */			for (cp2 = cp; *cp && *cp != ' '; cp++)				/*nada */ ;			c = *cp;			*cp = '\0';			if ((tpnt1 = _dl_check_if_named_library_is_loaded(cp2, trace_loaded_objects))) {				tpnt1->usage_count++;				goto next_lib2;			}#if defined (__SUPPORT_LD_DEBUG__)			if(_dl_debug)				_dl_dprintf(_dl_debug_file,					    "\tfile='%s';  needed by '%s'\n",					    cp2, _dl_progname);#endif			tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2, trace_loaded_objects);			if (!tpnt1) {#ifdef __LDSO_LDD_SUPPORT__				if (trace_loaded_objects)					_dl_dprintf(1, "\t%s => not found\n", cp2);				else#endif				{					_dl_dprintf(2, "%s: can't load library '%s'\n", _dl_progname, cp2);					_dl_exit(15);				}			} else {				tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;#ifdef __SUPPORT_LD_DEBUG_EARLY__				_dl_dprintf(_dl_debug_file,					    "Loading:\t(%x) %s\n",					    tpnt1->loadaddr, tpnt1->libname);#endif#ifdef __LDSO_LDD_SUPPORT__				if (trace_loaded_objects &&				    tpnt1->usage_count == 1) {					_dl_dprintf(1, "\t%s => %s (%x)\n",						    cp2, tpnt1->libname,						    (unsigned)tpnt1->loadaddr);				}#endif			}next_lib2:			/* find start of next library */			*cp = c;			for ( /*nada */ ; *cp && *cp == ' '; cp++)				/*nada */ ;		}		_dl_munmap(preload, st.st_size + 1);	} while (0);#endif /* __LDSO_PRELOAD_FILE_SUPPORT__ */	nlist = 0;	for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {		Elf32_Dyn *dpnt;		nlist++;		for (dpnt = (Elf32_Dyn *) tcurr->dynamic_addr; dpnt->d_tag; dpnt++) {			if (dpnt->d_tag == DT_NEEDED) {				char *name;				struct init_fini_list *tmp;				lpntstr = (char*) (tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] + dpnt->d_un.d_val);				name = _dl_get_last_path_component(lpntstr);				if ((tpnt1 = _dl_check_if_named_library_is_loaded(name, trace_loaded_objects)))	{					tpnt1->usage_count++;				}#if defined (__SUPPORT_LD_DEBUG__)				if(_dl_debug)					_dl_dprintf(_dl_debug_file,						    "\tfile='%s';  needed by '%s'\n",						    lpntstr, _dl_progname);#endif				if (!tpnt1) {					if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects)))	{#ifdef __LDSO_LDD_SUPPORT__						if (trace_loaded_objects) {							_dl_dprintf(1, "\t%s => not found\n", lpntstr);							continue;						} else#endif						{							_dl_dprintf(2, "%s: can't load library '%s'\n", _dl_progname, lpntstr);							_dl_exit(16);						}					}				}				tmp = alloca(sizeof(struct init_fini_list)); /* Allocates on stack, no need to free this memory */				tmp->tpnt = tpnt1;				tmp->next = tcurr->init_fini;				tcurr->init_fini = tmp;				tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;#ifdef __SUPPORT_LD_DEBUG_EARLY__				_dl_dprintf(_dl_debug_file,					    "Loading:\t(%x) %s\n",					    tpnt1->loadaddr, tpnt1->libname);#endif#ifdef __LDSO_LDD_SUPPORT__				if (trace_loaded_objects &&				    tpnt1->usage_count == 1) {					_dl_dprintf(1, "\t%s => %s (%x)\n",						    lpntstr, tpnt1->libname,						    (unsigned)tpnt1->loadaddr);				}#endif			}		}	}	_dl_unmap_cache();	--nlist; /* Exclude the application. */	/* As long as atexit() is used to run the FINI functions, we can use	 * alloca here. The use of atexit() should go away at some time as that	 * will make Valgring happy.	 */	init_fini_list = alloca(nlist * sizeof(struct elf_resolve *));	i = 0;	for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {		init_fini_list[i++] = tcurr;	}	/* Sort the INIT/FINI list in dependency order. */	for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {		int j, k;		for (j = 0; init_fini_list[j] != tcurr; ++j)			/* Empty */;		for (k = j + 1; k < nlist; ++k) {			struct init_fini_list *runp = init_fini_list[k]->init_fini;			for (; runp; runp = runp->next) {				if (runp->tpnt == tcurr) {					struct elf_resolve *here = init_fini_list[k];#ifdef __SUPPORT_LD_DEBUG__					if(_dl_debug)						_dl_dprintf(2, "Move %s from pos %d to %d in INIT/FINI list.\n", here->libname, k, j);#endif					for (i = (k - j); i; --i)						init_fini_list[i+j] = init_fini_list[i+j-1];					init_fini_list[j] = here;					++j;					break;				}			}		}	}#ifdef __SUPPORT_LD_DEBUG__	if(_dl_debug) {		_dl_dprintf(2, "\nINIT/FINI order and dependencies:\n");		for (i = 0; i < nlist; i++) {			struct init_fini_list *tmp;			_dl_dprintf(2, "lib: %s has deps:\n",				    init_fini_list[i]->libname);			tmp = init_fini_list[i]->init_fini;			for (; tmp; tmp = tmp->next)				_dl_dprintf(2, " %s ", tmp->tpnt->libname);			_dl_dprintf(2, "\n");		}	}#endif	/*	 * If the program interpreter is not in the module chain, add it.	 * This will be required for dlopen to be able to access the internal	 * functions in the dynamic linker and to relocate the interpreter	 * again once all libs are loaded.	 */	if (tpnt) {		ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;		ElfW(Phdr) *myppnt = (ElfW(Phdr) *) (load_addr + epnt->e_phoff);		int j;				tpnt = _dl_add_elf_hash_table(tpnt->libname, (char *)load_addr,					      tpnt->dynamic_info,					      (unsigned long)tpnt->dynamic_addr,					      0);		tpnt->n_phent = epnt->e_phnum;		tpnt->ppnt = myppnt;		for (j = 0; j < epnt->e_phnum; j++, myppnt++) {			if (myppnt->p_type ==  PT_GNU_RELRO) {				tpnt->relro_addr = myppnt->p_vaddr;				tpnt->relro_size = myppnt->p_memsz;				break;			}		}		tpnt->libtype = program_interpreter;		tpnt->usage_count++;		tpnt->symbol_scope = _dl_symbol_tables;		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;		} else {			rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));			_dl_memset(rpnt, 0, sizeof(struct dyn_elf));		}		rpnt->dyn = tpnt;		tpnt->rtld_flags = RTLD_NOW | RTLD_GLOBAL; /* Must not be LAZY */#ifdef RERELOCATE_LDSO		/* Only rerelocate functions for now. */		tpnt->init_flag = RELOCS_DONE;		lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);# ifdef ALLOW_ZERO_PLTGOT		if (tpnt->dynamic_info[DT_PLTGOT])# endif			INIT_GOT(lpnt, tpnt);#else		tpnt->init_flag = RELOCS_DONE | JMP_RELOCS_DONE;#endif		tpnt = NULL;	}#ifdef __LDSO_LDD_SUPPORT__	/* End of the line for ldd.... */	if (trace_loaded_objects) {		_dl_dprintf(1, "\t%s => %s (%x)\n",			    rpnt->dyn->libname + _dl_strlen(_dl_ldsopath) + 1,			    rpnt->dyn->libname, rpnt->dyn->loadaddr);		_dl_exit(0);	}#endif#ifdef __SUPPORT_LD_DEBUG_EARLY__	_dl_dprintf(_dl_debug_file, "Beginning relocation fixups\n");#endif#ifdef __mips__	/*	 * Relocation of the GOT entries for MIPS have to be done	 * after all the libraries have been loaded.	 */	_dl_perform_mips_global_got_relocations(_dl_loaded_modules, !unlazy);#endif	/*	 * OK, now all of the kids are tucked into bed in their proper	 * addresses.  Now we go through and look for REL and RELA records that	 * indicate fixups to the GOT tables.  We need to do this in reverse	 * order so that COPY directives work correctly.	 */	if (_dl_symbol_tables)		goof += _dl_fixup(_dl_symbol_tables, unlazy);	for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {		if (tpnt->relro_size)			_dl_protect_relro (tpnt);	}	/* OK, at this point things are pretty much ready to run.  Now we need	 * to touch up a few items that are required, and then we can let the	 * user application have at it.  Note that the dynamic linker itself	 * is not guaranteed to be fully dynamicly linked if we are using	 * ld.so.1, so we have to look up each symbol individually.	 */	_dl_envp = (unsigned long *) (intptr_t) _dl_find_hash("__environ", _dl_symbol_tables, NULL, 0);	if (_dl_envp)		*_dl_envp = (unsigned long) envp;#ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__	{		unsigned int j;		ElfW(Phdr) *myppnt;		/* We had to set the protections of all pages to R/W for		 * dynamic linking.  Set text pages back to R/O.		 */		for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {			for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) {				if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {					_dl_mprotect((void *) (tpnt->loadaddr + (myppnt->p_vaddr & PAGE_ALIGN)),							(myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));				}			}		}	}#endif	_dl_atexit = (int (*)(void *)) (intptr_t) _dl_find_hash("atexit", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT);#if defined (__SUPPORT_LD_DEBUG__)	_dl_on_exit = (int (*)(void (*)(int, void *),void*))		(intptr_t) _dl_find_hash("on_exit", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT);#endif	/* Notify the debugger we have added some objects. */	_dl_debug_addr->r_state = RT_ADD;	_dl_debug_state();	for (i = nlist; i; --i) {		tpnt = init_fini_list[i-1];		tpnt->init_fini = NULL; /* Clear, since alloca was used */		if (tpnt->init_flag & INIT_FUNCS_CALLED)			continue;		tpnt->init_flag |= INIT_FUNCS_CALLED;		if (tpnt->dynamic_info[DT_INIT]) {			void (*dl_elf_func) (void);			dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]);#if defined (__SUPPORT_LD_DEBUG__)			if(_dl_debug)				_dl_dprintf(_dl_debug_file,					    "\ncalling init: %s\n\n",					    tpnt->libname);#endif			(*dl_elf_func) ();		}		tpnt->init_flag |= FINI_FUNCS_CALLED;		if (_dl_atexit && tpnt->dynamic_info[DT_FINI]) {			void (*dl_elf_func) (void);			dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);			(*_dl_atexit) (dl_elf_func);#if defined (__SUPPORT_LD_DEBUG__)			if(_dl_debug && _dl_on_exit) {				(*_dl_on_exit)(debug_fini, tpnt->libname);			}#endif		}#if defined (__SUPPORT_LD_DEBUG__)		else {			if (!_dl_atexit)				_dl_dprintf(_dl_debug_file, "%s: The address of atexit () is 0x0.\n", tpnt->libname);		}#endif	}	/* Notify the debugger that all objects are now mapped in.  */	_dl_debug_addr->r_state = RT_CONSISTENT;	_dl_debug_state();	/* Find the real malloc function and make ldso functions use that from now on */	 _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash("malloc", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT);}char *_dl_getenv(const char *symbol, char **envp){	char *pnt;	const char *pnt1;	while ((pnt = *envp++)) {		pnt1 = symbol;		while (*pnt && *pnt == *pnt1)			pnt1++, pnt++;		if (!*pnt || *pnt != '=' || *pnt1)			continue;		return pnt + 1;	}	return 0;}void _dl_unsetenv(const char *symbol, char **envp){	char *pnt;	const char *pnt1;	char **newenvp = envp;	for (pnt = *envp; pnt; pnt = *++envp) {		pnt1 = symbol;		while (*pnt && *pnt == *pnt1)			pnt1++, pnt++;		if (!*pnt || *pnt != '=' || *pnt1)			*newenvp++ = *envp;	}	*newenvp++ = *envp;	return;}static int _dl_suid_ok(void){	__kernel_uid_t uid, euid;	__kernel_gid_t gid, egid;	uid = _dl_getuid();	euid = _dl_geteuid();	gid = _dl_getgid();	egid = _dl_getegid();	if(uid == euid && gid == egid) {		return 1;	}	return 0;}void *_dl_malloc(int size){	void *retval;#if 0#ifdef __SUPPORT_LD_DEBUG_EARLY__	_dl_dprintf(2, "malloc: request for %d bytes\n", size);#endif#endif	if (_dl_malloc_function)		return (*_dl_malloc_function) (size);	if (_dl_malloc_addr - _dl_mmap_zero + (unsigned)size > _dl_pagesize) {#ifdef __SUPPORT_LD_DEBUG_EARLY__		_dl_dprintf(2, "malloc: mmapping more memory\n");#endif		_dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, size,				PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);		if (_dl_mmap_check_error(_dl_mmap_zero)) {			_dl_dprintf(2, "%s: mmap of a spare page failed!\n", _dl_progname);			_dl_exit(20);		}	}	retval = _dl_malloc_addr;	_dl_malloc_addr += size;	/*	 * Align memory to 4 byte boundary.  Some platforms require this,	 * others simply get better performance.	 */	_dl_malloc_addr = (unsigned char *) (((unsigned long) _dl_malloc_addr + 3) & ~(3));	return retval;}#include "dl-hash.c"#include "dl-elf.c"

⌨️ 快捷键说明

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