Bug 233233 - .gnu.hash support is incompatible/unsupported on mips
Bug#: 233233 Product:  Gentoo Linux Version: unspecified Platform: MIPS
OS/Version: Linux Status: RESOLVED Severity: critical Priority: P2
Resolution: FIXED Assigned To: toolchain@gentoo.org Reported By: kumba@gentoo.org
Component: Development
URL: 
Summary: .gnu.hash support is incompatible/unsupported on mips
Keywords:  
Status Whiteboard: 
Opened: 2008-07-29 07:00 0000
Description:   Opened: 2008-07-29 07:00 0000
With the addition of 77_all_generate-gnu-hash.patch, newer binutils will not
function properly on mips due to an explicit check for .gnu.hash attempts by
ld.  If --hash-style=sysv is not explicitly set in make.conf via LDFLAGS or
CFLAGS, then the following error is encountered:

/usr/lib/gcc/mips-unknown-linux-gnu/4.3.1/../../../../mips-unknown-linux-gnu/bin/ld:
.gnu.hash is incompatible with the MIPS ABI

This is because .gnu.hash support is incompatible with the MIPS ABI, and very
likely, never will be compatible.  The gory details are available in the
following message:

http://www.sourceware.org/ml/binutils/2006-07/msg00341.html


We need to either have mips force --hash-style=sysv via some means/mechanism,
or this patch needs to be skipped when binutils is compiled on a mips host or
being compiled for a mips host.

------- Comment #1 From Ryan Hill 2008-07-29 14:18:51 0000 -------
i've mentioned this to vapier several times but nothing has ever come of it. 
forcing -Wl,--hash-style=sysv in the profile would work for the most part but
any package ignoring LDFLAGS will still break.  i think the best way to do this
is to make 77_all_generate-gnu-hash.patch conditional on !mips.

------- Comment #2 From Joshua Kinard 2008-07-29 14:32:36 0000 -------
Yeah, though considering all the patching code is in an eclass, I'm not sure
how a patch can be applied to all archs but one.  I think the patch naming
scheme allows one to apply only to a specific arch, or all archs only.

------- Comment #3 From Ryan Hill 2008-07-29 14:56:42 0000 -------
hmm.  one quick and dirty way i've done this before was to have something like
78_mips_read-my-mips_no-gnu-hashes.patch which is 77 reversed.  there may be a
better way of doing it though.

------- Comment #4 From Ryan Hill 2008-07-29 15:08:34 0000 -------
what do you know, epatch takes arguments. :P

src_unpack(){
    toolchain-binutils_src_unpack
    use mips && EPATCH_OPTS="-R" epatch
"${WORKDIR}"/patch/77_all_generate-gnu-hash.patch
}

------- Comment #5 From Joshua Kinard 2008-07-29 15:22:01 0000 -------
Yeah, but that means touching the ebuilds for binutils directly.  Probably
easier to apply a reverse patch that fires for mips only, since the offending
patch is a one-liner.

------- Comment #6 From SpanKY 2008-08-20 03:53:08 0000 -------
fixed in cvs ... released in 2.18-r3, but queued for everything else

http://sources.gentoo.org/gentoo/src/patchsets/binutils/2.17.50.0.10/77_all_generate-gnu-hash.patch?r1=1.1&r2=1.2
http://sources.gentoo.org/gentoo/src/patchsets/binutils/2.17.50.0.11/77_all_generate-gnu-hash.patch?r1=1.1&r2=1.2
http://sources.gentoo.org/gentoo/src/patchsets/binutils/2.17.50.0.12/77_all_generate-gnu-hash.patch?r1=1.1&r2=1.2
http://sources.gentoo.org/gentoo/src/patchsets/binutils/2.17.50.0.13/77_all_generate-gnu-hash.patch?r1=1.1&r2=1.2
http://sources.gentoo.org/gentoo/src/patchsets/binutils/2.17.50.0.14/77_all_generate-gnu-hash.patch?r1=1.1&r2=1.2
http://sources.gentoo.org/gentoo/src/patchsets/binutils/2.17.50.0.15/77_all_generate-gnu-hash.patch?r1=1.1&r2=1.2
http://sources.gentoo.org/gentoo/src/patchsets/binutils/2.17.50.0.16/77_all_generate-gnu-hash.patch?r1=1.1&r2=1.2
http://sources.gentoo.org/gentoo/src/patchsets/binutils/2.17.50.0.17/77_all_generate-gnu-hash.patch?r1=1.1&r2=1.2
http://sources.gentoo.org/gentoo/src/patchsets/binutils/2.17.50.0.18/77_all_generate-gnu-hash.patch?r1=1.1&r2=1.2
http://sources.gentoo.org/gentoo/src/patchsets/binutils/2.18/77_all_generate-gnu-hash.patch?r1=1.1&r2=1.2
http://sources.gentoo.org/gentoo/src/patchsets/binutils/2.18.50.0.1/77_all_generate-gnu-hash.patch?r1=1.1&r2=1.2
http://sources.gentoo.org/gentoo/src/patchsets/binutils/2.18.50.0.2/77_all_generate-gnu-hash.patch?r1=1.1&r2=1.2
http://sources.gentoo.org/gentoo/src/patchsets/binutils/2.18.50.0.3/77_all_generate-gnu-hash.patch?r1=1.1&r2=1.2
http://sources.gentoo.org/gentoo/src/patchsets/binutils/2.18.50.0.4/77_all_generate-gnu-hash.patch?r1=1.1&r2=1.2
http://sources.gentoo.org/gentoo/src/patchsets/binutils/2.18.50.0.5/77_all_generate-gnu-hash.patch?r1=1.1&r2=1.2
http://sources.gentoo.org/gentoo/src/patchsets/binutils/2.18.50.0.6/77_all_generate-gnu-hash.patch?r1=1.1&r2=1.2
http://sources.gentoo.org/gentoo/src/patchsets/binutils/2.18.50.0.7/77_all_generate-gnu-hash.patch?r1=1.1&r2=1.2

