[Bug dynamic-link/25615] New: dlopen RTLD_NOLOAD optimization

conanhc at gmail dot com sourceware-bugzilla@sourceware.org
Fri Feb 28 23:40:00 GMT 2020


https://sourceware.org/bugzilla/show_bug.cgi?id=25615

            Bug ID: 25615
           Summary: dlopen RTLD_NOLOAD optimization
           Product: glibc
           Version: 2.31
            Status: UNCONFIRMED
          Severity: minor
          Priority: P2
         Component: dynamic-link
          Assignee: unassigned at sourceware dot org
          Reporter: conanhc at gmail dot com
  Target Milestone: ---

When dlopen with RTLD_NOLOAD flag without RTLD_GLOBAL promotion, loader should
simply return the link_map or NULL and promote other flags like RTLD_NODELETE.

Loader shouldn't need to process any dependencies. In dl_open_worker, loader
should avoid calling _dl_map_object_deps. _dl_map_object_deps is very time
consuming on low-end platforms with lots of library dependencies.

dl_open_worker already have a similar check for libraries that are directly
dlopened
  /* It was already open.  */
  if (__glibc_unlikely (new->l_searchlist.r_list != NULL))
    {
      /* Let the user know about the opencount.  */
      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
    _dl_debug_printf ("opening file=%s [%lu]; direct_opencount=%u\n\n",
              new->l_name, new->l_ns, new->l_direct_opencount);

      /* If the user requested the object to be in the global
     namespace but it is not so far, prepare to add it now.  This
     can raise an exception to do a malloc failure.  */
      if ((mode & RTLD_GLOBAL) && new->l_global == 0)
    add_to_global_resize (new);

      /* Mark the object as not deletable if the RTLD_NODELETE flags
     was passed.  */
      if (__glibc_unlikely (mode & RTLD_NODELETE))
    {
      if (__glibc_unlikely (GLRO (dl_debug_mask) & DL_DEBUG_FILES)
          && !new->l_nodelete_active)
        _dl_debug_printf ("marking %s [%lu] as NODELETE\n",
                  new->l_name, new->l_ns);
      new->l_nodelete_active = true;
    }

      /* Finalize the addition to the global scope.  */
      if ((mode & RTLD_GLOBAL) && new->l_global == 0)
    add_to_global_update (new);

      assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT);

      return;
    }

However, this does not cover the case when we dlopen(RTLD_NOLOAD) a library
thats a dependency of program or dependency of a dlopened library. Loader sill
calls _dl_map_object_deps; load the dependencies, and then generates
l_searchlist; so subsequence calls can skip it.

An optimization can be made, such as if ((mode & RTLD_NOLOAD) && !((mode &
RTLD_GLOBAL) && new->l_global == 0)), loader simply promotes any other flag,
and returns.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


More information about the Glibc-bugs mailing list