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

📄 dl-load.c

📁 Newlib 嵌入式 C库 标准实现代码
💻 C
📖 第 1 页 / 共 4 页
字号:
      maplength = ehdr->e_phnum * sizeof (ElfW(Phdr));      if (ehdr->e_phoff + maplength <= fbp->len)	phdr = (void *) (fbp->buf + ehdr->e_phoff);      else	{	  phdr = alloca (maplength);	  lseek (fd, SEEK_SET, ehdr->e_phoff);	  if (__libc_read (fd, (void *) phdr, maplength) != maplength)	    {	    read_error:	      errval = errno;	      errstring = N_("cannot read file data");	      goto call_lose;	    }	}      /* Check .note.ABI-tag if present.  */      for (ph = phdr; ph < &phdr[ehdr->e_phnum]; ++ph)	if (ph->p_type == PT_NOTE && ph->p_filesz == 32 && ph->p_align >= 4)	  {	    if (ph->p_offset + 32 <= fbp->len)	      abi_note = (void *) (fbp->buf + ph->p_offset);	    else	      {		lseek (fd, SEEK_SET, ph->p_offset);		if (__libc_read (fd, (void *) abi_note_buf, 32) != 32)		  goto read_error;		abi_note = abi_note_buf;	      }	    if (memcmp (abi_note, &expected_note, sizeof (expected_note)))	      continue;	    osversion = (abi_note[5] & 0xff) * 65536			+ (abi_note[6] & 0xff) * 256			+ (abi_note[7] & 0xff);	    if (abi_note[4] != __ABI_TAG_OS		|| (_dl_osversion && _dl_osversion < osversion))	      {	      close_and_out:		close (fd);		__set_errno (ENOENT);		fd = -1;	      }	    break;	  }    }  return fd;}/* Try to open NAME in one of the directories in *DIRSP.   Return the fd, or -1.  If successful, fill in *REALNAME   with the malloc'd full directory name.  If it turns out   that none of the directories in *DIRSP exists, *DIRSP is   replaced with (void *) -1, and the old value is free()d   if MAY_FREE_DIRS is true.  */static intopen_path (const char *name, size_t namelen, int preloaded,	   struct r_search_path_struct *sps, char **realname,	   struct filebuf *fbp){  struct r_search_path_elem **dirs = sps->dirs;  char *buf;  int fd = -1;  const char *current_what = NULL;  int any = 0;  buf = alloca (max_dirnamelen + max_capstrlen + namelen);  do    {      struct r_search_path_elem *this_dir = *dirs;      size_t buflen = 0;      size_t cnt;      char *edp;      int here_any = 0;      int err;      /* If we are debugging the search for libraries print the path	 now if it hasn't happened now.  */      if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0)	  && current_what != this_dir->what)	{	  current_what = this_dir->what;	  print_search_path (dirs, current_what, this_dir->where);	}      edp = (char *) (memcpy (buf, this_dir->dirname, this_dir->dirnamelen) + this_dir->dirnamelen);      for (cnt = 0; fd == -1 && cnt < ncapstr; ++cnt)	{          char *tmp;	  /* Skip this directory if we know it does not exist.  */	  if (this_dir->status[cnt] == nonexisting)	    continue;          tmp = memcpy (edp, capstr[cnt].str, capstr[cnt].len);          tmp += capstr[cnt].len;          tmp = memcpy (tmp, name, namelen);          tmp += namelen;	  buflen = ((char *) (tmp - buf));	  /* Print name we try if this is wanted.  */	  if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0))	    _dl_debug_printf ("  trying file=%s\n", buf);	  fd = open_verify (buf, fbp);	  if (this_dir->status[cnt] == unknown)	    {	      if (fd != -1)		this_dir->status[cnt] = existing;	      else		{		  /* We failed to open machine dependent library.  Let's		     test whether there is any directory at all.  */		  struct stat64 st;		  buf[buflen - namelen - 1] = '\0';		  if (stat64 (buf, &st) != 0		      || ! S_ISDIR (st.st_mode))		    /* The directory does not exist or it is no directory.  */		    this_dir->status[cnt] = nonexisting;		  else		    this_dir->status[cnt] = existing;		}	    }	  /* Remember whether we found any existing directory.  */	  here_any |= this_dir->status[cnt] == existing;	  if (fd != -1 && __builtin_expect (preloaded, 0)	      && 0)	    {	      /* This is an extra security effort to make sure nobody can		 preload broken shared objects which are in the trusted		 directories and so exploit the bugs.  */	      struct stat64 st;	      if (fstat64 (fd, &st) != 0		  || (st.st_mode & S_ISUID) == 0)		{		  /* The shared object cannot be tested for being SUID		     or this bit is not set.  In this case we must not		     use this object.  */		  close (fd);		  fd = -1;		  /* We simply ignore the file, signal this by setting		     the error value which would have been set by `open'.  */		  errno = ENOENT;		}	    }	}      if (fd != -1)	{	  *realname = (char *) malloc (buflen);	  if (*realname != NULL)	    {	      memcpy (*realname, buf, buflen);	      return fd;	    }	  else	    {	      /* No memory for the name, we certainly won't be able		 to load and link it.  */	      close (fd);	      return -1;	    }	}      if (here_any && (err = errno) != ENOENT && err != EACCES)	/* The file exists and is readable, but something went wrong.  */	return -1;      /* Remember whether we found anything.  */      any |= here_any;    }  while (*++dirs != NULL);  /* Remove the whole path if none of the directories exists.  */  if (__builtin_expect (! any, 0))    {      /* Paths which were allocated using the minimal malloc() in ld.so	 must not be freed using the general free() in libc.  */      if (sps->malloced)	free (sps->dirs);      sps->dirs = (void *) -1;    }  return -1;}/* Map in the shared object file NAME.  */struct link_map *internal_function_dl_map_object (struct link_map *loader, const char *name, int preloaded,		int type, int trace_mode, int mode){  int fd;  char *realname;  char *name_copy;  struct link_map *l;  struct filebuf fb;  /* Look for this name among those already loaded.  */  for (l = _dl_loaded; l; l = l->l_next)    {      /* If the requested name matches the soname of a loaded object,	 use that object.  Elide this check for names that have not	 yet been opened.  */      if (__builtin_expect (l->l_faked, 0) != 0)	continue;      if (!_dl_name_match_p (name, l))	{	  const char *soname;	  if (__builtin_expect (l->l_soname_added, 1)	      || l->l_info[DT_SONAME] == NULL)	    continue;	  soname = ((const char *) D_PTR (l, l_info[DT_STRTAB])		    + l->l_info[DT_SONAME]->d_un.d_val);	  if (strcmp (name, soname) != 0)	    continue;	  /* We have a match on a new name -- cache it.  */	  add_name_to_object (l, soname);	  l->l_soname_added = 1;	}      /* We have a match.  */      return l;    }  /* Display information if we are debugging.  */  if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0) && loader != NULL)    _dl_debug_printf ("\nfile=%s;  needed by %s\n", name,		      loader->l_name[0] ? loader->l_name : _dl_argv[0]);  if (strchr (name, '/') == NULL)    {      /* Search for NAME in several places.  */      size_t namelen = strlen (name) + 1;      if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0))	_dl_debug_printf ("find library=%s; searching\n", name);      fd = -1;      /* When the object has the RUNPATH information we don't use any         RPATHs.  */      if (loader == NULL || loader->l_info[DT_RUNPATH] == NULL)	{	  /* First try the DT_RPATH of the dependent object that caused NAME	     to be loaded.  Then that object's dependent, and on up.  */	  for (l = loader; fd == -1 && l; l = l->l_loader)	    {	      if (l->l_rpath_dirs.dirs == NULL)		{		  if (l->l_info[DT_RPATH] == NULL)		    {		      /* There is no path.  */		      l->l_rpath_dirs.dirs = (void *) -1;		      continue;		    }		  else		    {		      /* Make sure the cache information is available.  */		      size_t ptrval = (D_PTR (l, l_info[DT_STRTAB])				       + l->l_info[DT_RPATH]->d_un.d_val);		      decompose_rpath (&l->l_rpath_dirs,				       (const char *) ptrval, l, "RPATH");		    }		}	      if (l->l_rpath_dirs.dirs != (void *) -1)		fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs,				&realname, &fb);	    }	  /* If dynamically linked, try the DT_RPATH of the executable             itself.  */	  l = _dl_loaded;	  if (fd == -1 && l && l->l_type != lt_loaded && l != loader	      && l->l_rpath_dirs.dirs != (void *) -1)	    fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs,			    &realname, &fb);	}      /* Try the LD_LIBRARY_PATH environment variable.  */      if (fd == -1 && env_path_list.dirs != (void *) -1)	fd = open_path (name, namelen, preloaded, &env_path_list,			&realname, &fb);      /* Look at the RUNPATH information for this binary.	 Note that this is no real loop.  'while' is used only to enable	 us to use 'break' instead of a 'goto' to jump to the end.  The	 loop is always left after the first round.  */      while (fd == -1 && loader != NULL	     && loader->l_runpath_dirs.dirs != (void *) -1)	{	  if (loader->l_runpath_dirs.dirs == NULL)	    {	      if (loader->l_info[DT_RUNPATH] == NULL)		{		  /* No RUNPATH.  */		  loader->l_runpath_dirs.dirs = (void *) -1;		  break;		}	      else		{		  /* Make sure the cache information is available.  */		  size_t ptrval = (D_PTR (loader, l_info[DT_STRTAB])				   + loader->l_info[DT_RUNPATH]->d_un.d_val);		  decompose_rpath (&loader->l_runpath_dirs,				   (const char *) ptrval, loader, "RUNPATH");		}	    }	  if (loader->l_runpath_dirs.dirs != (void *) -1)	    fd = open_path (name, namelen, preloaded,			    &loader->l_runpath_dirs, &realname, &fb);	  break;	}      if (fd == -1	  && (__builtin_expect (! preloaded, 1) || ! 0))	{	  /* Check the list of libraries in the file /etc/ld.so.cache,	     for compatibility with Linux's ldconfig program.  */	  const char *cached = _dl_load_cache_lookup (name);	  if (cached != NULL)	    {#ifdef SHARED	      l = loader ?: _dl_loaded;#else	      l = loader;#endif	      /* If the loader has the DF_1_NODEFLIB flag set we must not		 use a cache entry from any of these directories.  */	      if (#ifndef SHARED		  /* 'l' is always != NULL for dynamically linked objects.  */		  l != NULL &&#endif		  __builtin_expect (l->l_flags_1 & DF_1_NODEFLIB, 0))		{		  const char *dirp = system_dirs;		  unsigned int cnt = 0;		  do		    {		      if (memcmp (cached, dirp, system_dirs_len[cnt]) == 0)			{			  /* The prefix matches.  Don't use the entry.  */			  cached = NULL;			  break;			}		      dirp += system_dirs_len[cnt] + 1;		      ++cnt;		    }		  while (cnt < nsystem_dirs_len);		}	      if (cached != NULL)		{		  fd = open_verify (cached, &fb);		  if (__builtin_expect (fd != -1, 1))		    {		      realname = local_strdup (cached);		      if (realname == NULL)			{			  close (fd);			  fd = -1;			}		    }		}	    }	}      /* Finally, try the default path.  */      if (fd == -1	  && ((l = loader ?: _dl_loaded)	      /* 'l' is always != NULL for dynamically linked objects.  */#ifdef SHARED	      ,#else	      == NULL ||#endif	      __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1))	  && rtld_search_dirs.dirs != (void *) -1)	fd = open_path (name, namelen, preloaded, &rtld_search_dirs,			&realname, &fb);      /* Add another newline when we a tracing the library loading.  */      if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0))        _dl_debug_printf ("\n");    }  else    {      /* The path may contain dynamic string tokens.  */      realname = (loader		  ? expand_dynamic_string_token (loader, name)		  : local_strdup (name));      if (realname == NULL)	fd = -1;      else	{	  fd = open_verify (realname, &fb);	  if (__builtin_expect (fd, 0) == -1)	    free (realname);	}    }  if (__builtin_expect (fd, 0) == -1)    {      if (trace_mode)	{	  /* We haven't found an appropriate library.  But since we	     are only interested in the list of libraries this isn't	     so severe.  Fake an entry with all the information we	     have.  */	  static const Elf_Symndx dummy_bucket = STN_UNDEF;	  /* Enter the new object in the list of loaded objects.  */	  if ((name_copy = local_strdup (name)) == NULL	      || (l = _dl_new_object (name_copy, name, type, loader)) == NULL)	    _dl_signal_error (ENOMEM, name, NULL,			      N_("cannot create shared object descriptor"));	  /* Signal that this is a faked entry.  */	  l->l_faked = 1;	  /* Since the descriptor is initialized with zero we do not	     have do this here.	  l->l_reserved = 0; */	  l->l_buckets = &dummy_bucket;	  l->l_nbuckets = 1;	  l->l_relocated = 1;	  return l;	}      else	_dl_signal_error (errno, name, NULL,			  N_("cannot open shared object file"));    }  return _dl_map_object_from_fd (name, fd, &fb, realname, loader, type, mode);}

⌨️ 快捷键说明

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