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

📄 eshlibld.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 5 页
字号:
	   "base" pointer from the objects to the library).	    Luckily, this is not a priority operation; objects that are	   shared should normally remain shared. */	for (nextshlibpp = &(locals.libs);	     *nextshlibpp != NULL && *nextshlibpp != obj->base_lib;	     nextshlibpp = (struct shliblist **)		     &(nextshlibpp[0]->common.next))		;	if (*nextshlibpp == obj->base_lib) {		D_(printk("Found %s (%p)\n",			  obj->base_lib->common.name, obj->base_lib));		for (nextobjpp = &(nextshlibpp[0]->first_obj);		     *nextobjpp != NULL && *nextobjpp != obj			     DB(&& ++i < 500);		     nextobjpp = ((struct shlib_obj **)				  &(nextobjpp[0]->common.next))) {			D_(printk("Frowning on %s (%p)\n",				  nextobjpp[0]->common.name,				  nextobjpp[0]));		}		DB(	/* If the linked list gets trashed. */			if (i == 500) {				printk("Too many iterations\n");								fatal_never_tried();	/* Not been here yet. */			});		if (*nextobjpp == obj) {			/* Found it. */			struct shlib_obj **depobjp;			/* If we actually delete an object, we have to			   recalculate nextshlibpp and nextobjpp, since			   they may have gone, perhaps by being depended			   on through lots of levels. */			int obj_deleted = 0;			D_(printk("obj %s found in %s\n",				  obj->common.name,				  obj->base_lib->common.name));			/* About to unlink this object.	 First, go			   through all objects depended-on and decrease			   usecount (and possibly free them).			    Check for usecount == 0 before that, so we			    properly avoid recursing for circular			    dependencies.			     FIXME:  There's no check for max recursion			    here, although it should be "pretty safe"			    since we got this level of dependencies in			    the first place, and since this function			    would have a pretty small stack-frame. */			for (depobjp = obj->shdeps.shdeps;			     *depobjp != NULL;			     depobjp++) {				D_(printk("Bye to %s #%d\n",					  depobjp[0]->common.name,					  depobjp[0]->usecount));				if (depobjp[0]->usecount				    && --depobjp[0]->usecount == 0) {					obj_deleted = 1;					shlibobj_free(depobjp);				}			}			/* Maybe recalculate. */			if (obj_deleted) {				/* Recalculate nextshlibpp. */				D_(printk("Recalculate ->next lib %p obj %p ... ",					  nextshlibpp, nextobjpp));				for (nextshlibpp = &(locals.libs);				     *nextshlibpp != NULL					     && *nextshlibpp != obj->base_lib;				     nextshlibpp = (struct shliblist **)					     &(nextshlibpp[0]->common.next))					;				if (*nextshlibpp == obj->base_lib) {					/* Recalculate nextobjpp. */					for (nextobjpp						     = &(nextshlibpp[0]							 ->first_obj);					     *nextobjpp != NULL						     && *nextobjpp != obj						     DB(&& ++i < 500)						     ;					     nextobjpp = ((struct shlib_obj **)							  &(nextobjpp[0]							    ->common.next))) {						D_(printk("ReFrowning on"							  " %s (%p)\n",							  nextobjpp[0]							  ->common.name,							  nextobjpp[0]));					}					DB(						/* If the linked list gets trashed. */						if (i == 500) {							printk("Too many iterations\n");							/* Not been here yet. */							fatal_never_tried();						});					if (*nextobjpp != obj) {						debug_fatal("Cannot find"						       " obj %s again\n",						       obj->common.name);					}					D_(printk("%p %p\n", nextshlibpp,						  nextobjpp));				} else {					debug_fatal("Cannot find base %s again\n",						    obj->base_lib->common.name);				}			}			/* If it was the last object, we need to change			   the "last_next" pointer for this library. */			if (obj->base_lib->last_next			    == (struct shlib_obj **) &(obj->common.next)) {				D_(printk("Was last object, new last is %s\n",					  (nextshlibpp[0]->first_obj == obj					   ? "(gone)"					   : (((struct shlib_obj *)					       ((char *) nextobjpp						- ((unsigned int)						   (&((struct shlib_obj *)0)						    ->common.next))))					      ->common.name))));				obj->base_lib->last_next = nextobjpp;			}			*nextobjpp = ((struct shlib_obj *)				      obj->common.next);			/* Did we just remove the only member? */			if (nextshlibpp[0]->first_obj == NULL			    && *nextshlibpp != &locals.anon_objs) {				struct shliblist *shlib = *nextshlibpp;				D_(printk("Shlib %s gone, next is %s\n",					  nextshlibpp[0]->common.name,					  (shlib->common.next					   ? shlib->common.next->name					   : "(gone)")));				*nextshlibpp = ((struct shliblist *)						shlib->common.next);				/* Free the shliblist.  There's				   nothing hanging in there. */				sym_free(shlib, "last in lib");			}			/* Now free the object.	 Each of the segments			   needs to be freed too.  Note that we use some			   flavor of kfree here (when __KERNEL__).  This			   is possible since the originally mmapped area			   was "forgotten" through a call to the			   [special] do_mforgetmap function. */			if (obj->text_data) {				D_(printk("Will free text etc. at %p\n",					  obj->text_data));				sym_free ((void *) obj->text_data,					  "text+data(+bss)");			}			if (obj->bss) {				D_(printk("Will free bss at %p\n",					  obj->bss));				sym_free ((void *) obj->bss, "bss");			}			D_(printk("Object goes at %p\n", obj));			sym_free(obj, "object");		} else {			DB(printk("obj %s not found in %s!\n",				  obj->common.name,				  obj->base_lib->common.name));			fatal_never_tried();	/* Not been here yet. */		}	} else {		DB(printk("lib %s not found!\n", obj->base_lib->common.name));		fatal_never_tried();	/* Not been here yet. */	}}/* For the shared objects mentioned in the argument, mark that this was   the end of their use by this process. */voidshlibmod_exit(struct shlibdep **shdeps){	struct shlib_obj **objp;	if (*shdeps == NULL)		return;	/* Go through the list of dependencies, and decrease every use-count	   by one.  For those that became 0, perform free-actions. */	for (objp = (struct shlib_obj **) *shdeps;	     *objp != NULL;	     objp++) {		D_(printk("Exiting use of %s of %s from %d\n",			  objp[0]->common.name,			  (objp[0]->base_lib != NULL			   ? objp[0]->base_lib->common.name : "(preload)"),			  objp[0]->usecount));		if (--(objp[0]->usecount) == 0)			shlibobj_free(objp);	}	sym_free(*shdeps, "deps");	*shdeps = NULL;}/* For the shared objects mentioned in the argument, say that this process   forked and duplicate them (copy and update use count).   Return 0 if fail, nonzero for success. */intshlibmod_fork(struct shlibdep **shdeps){	/* We fake it a little here; there is no actual use of	   any struct shlibdep. */	struct shlib_obj **mydeps = (struct shlib_obj **) *shdeps;	struct shlib_obj **objp;	struct shlib_obj **tmpobjp;	int chunklen;#ifdef RELOC_DEBUG	/* We need to clear the debug struct for this task.	   There is a slight problem in that we do not find it at	   "current", but rather at "p", which is not attached here, and	   really is only needed for debug purposes.  It can be found by	   counting back from "shdeps", so we will do that rather than	   adding function parameters, structure members, or code at the	   call point. */	struct task_struct *new_current		/* No "offsetof()" available, I guess. */		= (struct task_struct *) ((char *) shdeps					  - ((unsigned int)					     (&((struct task_struct *)0)					      ->shlib_deps)));	struct task_struct *old_current = current;	memset(&(new_current->shlib_dbg), 0, sizeof(new_current->shlib_dbg));#endif	if (mydeps == NULL)		return 1;	/* Go through the list of dependencies, and increase every use	   count by one.  Copy the list itself and store in *shdeps. */	for (objp = mydeps, chunklen = sizeof (*objp);	     *objp != NULL;	     objp++) {		chunklen += sizeof(*objp);		D_(printk("Forking use of %s of %s from %d\n",			  objp[0]->common.name,			  (objp[0]->base_lib != NULL			   ? objp[0]->base_lib->common.name : "(preload)"),			  objp[0]->usecount));		objp[0]->usecount++;	}#ifdef RELOC_DEBUG	/* The debug-allocation machinery will use "current".  To avoid	   more ugly hackery, let's just temporarily set it.	   (No, we don't have SMP, I just kept the guts of the macro	   since I could not use straight "current"; it's not an lvalue -	   probably because someone don't want people to assign to it by	   mistake ;-). */	current_set[smp_processor_id()] = new_current;	tmpobjp = sym_malloc(chunklen, "Fork");	current_set[smp_processor_id()] = old_current;#else	tmpobjp = sym_malloc(chunklen, "Fork");#endif	if (tmpobjp == NULL) {		/* If we fail, count down all we updated. */		printk("Failed to allocate room for forking shared libraries");#ifdef RELOC_DEBUG		current_set[smp_processor_id()] = new_current;		shlibmod_exit(shdeps);		current_set[smp_processor_id()] = old_current;#else		shlibmod_exit(shdeps);#endif		return 0;	}	memcpy(tmpobjp, mydeps, chunklen);	*shdeps = (struct shlibdep *) tmpobjp;	return 1;}/* If the dependencies of the shared object are no other than   those mentioned in the program (that is, they are a subset of the   program objects), return 1, else return 0. */static intmatches_mentioned_dependencies(struct shlib_obj *obj,			       struct progenv *penv){	struct shlibdep shdeps = obj->shdeps;	struct shlib_obj **objp;	/* Check for general (dis)allowance. */	if (!	    /* If dependency (direct or indirect) on bss or data, then	       euid is >= 0, set to the euid of the process exporting	       the library. */	    (obj->euid < 0	     /* So check if we allow this all-around. */	     || (penv->env_flags & ALLOW_WRITE_DATA_FLAG)	     /* Or just for same euid. */	     || ((penv->env_flags & ALLOW_WRITE_DATA_SAME_UID_FLAG)		 && (obj->euid == penv->euid || obj->euid == 0)))) {		D_(printk("%s depends on writable data, not allowed for sharing\n",			  obj->common.name));		return 0;	}	/* Empty dependencies are good. */	if (shdeps.shdeps == NULL || shdeps.shdeps[0] == NULL) {		D_(printk("%s has no dependencies.  (Sharing ok).\n",			  obj->common.name));		return 1;	}	for (objp = shdeps.shdeps;	     *objp != NULL;	     objp++) {		struct shlib_obj *depobj = *objp;		struct symlist *slistp;		/* For non-contained objects, ->libindex is -1, so		   starting with that makes it right when comparing for		   "the right lib".   */		int i = -1;		/* Check if the library is mentioned. */		if (depobj->base_lib != &locals.anon_objs) {			int nlibs = penv->nlibs;			/* maybe FIXME: There's a weak spot here.			   We can't check that the path is right for a			   depended-on library that has not been looked up			   yet (as in decided-the-right-path for).			    In this case we have to depend on the choice			   of Good Names for the libraries, and not only			   depending on paths to separate them (which			   would be very unwise anyway, for other			   reasons too).			   So if the library is not determined (the			   meat is not loaded), we'll just check the			   basename. */			for (i = 0; i < nlibs; i++) {				struct libspec *libspc = penv->libs + i;				D_(printk(" Checking if %s is %s\n",					  depobj->base_lib->common.name + 1,					  libspc->path));				if (strcmp(libspc->path,					   depobj->base_lib->common.name + 1)				    == 0) {					D_(printk(" %s is straight %s\n",						  depobj->base_lib->common.name + 1,						  libspc->path));					break;				}				else {					/* If there was no match with the					   path, then check if the					   library is loaded (the path					   is determined), or if we					   should try just the basename					   and see if it fits. */					if (libspc->shlib					    == (struct shliblist *) NULL) {						/* Then the path is						   unchecked.						   Check the basenames. */						char *shlibbase							= strrchr(depobj->								  base_lib->								  common.name,								  '/');						if (shlibbase == NULL)							shlibbase								= depobj->								base_lib->								common.name;						else							/* Skip the '/'. */							shlibbase++;						if (strcmp(shlibbase,							   penv->libnames[i])						    == 0) {							D_(printk("Unchecked %s"								  "is mentioned\n",							       shlibbase));							break;						}					}				}			}			/* If we get here, we either found the correct			   library name, or ran out of places to look. */			if (i == nlibs) {#if defined(RELOC_DEBUG) || defined(MINIMAL_RELOC_DEBUG)				printk("Th

⌨️ 快捷键说明

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