From patchwork Sat Aug 20 02:01:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Hatle X-Patchwork-Id: 14793 Received: (qmail 112016 invoked by alias); 20 Aug 2016 02:01:54 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 111953 invoked by uid 89); 20 Aug 2016 02:01:53 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_SOFTFAIL autolearn=no version=3.3.2 spammy=Wind, substantial, H*RU:14.3.248.2, H*r:14.3.248 X-HELO: mail5.wrs.com To: GNU C Library CC: Alexander Miller From: Mark Hatle Subject: _dl_build_local_scope - BZ #20488 Message-ID: <19bf0fab-3aa7-aa98-040f-e8fbad3e8c17@windriver.com> Date: Fri, 19 Aug 2016 21:01:33 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 MIME-Version: 1.0 This is somewhat a followup to Alexander Miller's email for a few months back: https://sourceware.org/ml/libc-alpha/2016-05/msg00034.html Independently we identify a similar problem with the emulated rtld in the cross prelinker. The ELF spec indicates that the symbol resolution is breadth first, not depth first. Without doing this a failure can occur. The current prelinker (git://git.yoctoproject.org/prelink-cross) has a specific test case for the ordering issue. See 'order' test case. The patch below fixes the issue in glibc and was developed independently. My employer (Wind River) has a copyright assigned with the FSF if the change is substantial enough to require one. The patch is attached to BZ 20488, as well as included below. From 6e4ec5a3c5fe63b6458036f18d43124de4a7e724 Mon Sep 17 00:00:00 2001 From: Mark Hatle Date: Thu, 18 Aug 2016 14:07:58 -0500 Subject: [PATCH] elf/dl-deps.c: Make _dl_build_local_scope breadth first According to the ELF specification: When resolving symbolic references, the dynamic linker examines the symbol tables with a breadth-first search. This function was using a depth first search. By doing so the conflict resolution reported to the prelinker (when LD_TRACE_PRELINKING=1 is set) was incorrect. This caused problems when their were various circular dependencies between libraries. The problem usually manifested itself by the wrong IFUNC being executed. Signed-off-by: Mark Hatle --- elf/dl-deps.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/elf/dl-deps.c b/elf/dl-deps.c index 6a82987..fc37c87 100644 --- a/elf/dl-deps.c +++ b/elf/dl-deps.c @@ -73,13 +73,19 @@ _dl_build_local_scope (struct link_map **list, struct link_map *map) { struct link_map **p = list; struct link_map **q; + struct link_map **r; *p++ = map; map->l_reserved = 1; - if (map->l_initfini) - for (q = map->l_initfini + 1; *q; ++q) - if (! (*q)->l_reserved) - p += _dl_build_local_scope (p, *q); + + for (r = list; r < p; ++r) + if ((*r)->l_initfini) + for (q = (*r)->l_initfini + 1; *q; ++q) + if (! (*q)->l_reserved) + { + *p++ = *q; + (*q)->l_reserved = 1; + } return p - list; }