Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 06 Feb 2013 23:14:01 +1300
From:      Andrew Turner <andrew@fubar.geek.nz>
To:        freebsd-toolchain@freebsd.org
Subject:   Link issue with clang and ARM EABI
Message-ID:  <20130206231401.30953f4a@bender>

next in thread | raw e-mail | index | archive | help
--MP_/ZSFc84MBJQShx33Pmhr/YOl
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Hello,

I've been updating clang to support ARM EABI on FreeBSD. The problem
I've found is libc & compiler-rt are dependent on each other.

The current link order for a static binary is to append -lgcc -lc -lgcc
to the end of the link command. The __aeabi_mem* are implemented by
calling their equivalent function in libc, for example __aeabi_memmove
calls the libc memmove.

The problem is clang can place calls to these __aeabi_mem* functions in
libc. If we are building a static program libc will call into the
second copy of libgcc which is then unable to find the required symbol.

This doesn't appear to be a problem for the run-time linker so shared
binaries work without changing the libraries linked against.

The attached patch fixes this by changing the link order to -lc -lgcc
-lc -lgcc. This means the program will use the symbol in the first copy
of libc which will call into the first libgcc and that calls into the
second libc.

Can anyone see any problems doing this? I would like to send it
upstream and commit it to our tree to help get ARM EABI clang builds
working.

(CC me, I'm not on the list)

Andrew
--MP_/ZSFc84MBJQShx33Pmhr/YOl
Content-Type: text/x-patch
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=clang_libc.diff

Index: contrib/llvm/tools/clang/lib/Driver/Tools.cpp
===================================================================
--- contrib/llvm/tools/clang/lib/Driver/Tools.cpp	(revision 246368)
+++ contrib/llvm/tools/clang/lib/Driver/Tools.cpp	(working copy)
@@ -5574,10 +5574,24 @@
     }
     // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
     // the default system libraries. Just mimic this for now.
-    if (Args.hasArg(options::OPT_pg))
+
+    // On some architectures and ABIs, for example ARM EABI, libc and libgcc
+    // can call into each other. An example is when clang generates calls
+    // to __aeabi_memcpy, which may then call memcpy. As __aeabi_memcpy is
+    // probided by compiler-rt and memcpy is provided by libc this means
+    // libc is looking for a symbol in compiler-rt which in turn is looking
+    // for a symbol in libc. This is only a problem with static linking
+    // so in this case we link against libc, compiler-rt, libc and compiler-rt
+    // in that order.
+    if (Args.hasArg(options::OPT_pg)) {
+      if (Args.hasArg(options::OPT_static))
+        CmdArgs.push_back("-lc_p");
       CmdArgs.push_back("-lgcc_p");
-    else
+    } else {
+      if (Args.hasArg(options::OPT_static))
+        CmdArgs.push_back("-lc");
       CmdArgs.push_back("-lgcc");
+    }
     if (Args.hasArg(options::OPT_static)) {
       CmdArgs.push_back("-lgcc_eh");
     } else if (Args.hasArg(options::OPT_pg)) {

--MP_/ZSFc84MBJQShx33Pmhr/YOl--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130206231401.30953f4a>