_dl_init_paths (const char *llp)
{
  size_t idx;
  const char *strp;
  struct r_search_path_elem *pelem, **aelem;
  size_t round_size;
#ifdef PIC
  struct link_map *l;
#endif

  /* Fill in the information about the application's RPATH and the
     directories addressed by the LD_LIBRARY_PATH environment variable.  */

  /* Get the capabilities.  */
  capstr = _dl_important_hwcaps (_dl_platform, _dl_platformlen,
				 &ncapstr, &max_capstrlen);

  /* First set up the rest of the default search directory entries.  */
  aelem = rtld_search_dirs = (struct r_search_path_elem **)
    malloc ((sizeof (system_dirs_len) / sizeof (system_dirs_len[0]) + 1)
	     * sizeof (struct r_search_path_elem *));
  if (rtld_search_dirs == NULL)
    _dl_signal_error (ENOMEM, NULL, "cannot create search path array");

  round_size = ((2 * sizeof (struct r_search_path_elem) - 1
		 + ncapstr * sizeof (enum r_dir_status))
		/ sizeof (struct r_search_path_elem));

  rtld_search_dirs[0] = (struct r_search_path_elem *)
    malloc ((sizeof (system_dirs) / sizeof (system_dirs[0]) - 1)
	    * round_size * sizeof (struct r_search_path_elem));
  if (rtld_search_dirs[0] == NULL)
    _dl_signal_error (ENOMEM, NULL, "cannot create cache for search path");

  pelem = all_dirs = rtld_search_dirs[0];
  strp = system_dirs;
  idx = 0;

  do
    {
      size_t cnt;

      *aelem++ = pelem;

      pelem->what = "system search path";
      pelem->where = NULL;

      pelem->dirname = strp;
      pelem->dirnamelen = system_dirs_len[idx];
      strp += system_dirs_len[idx] + 1;

      if (pelem->dirname[0] != '/')
	for (cnt = 0; cnt < ncapstr; ++cnt)
	  pelem->status[cnt] = existing;
      else
	for (cnt = 0; cnt < ncapstr; ++cnt)
	  pelem->status[cnt] = unknown;

      pelem->next = (++idx == (sizeof (system_dirs_len)
			       / sizeof (system_dirs_len[0]))
		     ? NULL : (pelem + round_size));

      pelem += round_size;
    }
  while (idx < sizeof (system_dirs_len) / sizeof (system_dirs_len[0]));

  max_dirnamelen = SYSTEM_DIRS_MAX_LEN;
  *aelem = NULL;

#ifdef PIC
  /* This points to the map of the main object.  */
  l = _dl_loaded;
  if (l != NULL)
    {
      assert (l->l_type != lt_loaded);

      if (l->l_info[DT_RUNPATH])
	{
	  /* Allocate room for the search path and fill in information
	     from RUNPATH.  */
	  l->l_runpath_dirs =
	    decompose_rpath ((const void *) (l->l_info[DT_STRTAB]->d_un.d_ptr
					     + l->l_info[DT_RUNPATH]->d_un.d_val),
			     l, "RUNPATH");

	  /* The RPATH is ignored.  */
	  l->l_rpath_dirs = NULL;
	}
      else
	{
	  l->l_runpath_dirs = NULL;

	  if (l->l_info[DT_RPATH])
	    /* Allocate room for the search path and fill in information
	       from RPATH.  */
	    l->l_rpath_dirs =
	      decompose_rpath ((const void *) (l->l_info[DT_STRTAB]->d_un.d_ptr
					       + l->l_info[DT_RPATH]->d_un.d_val),
			       l, "RPATH");
	  else
	    l->l_rpath_dirs = NULL;
	}
    }
#endif	/* PIC */

  if (llp != NULL && *llp != '\0')
    {
      size_t nllp;
      const char *cp = llp;

      /* Decompose the LD_LIBRARY_PATH contents.  First determine how many
	 elements it has.  */
      nllp = 1;
      while (*cp)
	{
	  if (*cp == ':' || *cp == ';')
	    ++nllp;
	  ++cp;
	}

      env_path_list = (struct r_search_path_elem **)
	malloc ((nllp + 1) * sizeof (struct r_search_path_elem *));
      if (env_path_list == NULL)
	_dl_signal_error (ENOMEM, NULL,
			  "cannot create cache for search path");

      (void) fillin_rpath (local_strdup (llp), env_path_list, ":;",
			   __libc_enable_secure, "LD_LIBRARY_PATH", NULL);
    }
}