diff options
author | Milan Stastny | 2021-12-12 13:58:33 +0100 |
---|---|---|
committer | Milan Stastny | 2021-12-12 13:58:33 +0100 |
commit | b10b1148ceeb738e85727f1db503f9e61c0adf8d (patch) | |
tree | 4a4c9885cc44bb0839841f8f3eb1920e585a2680 | |
parent | e2bbf6a1fc9d9c280f575d302b6a07bd5f97ed16 (diff) | |
download | aur-b10b1148ceeb738e85727f1db503f9e61c0adf8d.tar.gz |
Update to the final patch
-rw-r--r-- | .SRCINFO | 10 | ||||
-rw-r--r-- | PKGBUILD | 14 | ||||
-rw-r--r-- | v8-1-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Testing-infrastructure.patch (renamed from v6-1-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Testing-infrastructure.patch) | 152 | ||||
-rw-r--r-- | v8-2-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Algorithm-changes.patch (renamed from v6-2-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Algorithm-changes.patch) | 183 |
4 files changed, 233 insertions, 126 deletions
@@ -1,6 +1,6 @@ pkgbase = glibc-dso pkgver = 2.33 - pkgrel = 8 + pkgrel = 9 url = https://www.gnu.org/software/libc arch = x86_64 license = GPL @@ -24,8 +24,8 @@ pkgbase = glibc-dso source = 0001-nptl_db-Support-different-libpthread-ld.so-load-orde.patch source = 0002-nptl-Check-for-compatible-GDB-in-nptl-tst-pthread-gd.patch source = 0003-nptl-Do-not-build-nptl-tst-pthread-gdb-attach-as-PIE.patch - source = v6-1-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Testing-infrastructure.patch - source = v6-2-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Algorithm-changes.patch + source = v8-1-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Testing-infrastructure.patch + source = v8-2-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Algorithm-changes.patch validpgpkeys = 7273542B39962DF7B299931416792B4EA25340F8 validpgpkeys = BC7C7372637EC10C57D7AA6579C43DFBF1CF2187 md5sums = 390bbd889c7e8e8a7041564cb6b27cca @@ -39,8 +39,8 @@ pkgbase = glibc-dso md5sums = 78f041fc66fee4ee372f13b00a99ff72 md5sums = 9e418efa189c20053e887398df2253cf md5sums = 7a09f1693613897add1791e7aead19c9 - md5sums = c553dbe5e7ae410629ca068d43ab7ebf - md5sums = b83e5a982dc5ec58c69e30672ca903fe + md5sums = 5974b86859dd65c7cfda756a8b2445c2 + md5sums = 26a619a810de7d296608cc78377bc27c pkgname = glibc-dso pkgdesc = GNU C Library - DSO patch @@ -6,7 +6,7 @@ pkgbase=glibc-dso pkgname=(glibc-dso lib32-glibc-dso) pkgver=2.33 -pkgrel=8 +pkgrel=9 arch=(x86_64) url='https://www.gnu.org/software/libc' license=(GPL LGPL) @@ -24,8 +24,8 @@ source=(https://ftp.gnu.org/gnu/glibc/glibc-$pkgver.tar.xz{,.sig} 0001-nptl_db-Support-different-libpthread-ld.so-load-orde.patch 0002-nptl-Check-for-compatible-GDB-in-nptl-tst-pthread-gd.patch 0003-nptl-Do-not-build-nptl-tst-pthread-gdb-attach-as-PIE.patch - v6-1-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Testing-infrastructure.patch - v6-2-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Algorithm-changes.patch) + v8-1-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Testing-infrastructure.patch + v8-2-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Algorithm-changes.patch) validpgpkeys=(7273542B39962DF7B299931416792B4EA25340F8 # Carlos O'Donell BC7C7372637EC10C57D7AA6579C43DFBF1CF2187) # Siddhesh Poyarekar md5sums=('390bbd889c7e8e8a7041564cb6b27cca' @@ -39,8 +39,8 @@ md5sums=('390bbd889c7e8e8a7041564cb6b27cca' '78f041fc66fee4ee372f13b00a99ff72' '9e418efa189c20053e887398df2253cf' '7a09f1693613897add1791e7aead19c9' - 'c553dbe5e7ae410629ca068d43ab7ebf' - 'b83e5a982dc5ec58c69e30672ca903fe') + '5974b86859dd65c7cfda756a8b2445c2' + '26a619a810de7d296608cc78377bc27c') prepare() { mkdir -p glibc-build lib32-glibc-build @@ -59,8 +59,8 @@ prepare() { # nptl: Do not build nptl/tst-pthread-gdb-attach as PIE patch -p1 -i "$srcdir"/0003-nptl-Do-not-build-nptl-tst-pthread-gdb-attach-as-PIE.patch - patch -p1 -i "$srcdir"/v6-1-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Testing-infrastructure.patch - patch -p1 -i "$srcdir"/v6-2-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Algorithm-changes.patch + patch -p1 -i "$srcdir"/v8-1-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Testing-infrastructure.patch + patch -p1 -i "$srcdir"/v8-2-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Algorithm-changes.patch } build() { diff --git a/v6-1-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Testing-infrastructure.patch b/v8-1-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Testing-infrastructure.patch index 7b241a485933..82431bea85a3 100644 --- a/v6-1-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Testing-infrastructure.patch +++ b/v8-1-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Testing-infrastructure.patch @@ -1,8 +1,8 @@ diff --git a/elf/Makefile b/elf/Makefile -index 4fe60947ad..fe7a8b418f 100644 +index bf45d8ee24..bdcf4cb885 100644 --- a/elf/Makefile +++ b/elf/Makefile -@@ -469,6 +469,21 @@ tests-special += $(objpfx)order-cmp.out $(objpfx)tst-array1-cmp.out \ +@@ -477,6 +477,21 @@ tests-special += $(objpfx)order-cmp.out $(objpfx)tst-array1-cmp.out \ $(objpfx)tst-unused-dep-cmp.out endif @@ -26,10 +26,10 @@ index 4fe60947ad..fe7a8b418f 100644 update-abi: update-abi-ld diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def new file mode 100644 -index 0000000000..51f1d2e158 +index 0000000000..873ddf55d9 --- /dev/null +++ b/elf/dso-sort-tests-1.def -@@ -0,0 +1,66 @@ +@@ -0,0 +1,66 @@ +# DSO sorting test descriptions. +# This file is to be processed by ../scripts/dso-ordering-test.py, see usage +# in elf/Makefile for how it is executed. @@ -69,7 +69,7 @@ index 0000000000..51f1d2e158 +output: f>e>d>c>b>a>{}<a<b<c<d<e<f + +# Sequence where the DSO c is unerlinked and calls a function in DSO a which -+# is technically a cycle. The main executable depends on the first two DSOs. ++# is technically a cycle. The main executable depends on the first two DSOs. +# Note: This test has unspecified behavior. +tst-dso-ordering8: a->b->c=>a;{}->[ba] +output: c>b>a>{}<a<b<c @@ -94,19 +94,19 @@ index 0000000000..51f1d2e158 +# The below expected outputs are what the two algorithms currently produce +# respectively, for regression testing purposes. +tst-bz15311: {+a;+e;+f;+g;+d;%d;-d;-g;-f;-e;-a};a->b->c->d;d=>[ba];c=>a;b=>e=>a;c=>f=>b;d=>g=>c -+output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<c<d<g<f<b<e];} ++xfail_output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<c<d<g<f<b<e];} +output(glibc.rtld.dynamic_sort=2): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<g<f<a<b<c<d<e];} diff --git a/elf/dso-sort-tests-2.def b/elf/dso-sort-tests-2.def new file mode 100644 -index 0000000000..865f57be04 +index 0000000000..b79e79ecb7 --- /dev/null +++ b/elf/dso-sort-tests-2.def -@@ -0,0 +1,614 @@ +@@ -0,0 +1,614 @@ +# Large DSO sorting testcase adapted from Red Hat Bugzilla 1162810 +# +# Note that below we specify different expected outputs between dynamic_sort=1 +# and dynamic_sort=2 algorithms, due to circular dependencies in the testcase -+# causing different sorting behavior. These expected outputs are what the two ++# causing different sorting behavior. These expected outputs are what the two +# algorithms currently produce, and are used for regression comparison tests. +# They are not "definitively" correct outputs, for circular dependencies +# inherently have unspecified behavior. @@ -718,10 +718,10 @@ index 0000000000..865f57be04 +output(glibc.rtld.dynamic_sort=2): M30X19>M30X15>M30X16>M30X11>M30X12>M30X17>M30X13>M30X14>M29X20>M30X23>M30X24>M30X20>M30X18>M29X15>M29X12>M30X22>M30X21>M29X22>M30X25>M29X19>M29X23>M29X16>M29X24>M29X13>M29X17>M29X18>M28X19>M29X21>M29X25>M29X14>M28X20>M28X15>M28X16>M28X21>M27X18>M29X11>M28X17>M28X11>M28X22>M28X24>M28X23>M27X21>M28X13>M27X20>M27X19>M26X14>M27X25>M28X18>M27X11>M28X25>M27X24>M26X24>M27X15>M27X14>M27X13>M26X23>M27X17>M26X22>M25X13>M28X14>M27X16>M26X19>M26X18>M27X23>M27X22>M26X17>M25X18>M26X21>M25X17>M26X20>M26X15>M26X13>M25X19>M24X14>M25X23>M26X11>M26X25>M25X16>M25X15>M24X22>M25X21>M25X20>M24X21>M25X25>M25X24>M24X20>M23X13>M22X15>M25X14>M24X19>M23X17>M24X25>M23X24>M24X13>M23X15>M24X18>M23X14>M22X11>M24X15>M23X22>M24X11>M23X19>M22X21>M24X24>M23X21>M22X20>M23X25>M22X19>M21X24>M20X23>M22X22>M25X11>M23X16>M22X18>M23X20>M22X17>M21X21>M21X20>M20X24>M22X14>M22X13>M21X11>M21X17>M22X23>M21X16>M20X25>M19X23>M18X16>M21X22>M20X20>M20X19>M21X13>M20X18>M19X13>M21X18>M20X21>M19X24>M18X12>M20X14>M20X13>M22X25>M20X12>M20X15>M19X14>M18X22>M19X18>M20X17>M19X17>M19X16>M18X21>M17X20>M19X19>M18X13>M17X11>M18X17>M19X25>M18X15>M17X25>M18X19>M17X24>M16X19>M15X17>M17X21>M16X24>M18X23>M17X16>M16X25>M19X15>M18X25>M17X23>M16X23>M15X23>M18X14>M17X14>M16X14>M17X18>M16X13>M17X22>M16X12>M15X22>M14X16>M17X12>M16X22>M15X12>M16X11>M15X11>M16X15>M15X25>M14X15>M13X14>M15X18>M16X21>M15X16>M14X21>M15X14>M16X20>M15X13>M14X22>M15X20>M14X20>M13X20>M14X11>M15X19>M14X24>M13X19>M14X13>M13X18>M12X13>M15X24>M14X23>M13X12>M14X12>M13X11>M12X11>M11X11>M21X12>M20X11>M19X11>M18X11>M17X15>M16X18>M14X25>M14X19>M13X24>M13X23>M13X22>M12X12>M22X12>M21X15>M19X22>M18X20>M16X17>M14X14>M24X12>M23X23>M22X16>M21X14>M20X22>M18X24>M16X16>M26X12>M24X16>M23X11>M21X23>M19X20>M17X17>M27X12>M26X16>M25X22>M24X17>M23X18>M21X25>M19X12>M17X19>M15X21>M14X18>M13X13>M23X12>M21X19>M19X21>M17X13>M15X15>M25X12>M24X23>M22X24>M20X16>M18X18>M28X12>A150>C158>B112>A112>C167>B146>A146>C180>B180>A180>C143>B143>A115>C126>B126>A126>C190>B190>A190>C138>B138>A138>C174>B174>A102>C122>B122>A122>C162>B162>A162>C142>B142>A142>C102>B102>A174>C176>B176>A176>C115>B115>A143>C172>B172>A172>C187>B187>A187>C130>B130>A130>C118>B118>A118>C184>B184>A184>C171>B171>A171>C168>B182>A182>C182>B168>A168>C109>B109>A109>C159>B159>A159>C134>B134>A134>C146>B167>A167>C140>B140>A140>C163>B163>A163>C112>B158>A158>C164>B164>A164>C131>B131>A131>C188>B188>A188>C199>B199>A199>C114>B114>A114>C106>B106>A106>C200>B200>A200>C183>B183>A183>C152>B152>A152>C147>B147>A147>C150>B150>A198>C144>B144>A144>C191>B191>A191>C108>B108>A108>C139>B139>A139>C194>B194>A194>C166>B166>A166>C120>B120>A120>C123>B123>A123>C132>B132>A132>C107>B107>A107>C170>B170>A170>C198>B198>A156>C125>B125>A125>C121>B121>A121>C193>B193>A193>C197>B197>A197>C175>B175>A175>C196>B196>A196>C105>B105>A105>C181>B181>A181>C113>B113>A113>C137>B137>A137>C155>B155>A155>C156>B156>A110>C128>B128>A128>C179>B179>A179>C124>B124>A124>C151>B151>A151>C178>B178>A178>C104>B104>A104>C111>B111>A111>C148>B148>A148>C169>B169>A169>C129>B129>A129>C149>B149>A149>C189>B189>A189>C119>B119>A119>C154>B154>A154>C136>B136>A136>C135>B135>A135>C116>B116>A116>C145>B145>A145>C161>B161>A161>C173>B173>A173>C157>B157>A157>C195>B195>A195>C186>B186>A186>C160>B160>A160>C153>B153>A153>C117>B117>A117>C165>B165>A165>C101>B101>A101>C103>B103>A103>C192>B192>A192>C177>B177>A177>C185>B185>A185>C141>B141>A141>C133>B133>A133>C127>B127>A127>C110>B110>M14X17>M13X15>M13X16>M13X17>M12X17>M12X21>M12X25>M12X14>M13X25>M12X15>M13X21>M12X16>M12X18>M12X19>M12X20>M12X22>M12X23>M12X24>M11X25>M11X24>M11X23>M11X22>M11X21>M11X20>M11X19>M11X18>M11X17>M11X16>M11X15>M11X14>M11X13>M11X12>{}<M11X12<M11X13<M11X14<M11X15<M11X16<M11X17<M11X18<M11X19<M11X20<M11X21<M11X22<M11X23<M11X24<M11X25<M12X24<M12X23<M12X22<M12X20<M12X19<M12X18<M12X16<M13X21<M12X15<M13X25<M12X14<M12X25<M12X21<M12X17<M13X17<M13X16<M13X15<M14X17<B110<C110<A127<B127<C127<A133<B133<C133<A141<B141<C141<A185<B185<C185<A177<B177<C177<A192<B192<C192<A103<B103<C103<A101<B101<C101<A165<B165<C165<A117<B117<C117<A153<B153<C153<A160<B160<C160<A186<B186<C186<A195<B195<C195<A157<B157<C157<A173<B173<C173<A161<B161<C161<A145<B145<C145<A116<B116<C116<A135<B135<C135<A136<B136<C136<A154<B154<C154<A119<B119<C119<A189<B189<C189<A149<B149<C149<A129<B129<C129<A169<B169<C169<A148<B148<C148<A111<B111<C111<A104<B104<C104<A178<B178<C178<A151<B151<C151<A124<B124<C124<A179<B179<C179<A128<B128<C128<A110<B156<C156<A155<B155<C155<A137<B137<C137<A113<B113<C113<A181<B181<C181<A105<B105<C105<A196<B196<C196<A175<B175<C175<A197<B197<C197<A193<B193<C193<A121<B121<C121<A125<B125<C125<A156<B198<C198<A170<B170<C170<A107<B107<C107<A132<B132<C132<A123<B123<C123<A120<B120<C120<A166<B166<C166<A194<B194<C194<A139<B139<C139<A108<B108<C108<A191<B191<C191<A144<B144<C144<A198<B150<C150<A147<B147<C147<A152<B152<C152<A183<B183<C183<A200<B200<C200<A106<B106<C106<A114<B114<C114<A199<B199<C199<A188<B188<C188<A131<B131<C131<A164<B164<C164<A158<B158<C112<A163<B163<C163<A140<B140<C140<A167<B167<C146<A134<B134<C134<A159<B159<C159<A109<B109<C109<A168<B168<C182<A182<B182<C168<A171<B171<C171<A184<B184<C184<A118<B118<C118<A130<B130<C130<A187<B187<C187<A172<B172<C172<A143<B115<C115<A176<B176<C176<A174<B102<C102<A142<B142<C142<A162<B162<C162<A122<B122<C122<A102<B174<C174<A138<B138<C138<A190<B190<C190<A126<B126<C126<A115<B143<C143<A180<B180<C180<A146<B146<C167<A112<B112<C158<A150<M28X12<M18X18<M20X16<M22X24<M24X23<M25X12<M15X15<M17X13<M19X21<M21X19<M23X12<M13X13<M14X18<M15X21<M17X19<M19X12<M21X25<M23X18<M24X17<M25X22<M26X16<M27X12<M17X17<M19X20<M21X23<M23X11<M24X16<M26X12<M16X16<M18X24<M20X22<M21X14<M22X16<M23X23<M24X12<M14X14<M16X17<M18X20<M19X22<M21X15<M22X12<M12X12<M13X22<M13X23<M13X24<M14X19<M14X25<M16X18<M17X15<M18X11<M19X11<M20X11<M21X12<M11X11<M12X11<M13X11<M14X12<M13X12<M14X23<M15X24<M12X13<M13X18<M14X13<M13X19<M14X24<M15X19<M14X11<M13X20<M14X20<M15X20<M14X22<M15X13<M16X20<M15X14<M14X21<M15X16<M16X21<M15X18<M13X14<M14X15<M15X25<M16X15<M15X11<M16X11<M15X12<M16X22<M17X12<M14X16<M15X22<M16X12<M17X22<M16X13<M17X18<M16X14<M17X14<M18X14<M15X23<M16X23<M17X23<M18X25<M19X15<M16X25<M17X16<M18X23<M16X24<M17X21<M15X17<M16X19<M17X24<M18X19<M17X25<M18X15<M19X25<M18X17<M17X11<M18X13<M19X19<M17X20<M18X21<M19X16<M19X17<M20X17<M19X18<M18X22<M19X14<M20X15<M20X12<M22X25<M20X13<M20X14<M18X12<M19X24<M20X21<M21X18<M19X13<M20X18<M21X13<M20X19<M20X20<M21X22<M18X16<M19X23<M20X25<M21X16<M22X23<M21X17<M21X11<M22X13<M22X14<M20X24<M21X20<M21X21<M22X17<M23X20<M22X18<M23X16<M25X11<M22X22<M20X23<M21X24<M22X19<M23X25<M22X20<M23X21<M24X24<M22X21<M23X19<M24X11<M23X22<M24X15<M22X11<M23X14<M24X18<M23X15<M24X13<M23X24<M24X25<M23X17<M24X19<M25X14<M22X15<M23X13<M24X20<M25X24<M25X25<M24X21<M25X20<M25X21<M24X22<M25X15<M25X16<M26X25<M26X11<M25X23<M24X14<M25X19<M26X13<M26X15<M26X20<M25X17<M26X21<M25X18<M26X17<M27X22<M27X23<M26X18<M26X19<M27X16<M28X14<M25X13<M26X22<M27X17<M26X23<M27X13<M27X14<M27X15<M26X24<M27X24<M28X25<M27X11<M28X18<M27X25<M26X14<M27X19<M27X20<M28X13<M27X21<M28X23<M28X24<M28X22<M28X11<M28X17<M29X11<M27X18<M28X21<M28X16<M28X15<M28X20<M29X14<M29X25<M29X21<M28X19<M29X18<M29X17<M29X13<M29X24<M29X16<M29X23<M29X19<M30X25<M29X22<M30X21<M30X22<M29X12<M29X15<M30X18<M30X20<M30X24<M30X23<M29X20<M30X14<M30X13<M30X17<M30X12<M30X11<M30X16<M30X15<M30X19 diff --git a/scripts/dso-ordering-test.py b/scripts/dso-ordering-test.py new file mode 100644 -index 0000000000..5dfb3476fa +index 0000000000..944ee74052 --- /dev/null +++ b/scripts/dso-ordering-test.py -@@ -0,0 +1,1150 @@ +@@ -0,0 +1,1144 @@ +#!/usr/bin/python3 +# Generate testcase files and Makefile fragments for DSO sorting test +# Copyright (C) 2021 Free Software Foundation, Inc. @@ -755,12 +755,12 @@ index 0000000000..5dfb3476fa +construction of complex dependency cases, however it must be noted that this +is only a tool to speed up testcase construction, and thus the generation +features are largely mechanical in nature; inconsistencies or errors may occur -+if the input description was itself erroronous or have unforeseen interactions. ++if the input description was itself erroneous or have unforeseen interactions. + +The format of the input test description files are: + + # Each test description has a name, lines of description, -+ # and an expected output specification. Comments use '#'. ++ # and an expected output specification. Comments use '#'. + testname1: <test-description-line> + output: <expected-output-string> + @@ -784,7 +784,7 @@ index 0000000000..5dfb3476fa + + # 'testname3' will be run and compared two times, for both + # GLIBC_TUNABLES=<glibc-tunable-string1> and -+ # GLIBC_TUNABLES=<glibc-tunable-string2>. This can be cleared and reset by the ++ # GLIBC_TUNABLES=<glibc-tunable-string2>. This can be cleared and reset by the + # 'clear_tunables' command: + clear_tunables + @@ -837,15 +837,15 @@ index 0000000000..5dfb3476fa +e.g. a=>b emits 'a(b())' + +For single character object names, square brackets [] in the description -+allows specifiying multiple objects; e.g. a->[bcd]->e is equivalent to ++allows specifying multiple objects; e.g. a->[bcd]->e is equivalent to + a->b->e;a->c->e;a->d->e + +The () parenthesis construct with space separated names is also allowed for -+specifying objects. For names with integer suffixes a range can also be used, ++specifying objects. For names with integer suffixes a range can also be used, +e.g. (foo1 bar2-5), specifies DSOs foo1, bar2, bar2, bar3, bar4, bar5. + +A {} construct specifies the main test program, and its link dependencies -+are also specified using ->. Inside {}, a few ;-seperated constructs are ++are also specified using ->. Inside {}, a few ;-separated constructs are +allowed: + +a Loads module a using dlopen(RTLD_LAZY|RTLD_GLOBAL) + ^a Loads module a using dlopen(RTLD_LAZY) @@ -854,7 +854,7 @@ index 0000000000..5dfb3476fa + -a Unloads module a using dlclose() + +The generated main program outputs '{' '}' with all output from above -+constructs in between. The other output before/after {} are the ordered ++constructs in between. The other output before/after {} are the ordered +constructor/destructor output. + +If no {} construct is present, a default empty main program is linked @@ -872,7 +872,7 @@ index 0000000000..5dfb3476fa + {}->foo,{}->* + +Note that '*' works not only on main{}, but can be used as the -+dependency target of any object. Note that it only works as a target, ++dependency target of any object. Note that it only works as a target, +not a dependency source. + +The '!' operator after object names turns on permutation of its @@ -880,7 +880,7 @@ index 0000000000..5dfb3476fa +with 'a.so' built with a link line of "b.so c.so d.so", for a!->[bcd] +permutations of a's dependencies creates multiple testcases with +different link line orders: "b.so c.so d.so", "c.so b.so d.so", -+"b.so d.so c.so", etc. Note that for a <test-name> specified on ++"b.so d.so c.so", etc. Note that for a <test-name> specified on +the script command-line, multiple <test-name_1>, <test-name_2>, etc. +tests will be generated (e.g. for a!->[bc]!->[de], eight tests with +different link orders for a, b, and c will be generated) @@ -913,10 +913,10 @@ index 0000000000..5dfb3476fa +its constructor run first, followed by 'b' and then 'a'. + +Destructor output for each DSO is a '<' character followed by its name, -+reflecting its reverse nature of constructors. In the above example, the ++reflecting its reverse nature of constructors. In the above example, the +destructor output part is "<a<b<c". + -+The middle "{}" part is the main program. In this simple example, nothing ++The middle "{}" part is the main program. In this simple example, nothing +was specified for the main program, so by default it is implicitly linked +to the DSO 'a' (with no other DSOs depending on it) and only prints the +brackets {} with no actions inside. @@ -929,22 +929,21 @@ index 0000000000..5dfb3476fa + +The constructor and destructor parts display the a->h dependency as expected. +Inside the main program, the "+c" action triggers a dlopen() of DSO 'c', -+causing another chain of constructors "g>c>" to be triggered. Here it is -+displayed inside [] brackets for each dlopen call. The same is done for "-c", ++causing another chain of constructors "g>c>" to be triggered. Here it is ++displayed inside [] brackets for each dlopen call. The same is done for "-c", +a dlclose() of 'c'. + +The "%c" output is due to calling to fn_c() inside DSO 'c', this comprises +of two parts: the '%' character is printed by the caller, here it is the main -+program. The 'c' character is printed from inside fn_c(). The '%' character -+indicates that this is called by a dlsym() of "fn_c". A '@' character would -+mean a direct call (with a symbol reference). These can all be controlled ++program. The 'c' character is printed from inside fn_c(). The '%' character ++indicates that this is called by a dlsym() of "fn_c". A '@' character would ++mean a direct call (with a symbol reference). These can all be controlled +by the main test program constructs documented earlier. + +The output strings described here is the exact same form placed in +test description files' "output: <expected output>" line. -+ -+ +""" ++ +import sys +import re +import os @@ -959,33 +958,40 @@ index 0000000000..5dfb3476fa +# and can be changed here to another toolchain path if needed. +build_gcc = "gcc" + -+parser = argparse.ArgumentParser("") -+parser.add_argument("description", -+ help="Description string of DSO dependency test to be " -+ "generated (see script source for documentation of " -+ "description language), either specified here as " -+ "command line argument, or by input file using " -+ "-f/--description-file option", -+ nargs="?", default="") -+parser.add_argument("test_name", help="Identifier for testcase being " -+ "generated", nargs="?", default="") -+parser.add_argument("--objpfx", -+ help="Path to place generated files, defaults to " -+ "current directory if none specified", -+ nargs="?", default="./") -+parser.add_argument("-m", "--output-makefile", -+ help="File to write Makefile fragment to, defaults to " -+ "stdout when option not present", nargs="?", default="") -+parser.add_argument("-f", "--description-file", -+ help="Input file containing testcase descriptions", -+ nargs="?", default="") -+parser.add_argument("--build", help="After C testcase generated, build it " -+ "using gcc (for manual testing purposes)", -+ action="store_true") -+parser.add_argument("--debug-output", help="Prints some internal data " -+ "structures; used for debugging of this script", -+ action="store_true") -+cmdlineargs = parser.parse_args() ++def get_parser(): ++ parser = argparse.ArgumentParser("") ++ parser.add_argument("description", ++ help="Description string of DSO dependency test to be " ++ "generated (see script source for documentation of " ++ "description language), either specified here as " ++ "command line argument, or by input file using " ++ "-f/--description-file option", ++ nargs="?", default="") ++ parser.add_argument("test_name", ++ help="Identifier for testcase being generated", ++ nargs="?", default="") ++ parser.add_argument("--objpfx", ++ help="Path to place generated files, defaults to " ++ "current directory if none specified", ++ nargs="?", default="./") ++ parser.add_argument("-m", "--output-makefile", ++ help="File to write Makefile fragment to, defaults to " ++ "stdout when option not present", ++ nargs="?", default="") ++ parser.add_argument("-f", "--description-file", ++ help="Input file containing testcase descriptions", ++ nargs="?", default="") ++ parser.add_argument("--build", help="After C testcase generated, build it " ++ "using gcc (for manual testing purposes)", ++ action="store_true") ++ parser.add_argument("--debug-output", ++ help="Prints some internal data " ++ "structures; used for debugging of this script", ++ action="store_true") ++ return parser ++ ++# Main script starts here. ++cmdlineargs = get_parser().parse_args() +test_name = cmdlineargs.test_name +description = cmdlineargs.description +objpfx = cmdlineargs.objpfx @@ -1024,8 +1030,6 @@ index 0000000000..5dfb3476fa + + # list of main program operations + self.main_program = [] -+ # set if main program needs -ldl -+ self.main_program_needs_ldl = False + # set if default dependencies added to main + self.main_program_default_deps = True + @@ -1058,9 +1062,6 @@ index 0000000000..5dfb3476fa + if not m: + error("'%s' is not recognized main program operation" % (s)) + opr = m.group(1) -+ if(opr == '+' or opr == '^' or opr == '%' or opr == '-'): -+ # Determined the main program needs libdl -+ test_descr.main_program_needs_ldl = True + obj = m.group(2) + if not obj in test_descr.objs: + test_descr.objs.append(obj) @@ -1113,7 +1114,6 @@ index 0000000000..5dfb3476fa + +# Main line parser of description language +def parse_description_string(t, descr_str): -+ + # State used when parsing dependencies + curr_objs = [] + in_dep = False @@ -1242,8 +1242,7 @@ index 0000000000..5dfb3476fa + error("unknown token '%s'" % (value)) + return t + -+ -+ ++# Main routine to process each testcase description +def process_testcase(t): + global objpfx + assert t.test_name @@ -1340,7 +1339,7 @@ index 0000000000..5dfb3476fa + + # Generate link dependencies for all DSOs, done in a DFS fashion. + # Usually this doesn't need to be this complex, just listing the direct -+ # dependencies is enough. However to support creating circular ++ # dependencies is enough. However to support creating circular + # dependency situations, traversing it by DFS and tracking processing + # status is the natural way to do it. + obj_processed = {} @@ -1359,7 +1358,7 @@ index 0000000000..5dfb3476fa + depstr = (" $(objpfx)" + test_subdir + "/" + + test_name + "-" + dep + ".FAKE.so") + # Create empty C file and Makefile fragments for fake -+ # object. This only needs to be done at most once for ++ # object. This only needs to be done at most once for + # an object name. + if not dep in fake_created: + f = open(testpfx + test_name + "-" + dep @@ -1404,8 +1403,6 @@ index 0000000000..5dfb3476fa + for o in test_descr.deps['#']: + depstr += (" $(objpfx)" + test_subdir + "/" + + test_name + "-" + o + ".so") -+ if test_descr.main_program_needs_ldl: -+ depstr += " $(libdl)" + makefile.write("$(objpfx)%s/%s:%s\n" % (test_subdir, test_name, depstr)) + ldflags = "-Wl,--no-as-needed" + if '#' in test_descr.soname_map: @@ -1534,10 +1531,9 @@ index 0000000000..5dfb3476fa + f = open(testpfx + test_name + ".c", "w") + + # if there are some operations in main(), it means we need -ldl -+ if test_descr.main_program_needs_ldl: -+ f.write("#include <dlfcn.h>\n") + f.write("#include <stdio.h>\n") + f.write("#include <stdlib.h>\n") ++ f.write("#include <dlfcn.h>\n") + for s in test_descr.main_program: + if s[0] == '@': + f.write("extern void fn_%s (void);\n" % (s[1:])); @@ -1667,8 +1663,6 @@ index 0000000000..5dfb3476fa + + test_descr.soname_map['#'] + ".so") + cmd += [soname] + cmd += list(main_deps) -+ if test_descr.main_program_needs_ldl: -+ cmd += ["-ldl"] + run_cmd(cmd) + + # Check if we need to enumerate permutations of dependencies @@ -1877,13 +1871,13 @@ new file mode 100644 index 0000000000..7e7d5dc67c --- /dev/null +++ b/support/Depend -@@ -0,0 +1 @@ +@@ -0,0 +1 @@ +elf diff --git a/support/Makefile b/support/Makefile -index a462781718..0da604ade8 100644 +index 7f03950914..984ec02dfe 100644 --- a/support/Makefile +++ b/support/Makefile -@@ -252,10 +252,16 @@ others-noinstall += shell-container echo-container true-container +@@ -257,10 +257,16 @@ others-noinstall += shell-container echo-container true-container others += $(LINKS_DSO_PROGRAM) others-noinstall += $(LINKS_DSO_PROGRAM) @@ -1904,7 +1898,7 @@ diff --git a/support/support_test_main.c b/support/support_test_main.c index 07e3cdd173..66a754b84f 100644 --- a/support/support_test_main.c +++ b/support/support_test_main.c -@@ -228,6 +228,18 @@ run_test_function (int argc, char **argv, const struct test_config *config) +@@ -228,6 +228,18 @@ run_test_function (int argc, char **argv, const struct test_config *config) while (wait_for_debugger) usleep (1000); @@ -1927,7 +1921,7 @@ diff --git a/support/test-driver.c b/support/test-driver.c index b0bea46dee..1552f62c9b 100644 --- a/support/test-driver.c +++ b/support/test-driver.c -@@ -116,7 +116,9 @@ main (int argc, char **argv) +@@ -116,7 +116,9 @@ main (int argc, char **argv) #if defined (TEST_FUNCTION) && defined (TEST_FUNCTON_ARGV) # error TEST_FUNCTION and TEST_FUNCTION_ARGV cannot be defined at the same time #endif @@ -1942,7 +1936,7 @@ diff --git a/support/test-driver.h b/support/test-driver.h index 8d4f38275d..b44c0ff033 100644 --- a/support/test-driver.h +++ b/support/test-driver.h -@@ -36,6 +36,7 @@ struct test_config +@@ -36,6 +36,7 @@ struct test_config int expected_signal; /* If non-zero, expect termination by signal. */ char no_mallopt; /* Boolean flag to disable mallopt. */ char no_setvbuf; /* Boolean flag to disable setvbuf. */ @@ -1955,7 +1949,7 @@ new file mode 100644 index 0000000000..61560d7bfb --- /dev/null +++ b/support/test-run-command.c -@@ -0,0 +1,22 @@ +@@ -0,0 +1,22 @@ +/* Main program for test-run-command support utility. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. diff --git a/v6-2-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Algorithm-changes.patch b/v8-2-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Algorithm-changes.patch index c83a2fb02c17..8dae228961e2 100644 --- a/v6-2-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Algorithm-changes.patch +++ b/v8-2-2-BZ-17645-fix-slow-DSO-sorting-behavior-in-dynamic-loader----Algorithm-changes.patch @@ -1,8 +1,28 @@ +diff --git a/NEWS b/NEWS +index 220d327071..b39b1e5e33 100644 +--- a/NEWS ++++ b/NEWS +@@ -51,6 +51,15 @@ Major new features: + + * The ISO C2X macro _PRINTF_NAN_LEN_MAX has been added to <stdio.h>. + ++* A new DSO sorting algorithm has been added in the dynamic linker that uses ++ topological sorting by depth-first search (DFS), solving performance issues ++ of the existing sorting algorithm when encountering particular circular ++ object dependency cases. ++ ++* A new tunable, glibc.rtld.dynamic_sort, can be used to select between the two ++ DSO sorting algorithms. The default setting of '1' uses the current existing ++ algorithm, while a value of '2' selects the new DFS-based algorithm. ++ + Deprecated and removed features, and other changes affecting compatibility: + + * The r_version update in the debugger interface makes the glibc binary diff --git a/elf/dl-close.c b/elf/dl-close.c -index f39001cab9..a55b3a00fa 100644 +index cfe0f1c0c9..4f5cfcc1c3 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c -@@ -167,8 +167,6 @@ _dl_close_worker (struct link_map *map, bool force) +@@ -167,8 +167,6 @@ _dl_close_worker (struct link_map *map, bool force) bool any_tls = false; const unsigned int nloaded = ns->_ns_nloaded; @@ -11,7 +31,7 @@ index f39001cab9..a55b3a00fa 100644 struct link_map *maps[nloaded]; /* Run over the list and assign indexes to the link maps and enter -@@ -176,24 +174,21 @@ _dl_close_worker (struct link_map *map, bool force) +@@ -176,24 +174,21 @@ _dl_close_worker (struct link_map *map, bool force) int idx = 0; for (struct link_map *l = ns->_ns_loaded; l != NULL; l = l->l_next) { @@ -39,7 +59,7 @@ index f39001cab9..a55b3a00fa 100644 /* Already handled. */ continue; -@@ -204,12 +199,12 @@ _dl_close_worker (struct link_map *map, bool force) +@@ -204,12 +199,12 @@ _dl_close_worker (struct link_map *map, bool force) /* See CONCURRENCY NOTES in cxa_thread_atexit_impl.c to know why acquire is sufficient and correct. */ && atomic_load_acquire (&l->l_tls_dtor_count) == 0 @@ -55,7 +75,7 @@ index f39001cab9..a55b3a00fa 100644 /* Signal the object is still needed. */ l->l_idx = IDX_STILL_USED; -@@ -225,9 +220,9 @@ _dl_close_worker (struct link_map *map, bool force) +@@ -225,9 +220,9 @@ _dl_close_worker (struct link_map *map, bool force) { assert ((*lp)->l_idx >= 0 && (*lp)->l_idx < nloaded); @@ -67,7 +87,7 @@ index f39001cab9..a55b3a00fa 100644 /* If we marked a new object as used, and we've already processed it, then we need to go back and process again from that point forward to -@@ -250,9 +245,9 @@ _dl_close_worker (struct link_map *map, bool force) +@@ -250,9 +245,9 @@ _dl_close_worker (struct link_map *map, bool force) { assert (jmap->l_idx >= 0 && jmap->l_idx < nloaded); @@ -79,7 +99,7 @@ index f39001cab9..a55b3a00fa 100644 if (jmap->l_idx - 1 < done_index) done_index = jmap->l_idx - 1; } -@@ -262,8 +257,7 @@ _dl_close_worker (struct link_map *map, bool force) +@@ -262,8 +257,7 @@ _dl_close_worker (struct link_map *map, bool force) /* Sort the entries. We can skip looking for the binary itself which is at the front of the search list for the main namespace. */ @@ -89,7 +109,7 @@ index f39001cab9..a55b3a00fa 100644 /* Call all termination functions at once. */ #ifdef SHARED -@@ -280,7 +274,7 @@ _dl_close_worker (struct link_map *map, bool force) +@@ -280,7 +274,7 @@ _dl_close_worker (struct link_map *map, bool force) /* All elements must be in the same namespace. */ assert (imap->l_ns == nsid); @@ -98,7 +118,7 @@ index f39001cab9..a55b3a00fa 100644 { assert (imap->l_type == lt_loaded && !imap->l_nodelete_active); -@@ -333,7 +327,7 @@ _dl_close_worker (struct link_map *map, bool force) +@@ -333,7 +327,7 @@ _dl_close_worker (struct link_map *map, bool force) if (i < first_loaded) first_loaded = i; } @@ -107,7 +127,7 @@ index f39001cab9..a55b3a00fa 100644 else if (imap->l_type == lt_loaded) { struct r_scope_elem *new_list = NULL; -@@ -557,7 +551,7 @@ _dl_close_worker (struct link_map *map, bool force) +@@ -560,7 +554,7 @@ _dl_close_worker (struct link_map *map, bool force) for (unsigned int i = first_loaded; i < nloaded; ++i) { struct link_map *imap = maps[i]; @@ -120,7 +140,7 @@ diff --git a/elf/dl-deps.c b/elf/dl-deps.c index 087a49b212..237d9636c5 100644 --- a/elf/dl-deps.c +++ b/elf/dl-deps.c -@@ -613,10 +613,9 @@ Filters not supported with LD_TRACE_PRELINKING")); +@@ -613,10 +613,9 @@ Filters not supported with LD_TRACE_PRELINKING")); /* If libc.so.6 is the main map, it participates in the sort, so that the relocation order is correct regarding libc.so.6. */ @@ -138,7 +158,7 @@ diff --git a/elf/dl-fini.c b/elf/dl-fini.c index 6dbdfe4b3e..c683884c35 100644 --- a/elf/dl-fini.c +++ b/elf/dl-fini.c -@@ -92,8 +92,7 @@ _dl_fini (void) +@@ -92,8 +92,7 @@ _dl_fini (void) /* Now we have to do the sorting. We can skip looking for the binary itself which is at the front of the search list for the main namespace. */ @@ -149,10 +169,10 @@ index 6dbdfe4b3e..c683884c35 100644 /* We do not rely on the linked list of loaded object anymore from this point on. We have our own list here (maps). The diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c -index d21770267a..91c5009ac4 100644 +index d21770267a..a274ed66cc 100644 --- a/elf/dl-sort-maps.c +++ b/elf/dl-sort-maps.c -@@ -16,16 +16,24 @@ +@@ -16,16 +16,24 @@ License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ @@ -161,7 +181,7 @@ index d21770267a..91c5009ac4 100644 +#include <elf/dl-tunables.h> +/* Note: this is the older, "original" sorting algorithm, being used as -+ default up to 2.32. ++ default up to 2.35. -/* Sort array MAPS according to dependencies of the contained objects. - Array USED, if non-NULL, is permutated along MAPS. If FOR_FINI this is @@ -183,7 +203,7 @@ index d21770267a..91c5009ac4 100644 /* A list of one element need not be sorted. */ if (nmaps <= 1) return; -@@ -66,14 +74,6 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used, +@@ -66,14 +74,6 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used, (k - i) * sizeof (maps[0])); maps[k] = thisp; @@ -198,7 +218,7 @@ index d21770267a..91c5009ac4 100644 if (seen[i + 1] > nmaps - i) { ++i; -@@ -120,3 +120,183 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used, +@@ -120,3 +120,183 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps, char *used, next:; } } @@ -357,15 +377,17 @@ index d21770267a..91c5009ac4 100644 +} + +void ++_dl_sort_maps_init (void) ++{ ++ int32_t algorithm = TUNABLE_GET (glibc, rtld, dynamic_sort, int32_t, NULL); ++ GLRO(dl_dso_sort_algo) = algorithm == 1 ? dso_sort_algorithm_original ++ : dso_sort_algorithm_dfs; ++} ++ ++void +_dl_sort_maps (struct link_map **maps, unsigned int nmaps, + unsigned int skip, bool for_fini) +{ -+ /* Index code for sorting algorithm currently in use. */ -+ static int32_t algorithm = 0; -+ if (__glibc_unlikely (algorithm == 0)) -+ algorithm = TUNABLE_GET (glibc, rtld, dynamic_sort, -+ int32_t, NULL); -+ + /* It can be tempting to use a static function pointer to store and call + the current selected sorting algorithm routine, but experimentation + shows that current processors still do not handle indirect branches @@ -373,20 +395,45 @@ index d21770267a..91c5009ac4 100644 + PTR_MANGLE/DEMANGLE, further impairing performance of small, common + input cases. A simple if-case with direct function calls appears to + be the fastest. */ -+ if (__glibc_likely (algorithm == 1)) ++ if (__glibc_likely (GLRO(dl_dso_sort_algo) == dso_sort_algorithm_original)) + _dl_sort_maps_original (maps, nmaps, skip, for_fini); -+ else if (algorithm == 2) -+ _dl_sort_maps_dfs (maps, nmaps, skip, for_fini); + else -+ __builtin_unreachable (); ++ _dl_sort_maps_dfs (maps, nmaps, skip, for_fini); +} + +#endif /* HAVE_TUNABLES. */ +diff --git a/elf/dl-support.c b/elf/dl-support.c +index d99c1f1d62..98d5d8db5c 100644 +--- a/elf/dl-support.c ++++ b/elf/dl-support.c +@@ -166,6 +166,8 @@ size_t _dl_phnum; + uint64_t _dl_hwcap; + uint64_t _dl_hwcap2; + ++enum dso_sort_algorithm _dl_dso_sort_algo; ++ + /* The value of the FPU control word the kernel will preset in hardware. */ + fpu_control_t _dl_fpu_control = _FPU_DEFAULT; + +diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c +index 2c684c2db2..4dc366eea4 100644 +--- a/elf/dl-sysdep.c ++++ b/elf/dl-sysdep.c +@@ -231,6 +231,9 @@ _dl_sysdep_start (void **start_argptr, + + __tunables_init (_environ); + ++ /* Initialize DSO sorting algorithm after tunables. */ ++ _dl_sort_maps_init (); ++ + #ifdef DL_SYSDEP_INIT + DL_SYSDEP_INIT; + #endif diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list index 8ddd4a2314..46ffb23784 100644 --- a/elf/dl-tunables.list +++ b/elf/dl-tunables.list -@@ -156,4 +156,13 @@ glibc { +@@ -156,4 +156,13 @@ glibc { security_level: SXID_IGNORE } } @@ -400,11 +447,22 @@ index 8ddd4a2314..46ffb23784 100644 + } + } } +diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def +index 873ddf55d9..5f7f18ef27 100644 +--- a/elf/dso-sort-tests-1.def ++++ b/elf/dso-sort-tests-1.def +@@ -62,5 +62,5 @@ output: b>a>{}<a<b + # The below expected outputs are what the two algorithms currently produce + # respectively, for regression testing purposes. + tst-bz15311: {+a;+e;+f;+g;+d;%d;-d;-g;-f;-e;-a};a->b->c->d;d=>[ba];c=>a;b=>e=>a;c=>f=>b;d=>g=>c +-xfail_output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<c<d<g<f<b<e];} ++output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<c<d<g<f<b<e];} + output(glibc.rtld.dynamic_sort=2): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<g<f<a<b<c<d<e];} diff --git a/elf/rtld.c b/elf/rtld.c -index d733359eaf..abdc13c13a 100644 +index b8ba2d8836..be2d5d8e74 100644 --- a/elf/rtld.c +++ b/elf/rtld.c -@@ -1389,6 +1389,9 @@ dl_main (const ElfW(Phdr) *phdr, +@@ -1391,6 +1391,9 @@ dl_main (const ElfW(Phdr) *phdr, main_map->l_name = (char *) ""; *user_entry = main_map->l_entry; @@ -418,7 +476,7 @@ diff --git a/elf/tst-rtld-list-tunables.exp b/elf/tst-rtld-list-tunables.exp index 9f66c52885..9bf572715f 100644 --- a/elf/tst-rtld-list-tunables.exp +++ b/elf/tst-rtld-list-tunables.exp -@@ -10,5 +10,6 @@ glibc.malloc.tcache_max: 0x0 (min: 0x0, max: 0x[f]+) +@@ -10,5 +10,6 @@ glibc.malloc.tcache_max: 0x0 (min: 0x0, max: 0x[f]+) glibc.malloc.tcache_unsorted_limit: 0x0 (min: 0x0, max: 0x[f]+) glibc.malloc.top_pad: 0x0 (min: 0x0, max: 0x[f]+) glibc.malloc.trim_threshold: 0x0 (min: 0x0, max: 0x[f]+) @@ -426,10 +484,10 @@ index 9f66c52885..9bf572715f 100644 glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10) glibc.rtld.optional_static_tls: 0x200 (min: 0x0, max: 0x[f]+) diff --git a/include/link.h b/include/link.h -index 4af16cb596..50f45db243 100644 +index 484ee6cb1b..c1c382ccfa 100644 --- a/include/link.h +++ b/include/link.h -@@ -181,6 +181,11 @@ struct link_map +@@ -181,6 +181,11 @@ struct link_map unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */ unsigned int l_global:1; /* Nonzero if object in _dl_global_scope. */ unsigned int l_reserved:2; /* Reserved for internal use. */ @@ -441,11 +499,56 @@ index 4af16cb596..50f45db243 100644 unsigned int l_phdr_allocated:1; /* Nonzero if the data structure pointed to by `l_phdr' is allocated. */ unsigned int l_soname_added:1; /* Nonzero if the SONAME is for sure in +diff --git a/manual/tunables.texi b/manual/tunables.texi +index 658547c613..10f4d75993 100644 +--- a/manual/tunables.texi ++++ b/manual/tunables.texi +@@ -309,6 +309,17 @@ changed once allocated at process startup. The default allocation of + optional static TLS is 512 bytes and is allocated in every thread. + @end deftp + ++@deftp Tunable glibc.rtld.dynamic_sort ++Sets the algorithm to use for DSO sorting, valid values are @samp{1} and ++@samp{2}. For value of @samp{1}, an older O(n^3) algorithm is used, which is ++long time tested, but may have performance issues when dependencies between ++shared objects contain cycles due to circular dependencies. When set to the ++value of @samp{2}, a different algorithm is used, which implements a ++topological sort through depth-first search, and does not exhibit the ++performance issues of @samp{1}. ++ ++The default value of this tunable is @samp{1}. ++@end deftp + + @node Elision Tunables + @section Elision Tunables diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h -index 9c15259236..ad48a0d7da 100644 +index 0410f777a6..65a6a51633 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h -@@ -1084,7 +1084,7 @@ extern void _dl_fini (void) attribute_hidden; +@@ -245,6 +245,13 @@ enum allowmask + }; + + ++/* DSO sort algorithm to use (check dl-sort-maps.c). */ ++enum dso_sort_algorithm ++ { ++ dso_sort_algorithm_original, ++ dso_sort_algorithm_dfs ++ }; ++ + struct audit_ifaces + { + void (*activity) (uintptr_t *, unsigned int); +@@ -678,6 +685,8 @@ struct rtld_global_ro + platforms. */ + EXTERN uint64_t _dl_hwcap2; + ++ EXTERN enum dso_sort_algorithm _dl_dso_sort_algo; ++ + #ifdef SHARED + /* We add a function table to _rtld_global which is then used to + call the function instead of going through the PLT. The result +@@ -1104,7 +1113,7 @@ extern void _dl_fini (void) attribute_hidden; /* Sort array MAPS according to dependencies of the contained objects. */ extern void _dl_sort_maps (struct link_map **maps, unsigned int nmaps, @@ -454,3 +557,13 @@ index 9c15259236..ad48a0d7da 100644 /* The dynamic linker calls this function before and having changing any shared object mappings. The `r_state' member of `struct r_debug' +@@ -1235,6 +1244,9 @@ extern struct link_map * _dl_get_dl_main_map (void) + # endif + #endif + ++/* Initialize the DSO sort algorithm to use. */ ++extern void _dl_sort_maps_init (void) attribute_hidden; ++ + /* Initialization of libpthread for statically linked applications. + If libpthread is not linked in, this is an empty function. */ + void __pthread_initialize_minimal (void) weak_function; |