This is the mail archive of the libc-ports@sources.redhat.com mailing list for the libc-ports project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[WIP] glibc: Use /lib/ld-linux-armhf.so.3 for ARM's -mfloat-abi=hard ABI.


On 4/23/2012 4:41 AM, Andrew Haley wrote:
> On 04/14/2012 05:34 PM, Carlos O'Donell wrote:
>> On Fri, Apr 13, 2012 at 1:35 PM, Roland McGrath <roland@hack.frob.com> wrote:
>>>> Mmm, Joseph is away.  Would one of the regular ARM libc maintainers
>>>> like to pick this up?
>>>
>>> Only Joseph is authoritative.
>>
>> The distro community has reached consensus.
>>
>> IMO the glibc community should rely on the experience of the distro
>> community to guide us on such issues.
>>
>> I plan to create the change, test it, post the patch, ask for review
>> and commit as long as others don't see anything technically wrong with
>> this change.
>>
>> During that time I will attempt to get Joseph's feedback on the
>> change, but may fail to do so. I don't see that this blocks the patch
>> checkin to our development *trunk*.
> 
> What's happening with this?

Summary:
========

* Patch gcc to use the new dynamic linker name.

* Patch glibc to...

  * Detect dynamic linker used by the compiler with the given options.

  * If the compiler and options would select the new dynamic
    linker then use that dynamic linker name for building glibc.

Compatibility for old hard-float binaries is left up to the distros.

I'm using the following GCC patch for testing. It is not the same 
as upstream. Upstream is currently broken because it uses named 
enumerations in a cpp macro equality.

(a) GCC patches:

Index: arm.h
===================================================================
--- arm.h       (revision 368507)
+++ arm.h       (working copy)
@@ -378,9 +378,9 @@

 enum float_abi_type
 {
-  ARM_FLOAT_ABI_SOFT,
-  ARM_FLOAT_ABI_SOFTFP,
-  ARM_FLOAT_ABI_HARD
+  ARM_FLOAT_ABI_SOFT = __ARM_FLOAT_ABI_SOFT,
+  ARM_FLOAT_ABI_SOFTFP = __ARM_FLOAT_ABI_SOFTFP,
+  ARM_FLOAT_ABI_HARD = __ARM_FLOAT_ABI_HARD
 };

 extern enum float_abi_type arm_float_abi;
Index: linux-eabi.h
===================================================================
--- linux-eabi.h        (revision 368507)
+++ linux-eabi.h        (working copy)
@@ -31,10 +31,14 @@
     }                                          \
   while (false)

+#define __ARM_FLOAT_ABI_SOFT 0
+#define __ARM_FLOAT_ABI_SOFTFP 1
+#define __ARM_FLOAT_ABI_HARD 2
+
 /* We default to a soft-float ABI so that binaries can run on all
    target hardware.  */
 #undef  TARGET_DEFAULT_FLOAT_ABI
-#define TARGET_DEFAULT_FLOAT_ABI ARM_FLOAT_ABI_SOFT
+#define TARGET_DEFAULT_FLOAT_ABI __ARM_FLOAT_ABI_SOFT

 /* We default to the "aapcs-linux" ABI so that enums are int-sized by
    default.  */
@@ -62,7 +66,17 @@
 /* Use ld-linux.so.3 so that it will be possible to run "classic"
    GNU/Linux binaries on an EABI system.  */
 #undef  GLIBC_DYNAMIC_LINKER
-#define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.3"
+#define GLIBC_DYNAMIC_LINKER_SOFT_FLOAT "/lib/ld-linux.so.3"
+#define GLIBC_DYNAMIC_LINKER_HARD_FLOAT "/lib/ld-linux-armhf.so.3"
+#if TARGET_DEFAULT_FLOAT_ABI == __ARM_FLOAT_ABI_HARD
+#define GLIBC_DYNAMIC_LINKER_DEFAULT GLIBC_DYNAMIC_LINKER_HARD_FLOAT
+#else
+#define GLIBC_DYNAMIC_LINKER_DEFAULT GLIBC_DYNAMIC_LINKER_SOFT_FLOAT
+#endif
+#define GLIBC_DYNAMIC_LINKER \
+   "%{mfloat-abi=hard:" GLIBC_DYNAMIC_LINKER_HARD_FLOAT "} \
+    %{mfloat-abi=soft*:" GLIBC_DYNAMIC_LINKER_SOFT_FLOAT "} \
+    %{!mfloat-abi=*:" GLIBC_DYNAMIC_LINKER_DEFAULT "}"

 /* At this point, bpabi.h will have clobbered LINK_SPEC.  We want to
    use the GNU/Linux version, not the generic BPABI version.  */
===

With the following glibc 2.15 patches:

The patches for trunk are almost identical modulo the
removal of the "eabi" directory since trunk is EABI-only.

(b) Detect dynamic linker used by compiler.

The following new configure test detects the dynamic linker
used by the compiler given the current set of options.
We store the result in libc_cv_compiler_dynlinker_default
for later use in ARM's preconfigure.

As far as I can tell nothing in this test is Linux specific.
We are using ELF terminology to detect the dynamic loader by
name and make no assumptions about the name except that we
assume that readelf returns the name in a given layout.

2012-04-26  Carlos O'Donell  <carlos_odonell@mentor.com>

	* configure.in: Check and set libc_cv_compiler_dynlinker_default.
	* configure: Regenerate.

