[v2] elf: Sort only uninitialized objects in _dl_map_object_deps()

Message ID 20200817120906.55044-1-nixiaoming@huawei.com
State Rejected
Headers
Series [v2] elf: Sort only uninitialized objects in _dl_map_object_deps() |

Commit Message

Xiaoming Ni Aug. 17, 2020, 12:09 p.m. UTC
  TIS ELF Version 1.2
Initialization and Termination Functions:
	1. Before the initialization code for any object A is called, the
	   initialization code for any other objects that object A depends
	   on are called.
	2. The order in which the dynamic linker calls termination functions
	   is the exact reverse order of their corresponding initialization
	   functions.
	3. The dynamic linker ensures that it will not execute any
	   initialization or termination functions more than once.

According to 1 and 2: _dl_sort_maps() is used for sorting when dlopen/dlclose.
According to 3: At dlopen, only the uninitialized objects need to be sorted.

v1: https://public-inbox.org/libc-alpha/20200725105205.103328-1-nixiaoming@huawei.com/
The new function _dl_sort_uninit_maps():
 sorts the linked list based on whether the object has been initialized,

v2:
the Chung-Lin Tang patch has optimized the sorting algorithm complexity to
linear:
	https://patchwork.sourceware.org/project/glibc/patch/1427b370-7400-afd0-16e8-55c1072db20e@mentor.com/
	https://patchwork.sourceware.org/project/glibc/patch/5de3ab61-3dca-b400-15c6-92ff5ae80877@mentor.com/
When the algorithm complexity of _dl_sort_maps() has been optimized, the benefits brought by
_dl_sort_uninit_maps() are not obvious.
	https://public-inbox.org/libc-alpha/accfd786-0d1e-bb27-d950-76ab30633767@mentor.com/
so _dl_sort_uninit_maps() is deleted from v2.
Avoid unnecessary sorting only when the entire linked list has been initialized.
---
 elf/dl-deps.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)
  

Comments

Xiaoming Ni Aug. 24, 2020, 1:14 a.m. UTC | #1
ping

On 2020/8/17 20:09, Xiaoming Ni wrote:
> TIS ELF Version 1.2
> Initialization and Termination Functions:
> 	1. Before the initialization code for any object A is called, the
> 	   initialization code for any other objects that object A depends
> 	   on are called.
> 	2. The order in which the dynamic linker calls termination functions
> 	   is the exact reverse order of their corresponding initialization
> 	   functions.
> 	3. The dynamic linker ensures that it will not execute any
> 	   initialization or termination functions more than once.
> 
> According to 1 and 2: _dl_sort_maps() is used for sorting when dlopen/dlclose.
> According to 3: At dlopen, only the uninitialized objects need to be sorted.
> 
> v1: https://public-inbox.org/libc-alpha/20200725105205.103328-1-nixiaoming@huawei.com/
> The new function _dl_sort_uninit_maps():
>   sorts the linked list based on whether the object has been initialized,
> 
> v2:
> the Chung-Lin Tang patch has optimized the sorting algorithm complexity to
> linear:
> 	https://patchwork.sourceware.org/project/glibc/patch/1427b370-7400-afd0-16e8-55c1072db20e@mentor.com/
> 	https://patchwork.sourceware.org/project/glibc/patch/5de3ab61-3dca-b400-15c6-92ff5ae80877@mentor.com/
> When the algorithm complexity of _dl_sort_maps() has been optimized, the benefits brought by
> _dl_sort_uninit_maps() are not obvious.
> 	https://public-inbox.org/libc-alpha/accfd786-0d1e-bb27-d950-76ab30633767@mentor.com/
> so _dl_sort_uninit_maps() is deleted from v2.
> Avoid unnecessary sorting only when the entire linked list has been initialized.
> ---
>   elf/dl-deps.c | 15 ++++++++++++++-
>   1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/elf/dl-deps.c b/elf/dl-deps.c
> index b5a43232a7..8f377302bf 100644
> --- a/elf/dl-deps.c
> +++ b/elf/dl-deps.c
> @@ -611,7 +611,20 @@ Filters not supported with LD_TRACE_PRELINKING"));
>       memcpy (l_initfini, map->l_searchlist.r_list,
>   	    nlist * sizeof (struct link_map *));
>   
> -  _dl_sort_maps (&l_initfini[1], nlist - 1, NULL, false);
> +  /* TIS  ELF Version 1.2
> +   * Initialization and Termination Functions:
> +   * 1. Before the initialization code for any object A is called, the
> +   *  initialization code for any other objects that object A depends on are called.
> +   * 2. The order in which the dynamic linker calls termination functions is the
> +   *  exact reverse order of their corresponding initialization functions.
> +   * 3. The dynamic linker ensures that it will not execute any initialization
> +   *  or termination functions more than once.
> +   *
> +   * According to 1 and 2, _dl_sort_maps() is used for sorting when dlopen/dlclose.
> +   * According to 3, we only need to sort the uninitialized objects.
> +   */
> +  if (map->l_init_called == 0)
> +    _dl_sort_maps (&l_initfini[1], nlist - 1, NULL, false);
>   
>     /* Terminate the list of dependencies.  */
>     l_initfini[nlist] = NULL;
>
  

Patch

diff --git a/elf/dl-deps.c b/elf/dl-deps.c
index b5a43232a7..8f377302bf 100644
--- a/elf/dl-deps.c
+++ b/elf/dl-deps.c
@@ -611,7 +611,20 @@  Filters not supported with LD_TRACE_PRELINKING"));
     memcpy (l_initfini, map->l_searchlist.r_list,
 	    nlist * sizeof (struct link_map *));
 
-  _dl_sort_maps (&l_initfini[1], nlist - 1, NULL, false);
+  /* TIS  ELF Version 1.2
+   * Initialization and Termination Functions:
+   * 1. Before the initialization code for any object A is called, the
+   *  initialization code for any other objects that object A depends on are called.
+   * 2. The order in which the dynamic linker calls termination functions is the
+   *  exact reverse order of their corresponding initialization functions.
+   * 3. The dynamic linker ensures that it will not execute any initialization
+   *  or termination functions more than once.
+   *
+   * According to 1 and 2, _dl_sort_maps() is used for sorting when dlopen/dlclose.
+   * According to 3, we only need to sort the uninitialized objects.
+   */
+  if (map->l_init_called == 0)
+    _dl_sort_maps (&l_initfini[1], nlist - 1, NULL, false);
 
   /* Terminate the list of dependencies.  */
   l_initfini[nlist] = NULL;