From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-oi1-x231.google.com (mail-oi1-x231.google.com [IPv6:2607:f8b0:4864:20::231]) by sourceware.org (Postfix) with ESMTPS id 804BA3858D32 for ; Mon, 13 Mar 2023 19:06:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 804BA3858D32 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org Received: by mail-oi1-x231.google.com with SMTP id bk32so10170340oib.10 for ; Mon, 13 Mar 2023 12:06:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1678734394; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=/X57vLTMaHS0ZIkAxnE3pT1K59LDR+3tRRujI/VodFI=; b=NCySpoBI8aFlpBBuYhFL7ksk8tA8Z7arbOJryw2PFf8WE/bqtMgZU/AbRStOSpNcvX bfeATQiXkwjmRfMCmep7GcZPIm7i5iRHXPhC5C2aZAmxlaesONP/hxZvGrfGXjg98pzq rcXQf/75zyJirHIbcuysNgNNCRYPkIZMr1ywn3KUvtKxN9t0yvX4UwxzxSd4vLI4tS6F 7OqyagKWo3eaMgz+p7tgyydSvswUe8g3SvPObGcPFMpj1WwEy09kGCToeu/+DrneVAuA dUR09HzCArNjUaJtVc8WK4H17tzcs5inr5FXvPfxPkfBeXrQLVa5PfCLf6rG29cnlzRj pGGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1678734394; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/X57vLTMaHS0ZIkAxnE3pT1K59LDR+3tRRujI/VodFI=; b=zXuhfrJ4T7zBpmnnlkbGDWpNRlBYdcVVUpYOhS1V5HL7pFUWfoPq4c4TZAS1n2QDun kCreZliY3PRJfHW5IoM/sxdxDifuyfaVQr3igaaDTqUhsXdglI4mEGdlqZruZYzfnCV1 juXXQwAMaqK5lBYz0uoHN1VKjKdcyKamND05Jd8Ic0iISsEMJJUhX+FjUnaSnIhxbQiD ttO0wiQUnwuSo7QK1kC+u6F6OBx0waixeUcAAK4ZUOVko2VkozcZc5ifOJGQIdrbAQx2 bGAzGWAPqP9jaJb6LY6BH5/SntpZPtV2aukwopIs2TNZCOw85j74U1X1NtyRNcqZGund VF+w== X-Gm-Message-State: AO0yUKXYXAGOTGdLTeQg2OoE3OSJG4/1YT1V7A3b1UGh80gG8m2mCK26 7hEclhuL1Fo+bESrfHie1A/eENQ896swigN7Aafp2A== X-Google-Smtp-Source: AK7set/4duSufNv2r7CBxhp7fEwEhXsXDbpXIRcXikzrg4w0QJmvxOB8yX5P4ZbQifDs3kpiyAe38Q== X-Received: by 2002:aca:1302:0:b0:37a:fa7d:972e with SMTP id e2-20020aca1302000000b0037afa7d972emr17927503oii.41.1678734393748; Mon, 13 Mar 2023 12:06:33 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c0:544b:9bad:e673:fbfa:30eb]) by smtp.gmail.com with ESMTPSA id d21-20020a056830045500b0068bb73bd95esm297122otc.58.2023.03.13.12.06.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Mar 2023 12:06:33 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org, Siddhesh Poyarekar , Florian Weimer Subject: [PATCH 1/2] elf: Remove glibc.rtld.dynamic_sort tunable Date: Mon, 13 Mar 2023 16:06:26 -0300 Message-Id: <20230313190627.2000578-2-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230313190627.2000578-1-adhemerval.zanella@linaro.org> References: <20230313190627.2000578-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-9.9 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SCC_10_SHORT_WORD_LINES,SCC_20_SHORT_WORD_LINES,SCC_35_SHORT_WORD_LINES,SCC_5_SHORT_WORD_LINES,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: And make the DFS algorithm (added on 2.35) the de-facto implementation. --- elf/dl-sort-maps.c | 139 +--------------------------- elf/dl-tunables.list | 9 -- elf/dso-sort-tests-1.def | 15 +-- elf/dso-sort-tests-2.def | 10 +- elf/tst-rtld-list-tunables.exp | 1 - manual/tunables.texi | 13 --- sysdeps/mach/hurd/dl-sysdep.c | 3 - sysdeps/unix/sysv/linux/dl-sysdep.c | 3 - 8 files changed, 8 insertions(+), 185 deletions(-) diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c index 325e96388e..72ca5cec33 100644 --- a/elf/dl-sort-maps.c +++ b/elf/dl-sort-maps.c @@ -20,112 +20,6 @@ #include #include =20 -/* Note: this is the older, "original" sorting algorithm, being used as - default up to 2.35. - - Sort array MAPS according to dependencies of the contained objects. - If FOR_FINI is true, this is called for finishing an object. */ -static void -_dl_sort_maps_original (struct link_map **maps, unsigned int nmaps, - bool force_first, bool for_fini) -{ - /* Allows caller to do the common optimization of skipping the first map, - usually the main binary. */ - maps +=3D force_first; - nmaps -=3D force_first; - - /* A list of one element need not be sorted. */ - if (nmaps <=3D 1) - return; - - unsigned int i =3D 0; - uint16_t seen[nmaps]; - memset (seen, 0, nmaps * sizeof (seen[0])); - while (1) - { - /* Keep track of which object we looked at this round. */ - ++seen[i]; - struct link_map *thisp =3D maps[i]; - - if (__glibc_unlikely (for_fini)) - { - /* Do not handle ld.so in secondary namespaces and objects which - are not removed. */ - if (thisp !=3D thisp->l_real || thisp->l_idx =3D=3D -1) - goto skip; - } - - /* Find the last object in the list for which the current one is - a dependency and move the current object behind the object - with the dependency. */ - unsigned int k =3D nmaps - 1; - while (k > i) - { - struct link_map **runp =3D maps[k]->l_initfini; - if (runp !=3D NULL) - /* Look through the dependencies of the object. */ - while (*runp !=3D NULL) - if (__glibc_unlikely (*runp++ =3D=3D thisp)) - { - move: - /* Move the current object to the back past the last - object with it as the dependency. */ - memmove (&maps[i], &maps[i + 1], - (k - i) * sizeof (maps[0])); - maps[k] =3D thisp; - - if (seen[i + 1] > nmaps - i) - { - ++i; - goto next_clear; - } - - uint16_t this_seen =3D seen[i]; - memmove (&seen[i], &seen[i + 1], (k - i) * sizeof (seen[0])); - seen[k] =3D this_seen; - - goto next; - } - - if (__glibc_unlikely (for_fini && maps[k]->l_reldeps !=3D NULL)) - { - unsigned int m =3D maps[k]->l_reldeps->act; - struct link_map **relmaps =3D &maps[k]->l_reldeps->list[0]; - - /* Look through the relocation dependencies of the object. */ - while (m-- > 0) - if (__glibc_unlikely (relmaps[m] =3D=3D thisp)) - { - /* If a cycle exists with a link time dependency, - preserve the latter. */ - struct link_map **runp =3D thisp->l_initfini; - if (runp !=3D NULL) - while (*runp !=3D NULL) - if (__glibc_unlikely (*runp++ =3D=3D maps[k])) - goto ignore; - goto move; - } - ignore:; - } - - --k; - } - - skip: - if (++i =3D=3D nmaps) - break; - next_clear: - memset (&seen[i], 0, (nmaps - i) * sizeof (seen[0])); - - next:; - } -} - -#if !HAVE_TUNABLES -/* In this case, just default to the original algorithm. */ -strong_alias (_dl_sort_maps_original, _dl_sort_maps); -#else - /* We use a recursive function due to its better clarity and ease of implementation, as well as faster execution speed. We already use alloca() for list allocation during the breadth-first search of @@ -180,9 +74,9 @@ dfs_traversal (struct link_map ***rpo, struct link_map *= map, /* Topologically sort array MAPS according to dependencies of the contained objects. */ =20 -static void -_dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps, - bool force_first, bool for_fini) +void +_dl_sort_maps (struct link_map **maps, unsigned int nmaps, bool force_firs= t, + bool for_fini) { struct link_map *first_map =3D maps[0]; for (int i =3D nmaps - 1; i >=3D 0; i--) @@ -289,30 +183,3 @@ _dl_sort_maps_dfs (struct link_map **maps, unsigned in= t nmaps, maps[0] =3D first_map; } } - -void -_dl_sort_maps_init (void) -{ - int32_t algorithm =3D TUNABLE_GET (glibc, rtld, dynamic_sort, int32_t, N= ULL); - GLRO(dl_dso_sort_algo) =3D algorithm =3D=3D 1 ? dso_sort_algorithm_origi= nal - : dso_sort_algorithm_dfs; -} - -void -_dl_sort_maps (struct link_map **maps, unsigned int nmaps, - bool force_first, bool for_fini) -{ - /* 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 - that efficiently, plus a static function pointer will involve - 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 (GLRO(dl_dso_sort_algo) =3D=3D dso_sort_algorithm_ori= ginal)) - _dl_sort_maps_original (maps, nmaps, force_first, for_fini); - else - _dl_sort_maps_dfs (maps, nmaps, force_first, for_fini); -} - -#endif /* HAVE_TUNABLES. */ diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list index 695ba7192e..b9fa831000 100644 --- a/elf/dl-tunables.list +++ b/elf/dl-tunables.list @@ -162,15 +162,6 @@ glibc { } } =20 - rtld { - dynamic_sort { - type: INT_32 - minval: 1 - maxval: 2 - default: 2 - } - } - gmon { minarcs { type: INT_32 diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def index 4bf9052db1..f5afd003d8 100644 --- a/elf/dso-sort-tests-1.def +++ b/elf/dso-sort-tests-1.def @@ -2,10 +2,6 @@ # This file is to be processed by ../scripts/dso-ordering-test.py, see usa= ge # in elf/Makefile for how it is executed. =20 -# We test both dynamic loader sorting algorithms -tunable_option: glibc.rtld.dynamic_sort=3D1 -tunable_option: glibc.rtld.dynamic_sort=3D2 - # Sequence of single dependencies with no cycles. tst-dso-ordering1: a->b->c output: c>b>a>{}a>{}b->c->d order). -# The older dynamic_sort=3D1 algorithm does not achieve this, while the DF= S-based -# dynamic_sort=3D2 algorithm does, although it is still arguable whether g= oing -# beyond spec to do this is the right thing to do. +# The DFS-based sorting algorithm does it, although it is still arguable w= hether +# going beyond spec to do this is the right thing to do. # 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=3D>[ba];c=3D>= a;b=3D>e=3D>a;c=3D>f=3D>b;d=3D>g=3D>c -output(glibc.rtld.dynamic_sort=3D1): {+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[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[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[a1;a->a2;a2->a;b->b1;c->a1;c=3D>a1 -output(glibc.rtld.dynamic_sort=3D1): {+a[a2>a1>a>];+b[b1>b>];-b[];%c(a1());}a1>a>];+b[b1>b>];-b[];%c(a1());}a1>a>];+b[b1>b>];-b[];%c(a1());}A101 @@ -610,5 +603,4 @@ M30X22 M30X23 M30X24 M30X25 -xfail_output(glibc.rtld.dynamic_sort=3D1): M30X19>M30X15>M30X16>M30X11>M30= X12>M30X17>M30X13>M30X14>M29X20>M30X23>M30X24>M30X20>M30X18>M29X15>M29X12>M= 30X22>M30X21>M29X22>M30X25>M29X19>M29X23>M29X16>M29X24>M29X13>M29X17>M29X18= >M28X19>M29X21>M29X25>M29X14>M28X20>M28X15>M28X16>M28X21>M27X18>M29X11>M28X= 17>M28X11>M28X22>M27X14>M28X18>M27X15>M28X13>M27X11>M28X23>M27X25>M28X14>M2= 8X25>M27X23>M27X22>M28X24>M27X21>M27X13>M27X19>M27X17>M26X11>M26X23>M26X21>= M26X22>M26X20>M26X16>M25X21>M17X22>M15X15>M20X14>M20X16>M18X18>M28X12>M27X2= 4>M25X17>M27X20>M26X18>M26X17>M27X16>M26X19>M25X18>M26X24>M25X20>M24X17>M23= X18>M25X13>M26X13>M17X23>M16X16>M26X12>M25X12>M26X15>M24X19>M25X23>M25X24>M= 25X25>M24X20>M25X19>M24X21>M23X17>M22X21>M24X14>M23X22>M24X24>M22X20>M24X13= >M25X11>M24X12>M25X15>M23X15>M25X16>M24X22>M23X13>M24X18>M23X14>M22X22>M21X= 20>M24X25>M23X16>M22X25>M21X19>M22X14>M23X11>M22X15>M21X18>M22X19>M21X17>M2= 0X17>M19X17>M21X24>M21X12>M20X22>M19X16>M18X25>M19X21>M19X20>M18X24>M20X12>= M19X11>M23X20>M22X24>M22X16>M21X21>M25X14>M23X19>M23X24>M20X24>M19X12>M18X1= 5>M17X14>M16X18>M14X25>M16X22>M16X20>M17X17>M22X12>M21X11>M20X15>M18X22>M19= X24>M19X18>M18X21>M17X16>M17X18>M16X21>M15X20>M19X22>M18X20>M18X11>M17X19>M= 16X17>M15X21>M16X14>M16X13>M15X22>M14X20>M17X25>M16X19>M14X21>M13X24>M12X12= >M16X24>M15X23>M14X16>M16X15>M15X25>M15X11>M15X12>M14X15>M13X14>M14X22>M13X= 20>M12X13>M11X11>M22X23>M21X15>M21X16>M20X21>M20X20>M18X17>M19X25>M18X23>M2= 1X13>M15X17>M15X18>M18X19>M17X24>M16X12>M17X13>M20X25>M19X23>M15X19>M14X13>= M13X18>M15X13>M17X12>M16X11>M18X13>M18X12>M14X11>M14X24>M13X19>M15X14>M17X2= 0>M20X11>M20X13>M21X14>M15X24>M14X12>M13X22>M14X23>M13X23>M14X19>M17X15>M16= X25>M17X11>M18X14>M19X19>M21X25>M13X12>M13X11>M14X18>M13X13>M12X11>M15X16>M= 14X14>M27X12>M17X21>M20X23>M22X13>M21X22>M24X16>M24X15>M26X25>M23X25>M26X14= >M23X12>M22X18>M24X11>M16X23>M19X14>M19X13>M21X23>M22X17>M23X23>M23X21>M25X= 22>M18X16>M19X15>M20X18>M20X19>M22X11>M24X23>C156>C118>C143>C137>C147>C106>= C168>C113>C163>C155>C105>C146>C187>A150>C139>C180>C164>C193>C157>A191>C158>= B188>A159>C184>C121>C154>B171>A105>C131>C104>B104>C161>C111>B145>C160>B155>= A163>C112>C142>B148>C133>B198>A198>A115>C114>B157>A156>C175>B144>A120>C173>= B184>A174>C126>B107>A139>C194>B194>A194>C116>B116>C166>B160>B110>A110>C128>= B128>A128>C179>B162>A154>C186>B187>A179>C124>B181>A101>C153>B158>A136>C135>= C176>A192>B133>A133>C177>B177>A177>C185>C103>B141>A141>C183>A162>C192>C129>= B179>C144>B124>B183>C127>B127>A127>B108>A112>B153>A153>C167>B167>A186>A122>= C162>A144>B149>C174>B131>A185>C141>B106>A126>A167>C140>B122>A170>C198>B143>= C117>C123>B123>A147>A106>C200>B169>C191>B175>A123>B118>A182>C132>B151>A145>= A104>A109>C159>C150>B119>A119>A178>B164>B114>A164>C181>A102>C122>B134>A157>= A116>C195>B191>B111>C172>B172>A118>B129>A129>C149>A107>C170>B197>A197>A173>= B168>A132>C107>B165>A160>A131>C188>A168>B109>C178>A189>A148>C119>C190>C120>= B166>B176>C108>B135>B139>A103>B178>A169>B132>C125>C138>B163>A111>B170>C110>= A165>C151>C169>C199>A138>C182>A135>B101>B142>C101>C148>B193>B152>A158>A199>= C136>B137>A161>B120>A108>A149>A125>B113>A184>C171>A134>A175>A124>B150>B161>= B102>A146>A187>C130>B192>B200>A200>A142>A183>C102>B105>B156>A176>C165>B147>= A137>A196>B190>A190>B125>C134>C189>B126>B186>A166>B136>B195>A195>B154>B138>= B112>B173>A117>B159>B182>A181>A140>C145>B117>A152>A193>C197>B130>A172>A113>= A151>B115>A143>B140>B185>B103>A121>A180>A130>A171>B199>C196>B146>B180>C115>= B174>B121>A188>B196>B189>C152>C109>A155>A114>M14X17>M13X15>M13X16>M13X17>M1= 2X17>M12X21>M12X25>M12X14>M13X25>M12X15>M13X21>M12X16>M12X18>M12X19>M12X20>= M12X22>M12X23>M12X24>M11X25>M11X24>M11X23>M11X22>M11X21>M11X20>M11X19>M11X1= 8>M11X17>M11X16>M11X15>M11X14>M11X13>M11X12>{}M30X15>M30X16>M30X11>M30X12>M3= 0X17>M30X13>M30X14>M29X20>M30X23>M30X24>M30X20>M30X18>M29X15>M29X12>M30X22>= M30X21>M29X22>M30X25>M29X19>M29X23>M29X16>M29X24>M29X13>M29X17>M29X18>M28X1= 9>M29X21>M29X25>M29X14>M28X20>M28X15>M28X16>M28X21>M27X18>M29X11>M28X17>M28= X11>M28X22>M28X24>M28X23>M27X21>M28X13>M27X20>M27X19>M26X14>M27X25>M28X18>M= 27X11>M28X25>M27X24>M26X24>M27X15>M27X14>M27X13>M26X23>M27X17>M26X22>M25X13= >M28X14>M27X16>M26X19>M26X18>M27X23>M27X22>M26X17>M25X18>M26X21>M25X17>M26X= 20>M26X15>M26X13>M25X19>M24X14>M25X23>M26X11>M26X25>M25X16>M25X15>M24X22>M2= 5X21>M25X20>M24X21>M25X25>M25X24>M24X20>M23X13>M22X15>M25X14>M24X19>M23X17>= M24X25>M23X24>M24X13>M23X15>M24X18>M23X14>M22X11>M24X15>M23X22>M24X11>M23X1= 9>M22X21>M24X24>M23X21>M22X20>M23X25>M22X19>M21X24>M20X23>M22X22>M25X11>M23= X16>M22X18>M23X20>M22X17>M21X21>M21X20>M20X24>M22X14>M22X13>M21X11>M21X17>M= 22X23>M21X16>M20X25>M19X23>M18X16>M21X22>M20X20>M20X19>M21X13>M20X18>M19X13= >M21X18>M20X21>M19X24>M18X12>M20X14>M20X13>M22X25>M20X12>M20X15>M19X14>M18X= 22>M19X18>M20X17>M19X17>M19X16>M18X21>M17X20>M19X19>M18X13>M17X11>M18X17>M1= 9X25>M18X15>M17X25>M18X19>M17X24>M16X19>M15X17>M17X21>M16X24>M18X23>M17X16>= M16X25>M19X15>M18X25>M17X23>M16X23>M15X23>M18X14>M17X14>M16X14>M17X18>M16X1= 3>M17X22>M16X12>M15X22>M14X16>M17X12>M16X22>M15X12>M16X11>M15X11>M16X15>M15= X25>M14X15>M13X14>M15X18>M16X21>M15X16>M14X21>M15X14>M16X20>M15X13>M14X22>M= 15X20>M14X20>M13X20>M14X11>M15X19>M14X24>M13X19>M14X13>M13X18>M12X13>M15X24= >M14X23>M13X12>M14X12>M13X11>M12X11>M11X11>M21X12>M20X11>M19X11>M18X11>M17X= 15>M16X18>M14X25>M14X19>M13X24>M13X23>M13X22>M12X12>M22X12>M21X15>M19X22>M1= 8X20>M16X17>M14X14>M24X12>M23X23>M22X16>M21X14>M20X22>M18X24>M16X16>M26X12>= M24X16>M23X11>M21X23>M19X20>M17X17>M27X12>M26X16>M25X22>M24X17>M23X18>M21X2= 5>M19X12>M17X19>M15X21>M14X18>M13X13>M23X12>M21X19>M19X21>M17X13>M15X15>M25= X12>M24X23>M22X24>M20X16>M18X18>M28X12>A150>C158>B112>A112>C167>B146>A146>C= 180>B180>A180>C143>B143>A115>C126>B126>A126>C190>B190>A190>C138>B138>A138>C= 174>B174>A102>C122>B122>A122>C162>B162>A162>C142>B142>A142>C102>B102>A174>C= 176>B176>A176>C115>B115>A143>C172>B172>A172>C187>B187>A187>C130>B130>A130>C= 118>B118>A118>C184>B184>A184>C171>B171>A171>C168>B182>A182>C182>B168>A168>C= 109>B109>A109>C159>B159>A159>C134>B134>A134>C146>B167>A167>C140>B140>A140>C= 163>B163>A163>C112>B158>A158>C164>B164>A164>C131>B131>A131>C188>B188>A188>C= 199>B199>A199>C114>B114>A114>C106>B106>A106>C200>B200>A200>C183>B183>A183>C= 152>B152>A152>C147>B147>A147>C150>B150>A198>C144>B144>A144>C191>B191>A191>C= 108>B108>A108>C139>B139>A139>C194>B194>A194>C166>B166>A166>C120>B120>A120>C= 123>B123>A123>C132>B132>A132>C107>B107>A107>C170>B170>A170>C198>B198>A156>C= 125>B125>A125>C121>B121>A121>C193>B193>A193>C197>B197>A197>C175>B175>A175>C= 196>B196>A196>C105>B105>A105>C181>B181>A181>C113>B113>A113>C137>B137>A137>C= 155>B155>A155>C156>B156>A110>C128>B128>A128>C179>B179>A179>C124>B124>A124>C= 151>B151>A151>C178>B178>A178>C104>B104>A104>C111>B111>A111>C148>B148>A148>C= 169>B169>A169>C129>B129>A129>C149>B149>A149>C189>B189>A189>C119>B119>A119>C= 154>B154>A154>C136>B136>A136>C135>B135>A135>C116>B116>A116>C145>B145>A145>C= 161>B161>A161>C173>B173>A173>C157>B157>A157>C195>B195>A195>C186>B186>A186>C= 160>B160>A160>C153>B153>A153>C117>B117>A117>C165>B165>A165>C101>B101>A101>C= 103>B103>A103>C192>B192>A192>C177>B177>A177>C185>B185>A185>C141>B141>A141>C= 133>B133>A133>C127>B127>A127>C110>B110>M14X17>M13X15>M13X16>M13X17>M12X17>M= 12X21>M12X25>M12X14>M13X25>M12X15>M13X21>M12X16>M12X18>M12X19>M12X20>M12X22= >M12X23>M12X24>M11X25>M11X24>M11X23>M11X22>M11X21>M11X20>M11X19>M11X18>M11X= 17>M11X16>M11X15>M11X14>M11X13>M11X12>{}M30X15>M30X16>M30X11>M30X12>M30X17>M30X13>M30X14>M29X20>M30= X23>M30X24>M30X20>M30X18>M29X15>M29X12>M30X22>M30X21>M29X22>M30X25>M29X19>M= 29X23>M29X16>M29X24>M29X13>M29X17>M29X18>M28X19>M29X21>M29X25>M29X14>M28X20= >M28X15>M28X16>M28X21>M27X18>M29X11>M28X17>M28X11>M28X22>M28X24>M28X23>M27X= 21>M28X13>M27X20>M27X19>M26X14>M27X25>M28X18>M27X11>M28X25>M27X24>M26X24>M2= 7X15>M27X14>M27X13>M26X23>M27X17>M26X22>M25X13>M28X14>M27X16>M26X19>M26X18>= M27X23>M27X22>M26X17>M25X18>M26X21>M25X17>M26X20>M26X15>M26X13>M25X19>M24X1= 4>M25X23>M26X11>M26X25>M25X16>M25X15>M24X22>M25X21>M25X20>M24X21>M25X25>M25= X24>M24X20>M23X13>M22X15>M25X14>M24X19>M23X17>M24X25>M23X24>M24X13>M23X15>M= 24X18>M23X14>M22X11>M24X15>M23X22>M24X11>M23X19>M22X21>M24X24>M23X21>M22X20= >M23X25>M22X19>M21X24>M20X23>M22X22>M25X11>M23X16>M22X18>M23X20>M22X17>M21X= 21>M21X20>M20X24>M22X14>M22X13>M21X11>M21X17>M22X23>M21X16>M20X25>M19X23>M1= 8X16>M21X22>M20X20>M20X19>M21X13>M20X18>M19X13>M21X18>M20X21>M19X24>M18X12>= M20X14>M20X13>M22X25>M20X12>M20X15>M19X14>M18X22>M19X18>M20X17>M19X17>M19X1= 6>M18X21>M17X20>M19X19>M18X13>M17X11>M18X17>M19X25>M18X15>M17X25>M18X19>M17= X24>M16X19>M15X17>M17X21>M16X24>M18X23>M17X16>M16X25>M19X15>M18X25>M17X23>M= 16X23>M15X23>M18X14>M17X14>M16X14>M17X18>M16X13>M17X22>M16X12>M15X22>M14X16= >M17X12>M16X22>M15X12>M16X11>M15X11>M16X15>M15X25>M14X15>M13X14>M15X18>M16X= 21>M15X16>M14X21>M15X14>M16X20>M15X13>M14X22>M15X20>M14X20>M13X20>M14X11>M1= 5X19>M14X24>M13X19>M14X13>M13X18>M12X13>M15X24>M14X23>M13X12>M14X12>M13X11>= M12X11>M11X11>M21X12>M20X11>M19X11>M18X11>M17X15>M16X18>M14X25>M14X19>M13X2= 4>M13X23>M13X22>M12X12>M22X12>M21X15>M19X22>M18X20>M16X17>M14X14>M24X12>M23= X23>M22X16>M21X14>M20X22>M18X24>M16X16>M26X12>M24X16>M23X11>M21X23>M19X20>M= 17X17>M27X12>M26X16>M25X22>M24X17>M23X18>M21X25>M19X12>M17X19>M15X21>M14X18= >M13X13>M23X12>M21X19>M19X21>M17X13>M15X15>M25X12>M24X23>M22X24>M20X16>M18X= 18>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>M1= 2X15>M13X21>M12X16>M12X18>M12X19>M12X20>M12X22>M12X23>M12X24>M11X25>M11X24>= M11X23>M11X22>M11X21>M11X20>M11X19>M11X18>M11X17>M11X16>M11X15>M11X14>M11X1= 3>M11X12>{}