From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21319 invoked by alias); 7 Feb 2013 05:13:19 -0000 Received: (qmail 21287 invoked by uid 22791); 7 Feb 2013 05:13:17 -0000 X-SWARE-Spam-Status: No, hits=-6.9 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_SPAMHAUS_DROP,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,RP_MATCHES_RCVD,SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 07 Feb 2013 05:13:07 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r175D4N8032006 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 7 Feb 2013 00:13:04 -0500 Received: from [10.3.113.175] (ovpn-113-175.phx2.redhat.com [10.3.113.175]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r175D2hZ020965; Thu, 7 Feb 2013 00:13:03 -0500 Message-ID: <511337DE.9000802@redhat.com> Date: Thu, 07 Feb 2013 05:13:00 -0000 From: "Carlos O'Donell" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130110 Thunderbird/17.0.2 MIME-Version: 1.0 To: libc-ports@sourceware.org, GNU C Library , "Joseph S. Myers" , Brendan Conoboy , Steve McIntyre Subject: [PATCH] ARM: Fix transitional issues with ld.so.cache. Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact libc-ports-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: libc-ports-owner@sourceware.org X-SW-Source: 2013-02/txt/msg00002.txt.bz2 Joseph, Steve, With a recent binutils the objects built for the VFP ABI are marked with the ELF flag EF_ARM_ABI_FLOAT_HARD. This flag is used by ldconfig to annotate the object in the cache with the FLAG_ARM_LIBHF flag. The FLAG_ARM_LIBHF flag is used to prevent the hard-float dyanmic linker from loading objects that use the wrong ABI e.g. soft-float ABI. Unfortunately the binutils changes for marking objects did not make it into the initial distribution builds and therefore there are many objects in the wild that lack any markings to indicate their ABI. The failure scenario is as follows: * Upgrade to a new glibc. * Upgrade to a new binutils. * Build your library with the new binutils. * Run the new glibc's ldconfig. * Try to run an old application. At this point you have a library marked FLAG_ARM_LIBHF, that can't be mixed with any of the other libraries which are hard-float ABI but no markings and therefore don't match the flags for your library e.g. _dl_cache_check_flags() fails, and the dynamic linker refuses run the application. See BZ#15006 for an example: "Libraries in ld.so.cache ignored by ld-linux-armhf.so.3 on armv6l" http://sourceware.org/bugzilla/show_bug.cgi?id=15006 The solution to this problem is to use 3 states (instead of 2) for the objects in the cache, namely: (1) Don't know / Don't care. (2) Soft-float ABI (new state) (3) VFP ABI. In order to support this transitional period we then allow (1) to mix with either (2) or (3). Once all the distributions have updated to a newer binutils, and all objects are rebuilt, then every object may be either (2) or (3). I say (1) is also a "Don't care" state because this lack of flags can be used in the future to mark objects as not using any of the features of the VFP ABI and thus compatible with either (2) or (3) e.g. make no function calls that have floating point values as arguments. The patch does the following: (a) Adds FLAG_ARM_LIBSF as a new ldconfig flag and adjusts the verbose cache printout to list `,soft-float' when this flag is set and distinguishing from "Don't know." (b) Sets FLAG_ARM_LIBSF for any object with the ELF flag EF_ARM_ABI_FLOAT_SOFT. (c) Expands the conditions in _dl_cache_check to allow hard-float and soft-float dynamic loaders to load unmarked don't know / don't care objects. Tested on ARM with no regressions. Tests run to validate the new compatibility feature: * Built application and library with no markings. - Setup ld.so.conf to include the library. - Ran ldconfig. - Application runs correctly. * Built hard-float ABI application and library with new bintuils. - Verified with readelf that both are now marked hard-float in the ELF flags (though only new readelf can parse it, old readelf prints ). - Ran ldconfig. - Application runs correctly. * Built new glibc. - Removed ldconfig cache and aux cache. - Used newly built ldconfig to build cache. - Application runs correctly when run under new dynamic linker since support for mixing don't care with hard-float is in place. - Double checked that application *fails* to run with distro dynamic linker since the referenced library is marked in the cache with FLAG_ARM_LIBHF that doesn't match any other libraries in the cache and there is no support for mixing unmarked objects. WARNING: - Once you upgrade glibc and run ldconfig it is no longer safe to downgrade glibc. If you downgrade you may not be able to run the applications you need until you forcibly remove the caches and run ldconfig again to rebuild the cache without the new flags. By downgrading you have done is made the bug come back, but now it's worse because all of the objects built with the new binutils are treated as incompatible. OK to checkin? ChangeLog 2013-02-06 Carlos O'Donell * sysdeps/generic/ldconfig.h: Define FLAG_ARM_LIBSF. * elf/cache.c (print_entry): Add FLAG_ARM_LIBSF support. ports/ChangeLog.arm 2013-02-06 Carlos O'Donell * sysdeps/unix/sysv/linux/arm/dl-cache.h [__ARM_PCS_VFP] (_dl_cache_check_flags): Allow plain FLAG_ELF_LIBC6. [!__ARM_PCS_VFP] (_dl_cache_check_flags): Likewise. * sysdeps/unix/sysv/linux/arm/readelflib.c (process_elf_file): Set FLAG_ARM_LIBSF for soft-float ABI otherwise just FLAG_ELF_LIBC6. diff --git a/elf/cache.c b/elf/cache.c index 9901952..699550b 100644 --- a/elf/cache.c +++ b/elf/cache.c @@ -100,6 +100,10 @@ print_entry (const char *lib, int flag, unsigned int osversion, case FLAG_AARCH64_LIB64: fputs (",AArch64", stdout); break; + /* Uses the ARM soft-float ABI. */ + case FLAG_ARM_LIBSF: + fputs (",soft-float", stdout); + break; case 0: break; default: diff --git a/sysdeps/generic/ldconfig.h b/sysdeps/generic/ldconfig.h index 57a9a46..91190aa 100644 --- a/sysdeps/generic/ldconfig.h +++ b/sysdeps/generic/ldconfig.h @@ -36,6 +36,7 @@ #define FLAG_X8664_LIBX32 0x0800 #define FLAG_ARM_LIBHF 0x0900 #define FLAG_AARCH64_LIB64 0x0a00 +#define FLAG_ARM_LIBSF 0x0b00 /* Name of auxiliary cache. */ #define _PATH_LDCONFIG_AUX_CACHE "/var/cache/ldconfig/aux-cache" diff --git a/ports/sysdeps/unix/sysv/linux/arm/dl-cache.h b/ports/sysdeps/unix/sysv/linux/arm/dl-cache.h index acc4f28..1221181 100644 --- a/ports/sysdeps/unix/sysv/linux/arm/dl-cache.h +++ b/ports/sysdeps/unix/sysv/linux/arm/dl-cache.h @@ -18,12 +18,17 @@ #include +/* In order to support the transition from unmarked objects + to marked objects we must treat unmarked objects as + compatible with either FLAG_ARM_LIBHF or FLAG_ARM_LIBSF. */ #ifdef __ARM_PCS_VFP # define _dl_cache_check_flags(flags) \ - ((flags) == (FLAG_ARM_LIBHF | FLAG_ELF_LIBC6)) + ((flags) == (FLAG_ARM_LIBHF | FLAG_ELF_LIBC6) \ + || (flags) == FLAG_ELF_LIBC6) #else # define _dl_cache_check_flags(flags) \ - ((flags) == FLAG_ELF_LIBC6) + ((flags) == (FLAG_ARM_LIBSF | FLAG_ELF_LIBC6) \ + || (flags) == FLAG_ELF_LIBC6) #endif #include_next diff --git a/ports/sysdeps/unix/sysv/linux/arm/readelflib.c b/ports/sysdeps/unix/sysv/linux/arm/readelflib.c index 81e5ccb..0fbd0dc 100644 --- a/ports/sysdeps/unix/sysv/linux/arm/readelflib.c +++ b/ports/sysdeps/unix/sysv/linux/arm/readelflib.c @@ -46,6 +46,12 @@ process_elf_file (const char *file_name, const char *lib, int *flag, if (elf32_header->e_flags & EF_ARM_ABI_FLOAT_HARD) *flag = FLAG_ARM_LIBHF|FLAG_ELF_LIBC6; else if (elf32_header->e_flags & EF_ARM_ABI_FLOAT_SOFT) + *flag = FLAG_ARM_LIBSF|FLAG_ELF_LIBC6; + else + /* We must assume the unmarked objects are compatible + with all ABI variants. Such objects may have been + generated in a transitional period when the ABI + tags were not added to all objects. */ *flag = FLAG_ELF_LIBC6; } } ---