Message ID | 20200817120906.55044-1-nixiaoming@huawei.com |
---|---|
State | New |
Headers | show |
Series | [v2] elf: Sort only uninitialized objects in _dl_map_object_deps() | expand |
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; >
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;