[v2] elf: Sort only uninitialized objects in _dl_map_object_deps()
Commit Message
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
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;
>
@@ -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;