------- Comment #7 From SpanKY 2008-08-20 04:00:14 0000 -------
*** Bug 232139 has been marked as a duplicate of this bug. ***

------- Comment #8 From Joshua Kinard 2008-08-23 20:28:42 0000 -------
Doesn't look like the change to 77_all_generate-gnu-hash.patch works:

# mips64make -j3 vmlinux
  CHK     include/linux/version.h
  CHK     include/linux/utsrelease.h
  Checking missing-syscalls for N32
  CALL    scripts/checksyscalls.sh
  Checking missing-syscalls for O32
  CALL    scripts/checksyscalls.sh
  CALL    scripts/checksyscalls.sh
  CHK     include/linux/compile.h
  LD      usr/built-in.o
mips64-unknown-linux-gnu-ld: .gnu.hash is incompatible with the MIPS ABI
  LD      init/mounts.o
mips64-unknown-linux-gnu-ld: .gnu.hash is incompatible with the MIPS ABI
make[1]: *** [init/mounts.o] Error 1
make: *** [init] Error 2
make: *** Waiting for unfinished jobs....
make[1]: *** [usr/built-in.o] Error 1
make: *** [usr] Error 2
  LD      arch/mips/sgi-ip30/built-in.o
mips64-unknown-linux-gnu-ld: .gnu.hash is incompatible with the MIPS ABI
make[1]: *** [arch/mips/sgi-ip30/built-in.o] Error 1
make: *** [arch/mips/sgi-ip30] Error 2


The problem with that warning/error message out of the ld is the return code
triggers a failure to the make system, killing the compile.  Removing the 77_
patch looks so far like the only thing that works for us.

------- Comment #9 From SpanKY 2008-08-29 08:46:50 0000 -------
i imagine it's only failing in the cross case.  native prob works fine.

------- Comment #10 From Joshua Kinard 2008-11-04 22:29:57 0000 -------
Native does work fine, but this essentially breaks crossdev for mips targets,
because the #ifdef __mips__ check passes on a non-mips system, and binutils
gets built with .gnu hash support.  End result:

# mips64make -j3 vmlinux
  CHK     include/linux/version.h
  CHK     include/linux/utsrelease.h
  Checking missing-syscalls for N32
  CALL    scripts/checksyscalls.sh
  Checking missing-syscalls for O32
  CALL    scripts/checksyscalls.sh
  CALL    scripts/checksyscalls.sh
  CHK     include/linux/compile.h
  GEN     .version
  CHK     include/linux/compile.h
  UPD     include/linux/compile.h
  CC      init/version.o
  LD      init/built-in.o
mips64-unknown-linux-gnu-ld: .gnu.hash is incompatible with the MIPS ABI
make[1]: *** [init/built-in.o] Error 1
make: *** [.tmp_vmlinux1] Error 2

# uname -a
Linux khazad-dum 2.6.25.6 #4 SMP Sun Jun 22 14:21:56 EDT 2008 i686 AMD
Athlon(tm) MP 2000+ AuthenticAMD GNU/Linux

So I have to resort to tricks to get cross-binutils to build properly so I can
cross-compile mips kernels.

------- Comment #11 From Phattanon Duangdara 2008-11-23 09:48:06 0000 -------
I just add this in toolchain-binutils.eclass for workaround in case of cross
compile
remove gnu-patch patch file for this target

--- /usr/portage/eclass/toolchain-binutils.eclass       2007-11-12
03:06:11.000000000 +0700
+++ /usr/local/portage/eclass/toolchain-binutils.eclass 2008-11-23
16:40:25.992977846 +0700
@@ -114,6 +114,10 @@
        if ! use vanilla ; then
                if [[ -n ${PATCHVER} ]] ; then
                        EPATCH_SOURCE=${WORKDIR}/patch
+                       if [[ ${CTARGET} == mips* ]] ; then
+                               # remove gnu-hash for mips (bug #233233)
+                               rm -f ${EPATCH_SOURCE}/*gnu-hash*.patch
+                       fi
                        [[ -n $(ls "${EPATCH_SOURCE}"/*.bz2 2>/dev/null) ]] \
                                && EPATCH_SUFFIX="patch.bz2" \
                                || EPATCH_SUFFIX="patch"

------- Comment #12 From Ryan Hill 2008-11-23 10:24:40 0000 -------
if we want to do it that way just set EPATCH_EXCLUDE.

------- Comment #13 From Pavel Shirov 2008-11-25 13:04:35 0000 -------
This is related to #229173

------- Comment #14 From Joshua Kinard 2008-11-29 19:14:27 0000 -------
Created an attachment (id=173791) [details]
Block .gnu.hash patch on mips

Here's a proposed patch that uses EPATCH_EXCLUDE.  Tested on x86_64 -->
mips64-unknown-linux-gnu.

------- Comment #15 From Joshua Kinard 2008-12-05 06:51:27 0000 -------
No comments/complaints?  I'll put this in in a few days unless otherwise.  It's
holding us back on some things.

------- Comment #16 From SpanKY 2008-12-07 20:31:39 0000 -------
*** Bug 246573 has been marked as a duplicate of this bug. ***

------- Comment #17 From Joshua Kinard 2008-12-09 06:07:43 0000 -------
Patch is in.

------- Comment #18 From Mark Loeser 2009-05-10 02:13:52 0000 -------
*** Bug 229173 has been marked as a duplicate of this bug. ***