Index: configure.in
===================================================================
--- configure.in        (revision 368507)
+++ configure.in        (working copy)
@@ -2432,6 +2432,31 @@
 dnl See sysdeps/mach/configure.in for this variable.
 AC_SUBST(mach_interface_list)

+dnl Determine the dynamic linker that the compiler would have used given
+dnl options we have been given. This is useful for machines to know so
+dnl compute it here and have it available for things like ABI checking.
+AC_CACHE_CHECK([what dynamic linker is used by the compiler], libc_cv_complier_dynlinker_default,
+[libc_cv_compiler_dynlinker_default=""
+cat > conftest.c <<EOF
+int main (void) {}
+EOF
+  if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS
+                       -o conftest conftest.c
+                       1>&AS_MESSAGE_LOG_FD])
+  then
+    dnl We read out the program interpreter.
+    libc_cv_compiler_dynlinker_default="`$READELF -W -l conftest | grep interpreter | sed -e 's,^.* \(\/.*\).$,\1,g'`"
+    if test -z "$libc_cv_compiler_dynlinker_default"; then
+      dnl Unexpected output and we failed to parse it correctly.
+      libc_cv_compiler_dynlinker_default="UNEXPECTED"
+    fi
+  else
+    dnl Could not determine default dynamic linker used by the compiler.
+    libc_cv_compiler_dynlinker_default="UNKNOWN"
+  fi
+rm -r conftest.*])
+AC_SUBST(libc_cv_compiler_dynlinker_default)
+
 if test "`(cd $srcdir; pwd)`" = "`pwd`"; then
   config_makefile=
 else
===

(c) Detect alternate loader used by compiler.

In ARM's preconfigure we detect that the compiler is using the new
dynamic linker and select the new "armhf" sysdep directory. The
new "armhf" sysdep directory has a shlib-versions file which 
names the dynamic linker correctly.

One downside to this solution is that we need to duplicate
the directory structure for arm along with Implies in order
to pickup the optimized routines normally present.

This is a bit hackish and I'd be open to other solutions, but
at present this works.

2012-04-26  Carlos O'Donell  <carlos_odonell@mentor.com>

	* sysdeps/arm/preconfigure: Select armhf directory based on
	libc_cv_compiler_dynlinker_default.
	* sysdeps/arm/eabi/armhf/shlib-versions: New file.
	* sysdeps/arm/eabi/armhf/armv6t2/Implies: New file.
	* sysdeps/arm/eabi/armhf/armv7/Implies: New file.

Index: sysdeps/arm/preconfigure
===================================================================
--- sysdeps/arm/preconfigure	(revision 368507)
+++ sysdeps/arm/preconfigure	(working copy)
@@ -35,6 +35,19 @@
 		  ;;
 		esac
 
+		# We need to additionally check to see if the compiler
+		# is using the new dynamic linker name for the -mfloat-abi=hard
+		# ABI. If it is then we need to select an alternate directory
+		# with an alternate shlib-versions file which names the dynamic
+		# linker correctly.
+		armhf_dynamic_linker="ld-linux-armhf.so.3"
+                if `echo "$libc_cv_compiler_dynlinker_default" | grep "$armhf_dynamic_linker" >& /dev/null`; then
+		    echo "Found compiler is using the new dynamic linker name for the hard-float ABI."
+		    machine=armhf/$machine
+                else
+		    echo "Found compiler either didn't select hard-float ABI or is using the old dynamic linker name."
+		fi
+
 		machine=arm/eabi/$machine
 		if [ "${CFLAGS+set}" != "set" ]; then
 		  CFLAGS="-g -O2"
Index: sysdeps/arm/eabi/armhf/armv6t2/Implies
===================================================================
--- sysdeps/arm/eabi/armhf/armv6t2/Implies	(revision 0)
+++ sysdeps/arm/eabi/armhf/armv6t2/Implies	(revision 0)
@@ -0,0 +1 @@
+arm/eabi/armv6t2
Index: sysdeps/arm/eabi/armhf/shlib-versions
===================================================================
--- sysdeps/arm/eabi/armhf/shlib-versions	(revision 0)
+++ sysdeps/arm/eabi/armhf/shlib-versions	(revision 0)
@@ -0,0 +1,5 @@
+# As of 2.16 the -mfloat-abi=hard ABI variant has a new unique
+# name for the dynamic loader.
+arm.*-.*-linux-gnueabi.*	DEFAULT			GLIBC_2.4
+
+arm.*-.*-linux-gnueabi.*	ld=ld-linux-armhf.so.3
Index: sysdeps/arm/eabi/armhf/armv7/Implies
===================================================================
--- sysdeps/arm/eabi/armhf/armv7/Implies	(revision 0)
+++ sysdeps/arm/eabi/armhf/armv7/Implies	(revision 0)
@@ -0,0 +1 @@
+arm/eabi/armv7
===

Testing still in progress across the 9 multilibs we build
for Sourcery CodeBench.

I caught a couple of problems early and fixed them though,
like not using AC_MSG_ERROR for the configure failure cases
because you might be installing headers and not have a compiler
capable of compiling an application yet. This does imply that
you *might* not get the right set of headers if such headers
changed depending on the dynamic linker selected (which
they shouldn't).

Comments?

Cheers,
Carlos.
-- 
Carlos O'Donell
Mentor Graphics / CodeSourcery
carlos_odonell@mentor.com
carlos@codesourcery.com
+1 (613) 963 1026


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]