Subject: toolchain/22452: programs broken b/c libgcc1 functions are in libc, not libgcc
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <uwe@netbsd.org>
List: netbsd-bugs
Date: 08/12/2003 12:46:48
>Number: 22452
>Category: toolchain
>Synopsis: programs broken b/c libgcc1 functions are in libc, not libgcc
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: toolchain-manager
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Aug 12 12:47:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator: Valeriy E. Ushakov
>Release: 1.6W
>Organization:
>Environment:
NetBSD nada 1.6W NetBSD 1.6W (NADA) #15: Fri Aug 8 04:21:34 MSD 2003 uwe@sampo:/export/netbsd/cvs/src/sys/arch/hpcsh/compile/NADA hpcsh
>Description:
With gcc-2.95.3 sh3 ports were limited to static world. Now that
gcc-3.3.1 is in the tree, sh3 ports can be compiled to use shared
libraries, however the resulting world has many important binaries
broken (fsck_ffs, ksh, mv, sshd - to name a few). I used to run
dynamic sh3 words before, built with gcc-3.3 as EXTERNAL_TOOLCHAIN and
it worked fine.
The problem is caused by the fact that in NetBSD platform's libgcc1
functions are part of libc, not libgcc.
In my case i traced the lossage down to __udivsi3 function (or
pseudo-instruction, if you will).
__udivsi3_i1 instruction is not treated as a normal function call that
clobbers all the scratch registers. In sh.md it is defined to clobber
only a couple of registers.
However, since in NetBSD this function is in libc, when the shared
libc.so is used, the call to __udivsi3 (in libc.so) will clobber the
scratch registers because it has to go through the dynamic linker. In
other words, a call to __udivsi3 in a shared library doesn't really
satisfy the constraints of sh.md.
In a stock gcc distribution, this function is in libgcc.a, so the code
is correct and the dynamic world built in such way worked fine. But
when the __udivsi3 is in the libc.so - the code generated by the gcc
is simply not correct (keeps values in scratch registers across a
function call).
I'd say that this is our fault that we put __udivsi3 (and other
libgcc1 functions) into libc. We should move it back to libgcc where
it belongs, because the code generated by the gcc depends on it.
>How-To-Repeat:
Build world for a sh3 platform using gcc-3.3.1 by specifying USE_TOOLS_TOOLCHAIN=no
Make sure that NOPIC is not defined by bsd.own.mk. Setting HAVE_GCC3
might be ok though I'm not sure if it has other effect. I simply
commented that piece of bsd.own.mk out for my builds.
Try to run the produced binaries. Observe some of them fail
in misterious ways. E.g.
$ mv a b
mv: out of memory!
>Fix:
Functions like __udivsi3 should be moved to libgcc.a.
Manually adding relevant .o files from libc.a to libgcc.a and
relinking the failing binaries made them work.
libgcc1 functions are in lib/libc/arch/${MACHINE}/gen/
For sh3 those are (if i haven't missed some):
ashiftrt.S
ashlsi3.S
ashrsi3.S
lshrsi3.S
movstr.S
movstrSI.S
movstr_i4.S
mulsi3.S
sdivsi3.S
udivsi3.S
>Release-Note:
>Audit-Trail:
>Unformatted: