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>