From patchwork Tue Mar 11 22:29:33 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roland McGrath X-Patchwork-Id: 43 Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx20.g.dreamhost.com (caibbdcaaahc.dreamhost.com [208.113.200.72]) by wilcox.dreamhost.com (Postfix) with ESMTP id 94303360108 for ; Tue, 11 Mar 2014 15:29:40 -0700 (PDT) Received: by homiemail-mx20.g.dreamhost.com (Postfix, from userid 14307373) id 2A56C40C6F912; Tue, 11 Mar 2014 15:29:40 -0700 (PDT) X-Original-To: glibc@patchwork.siddhesh.in Delivered-To: x14307373@homiemail-mx20.g.dreamhost.com Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by homiemail-mx20.g.dreamhost.com (Postfix) with ESMTPS id F036C40CB2B7F for ; Tue, 11 Mar 2014 15:29:39 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:mime-version:content-type :content-transfer-encoding:from:to:subject:message-id:date; q= dns; s=default; b=ZQBgexbYTShQhH3mNJolUYn7IroSO4zrSOatA0nDkwu1nn aqEFcQ6c6NZH5dE/B/XkPnbdf13ekUf3V8eQ88ApjVvB9rHDvGu8C9SmzSNK7MmN SKX+8nzfblbOhFeOt/UW+OBhW3090lyz2NtZVktGIeYLRzjHhD5ZIVsyH+8zY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:mime-version:content-type :content-transfer-encoding:from:to:subject:message-id:date; s= default; bh=8X9r8a1RH3lYJp9ldE+i9D7cMT4=; b=TobaQrp07oqBWKUK5g18 vLZYEeBtTMSfIbmX0+ZEW8TNlcr0zbGufdjX8C1CXJEa64zTWRnwdmUg462hioZm FdKdp8o59O9giU0CFPB3UM5p/nkO7sThkC9uwQErmeogj/q3UfBmdpzs9v3EP6qz o/trLl6mK1da6oLpUcYaSsI= Received: (qmail 26129 invoked by alias); 11 Mar 2014 22:29:37 -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 26119 invoked by uid 89); 11 Mar 2014 22:29:36 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: topped-with-meat.com MIME-Version: 1.0 From: Roland McGrath To: "GNU C. Library" Subject: [PATCH roland/ehdr_start] Use __ehdr_start, when available, for rtld to get its own headers. Message-Id: <20140311222933.CC24274474@topped-with-meat.com> Date: Tue, 11 Mar 2014 15:29:33 -0700 (PDT) X-CMAE-Score: 0 X-CMAE-Analysis: v=2.1 cv=Rt9WckWK c=1 sm=1 tr=0 a=WkljmVdYkabdwxfqvArNOQ==:117 a=14OXPxybAAAA:8 a=p-IcBxuay_IA:10 a=Z6MIti7PxpgA:10 a=kj9zAlcOel0A:10 a=hOe2yjtxAAAA:8 a=DxikxMTHkCS5zwfZm2gA:9 a=CjuIK1q_8ugA:10 X-DH-Original-To: glibc@patchwork.siddhesh.in My motivation for this change is my NaCl port, where the old code's assumption about ELF file layout does not hold. But in fact this is not only cleaner but results in marginally better code. (To compensate I've added a couple of asserts. ;-) Tested on x86_64-linux-gnu: * with binutils-2.22 that the configure check fails and nothing changes * with binutils trunk (2.23 or 2.24 would do as well) that the configure check passes and the new code works (no 'make check' regressions) I'll commit this in a few days absent objections. Thanks, Roland * configure.ac (HAVE_EHDR_START): New check. * configure: Regenerated. * config.h.in (HAVE_EHDR_START): New #undef. * elf/rtld.c (dl_main) [HAVE_EHDR_START]: Use __ehdr_start rather than assuming the lowest-addressed segment maps the start of the file. --- a/config.h.in +++ b/config.h.in @@ -195,6 +195,9 @@ /* Define if linux/fanotify.h is available. */ #undef HAVE_LINUX_FANOTIFY_H +/* Define if the linker defines __ehdr_start. */ +#undef HAVE_EHDR_START + /* */ --- a/configure +++ b/configure @@ -7268,6 +7268,44 @@ if test $libc_cv_predef_stack_protector = yes; then fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker provides __ehdr_start" >&5 +$as_echo_n "checking whether the linker provides __ehdr_start... " >&6; } +if ${libc_cv_ehdr_start+:} false; then : + $as_echo_n "(cached) " >&6 +else + +old_CFLAGS="$CFLAGS" +old_LDFLAGS="$LDFLAGS" +old_LIBS="$LIBS" +CFLAGS="$CFLAGS -fPIC" +LDFLAGS="$LDFLAGS -nostdlib -nostartfiles -shared" +LIBS= +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +extern const char __ehdr_start __attribute__ ((visibility ("hidden"))); +const char *ehdr (void) { return &__ehdr_start; } + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + libc_cv_ehdr_start=yes +else + libc_cv_ehdr_start=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +CFLAGS="$old_CFLAGS" +LDFLAGS="$old_LDFLAGS" +LIBS="$old_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ehdr_start" >&5 +$as_echo "$libc_cv_ehdr_start" >&6; } +if test $libc_cv_ehdr_start = yes; then + $as_echo "#define HAVE_EHDR_START 1" >>confdefs.h + +fi + ### End of automated tests. ### Now run sysdeps configure fragments. --- a/configure.ac +++ b/configure.ac @@ -2069,6 +2069,27 @@ if test $libc_cv_predef_stack_protector = yes; then fi AC_SUBST(libc_extra_cflags) +AC_CACHE_CHECK([whether the linker provides __ehdr_start], + libc_cv_ehdr_start, [ +old_CFLAGS="$CFLAGS" +old_LDFLAGS="$LDFLAGS" +old_LIBS="$LIBS" +CFLAGS="$CFLAGS -fPIC" +LDFLAGS="$LDFLAGS -nostdlib -nostartfiles -shared" +LIBS= +AC_LINK_IFELSE([AC_LANG_SOURCE([ +extern const char __ehdr_start __attribute__ ((visibility ("hidden"))); +const char *ehdr (void) { return &__ehdr_start; } +])], + [libc_cv_ehdr_start=yes], [libc_cv_ehdr_start=no]) +CFLAGS="$old_CFLAGS" +LDFLAGS="$old_LDFLAGS" +LIBS="$old_LIBS" +]) +if test $libc_cv_ehdr_start = yes; then + AC_DEFINE([HAVE_EHDR_START]) +fi + ### End of automated tests. ### Now run sysdeps configure fragments. --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1370,10 +1370,25 @@ of this helper program; chances are you did not intend to run this program.\n\ GLRO(dl_use_load_bias) = main_map->l_addr == 0 ? -1 : 0; /* Set up the program header information for the dynamic linker - itself. It is needed in the dl_iterate_phdr() callbacks. */ - ElfW(Ehdr) *rtld_ehdr = (ElfW(Ehdr) *) GL(dl_rtld_map).l_map_start; - ElfW(Phdr) *rtld_phdr = (ElfW(Phdr) *) (GL(dl_rtld_map).l_map_start - + rtld_ehdr->e_phoff); + itself. It is needed in the dl_iterate_phdr callbacks. */ + const ElfW(Ehdr) *rtld_ehdr; + + /* Starting from binutils-2.23, the linker will define the magic symbol + __ehdr_start to point to our own ELF header if it is visible in a + segment that also includes the phdrs. If that's not available, we use + the old method that assumes the beginning of the file is part of the + lowest-addressed PT_LOAD segment. */ +#ifdef HAVE_EHDR_START + extern const ElfW(Ehdr) __ehdr_start __attribute__ ((visibility ("hidden"))); + rtld_ehdr = &__ehdr_start; +#else + rtld_ehdr = (void *) GL(dl_rtld_map).l_map_start; +#endif + assert (rtld_ehdr->e_ehsize == sizeof *rtld_ehdr); + assert (rtld_ehdr->e_phentsize == sizeof (ElfW(Phdr))); + + const ElfW(Phdr) *rtld_phdr = (const void *) rtld_ehdr + rtld_ehdr->e_phoff; + GL(dl_rtld_map).l_phdr = rtld_phdr; GL(dl_rtld_map).l_phnum = rtld_ehdr->e_phnum;