• Status Closed
  • Percent Complete
    100%
  • Task Type Bug Report
  • Category Packages → Packages: Stable
  • Assigned To No-one
  • Operating System i486
  • Severity Low
  • Priority Low
  • Reported Version
  • Due in Version Undecided
  • Due Date Undecided
  • Votes
  • Private
Attached to Project: Archlinux32
Opened by Andreas Baumann - 15.11.2018
Last edited by Andreas Baumann - 31.01.2019

FS#57 - libc fails on AMD-K6

pacstrap /test base
LD_LIBRARY_PATH=/test/usr/lib gdb –args /test/bin/bash results in:

Program terminated with signal SIGILL, Illegal instruction.
#0  0xb7619991 in strcmp () from /test/usr/lib/libc.so.6
(gdb) bt
#0  0xb7619991 in strcmp () from /test/usr/lib/libc.so.6
#1  0xb75bd41f in setlocale () from /test/usr/lib/libc.so.6
#2  0x0076b7f2 in ?? ()
#3  0x0053acf6 in ?? ()
#4  0xb75b3a31 in __libc_start_main () from /test/usr/lib/libc.so.6
#5  0x0053e561 in ?? ()

So, getting the exact failing opcode is hard.

2.28-5.0 was ok,
2.28-5.2 is not.

So it’s something we changed or something changed on one of the i486 build slaves.

Happens only on the AMD-K6, all other machines with CPUs with limited special instruction
sets (Pentium-S, AMD Geode) are working fine.

Closed by  Andreas Baumann
31.01.2019 13:50
Reason for closing:  Fixed
Additional comments about closing:  

works with glibc-2.28-5.5-i486

Admin
Andreas Baumann commented on 10.01.2019 08:27

happens on a Pentium-S now too.
Pentium-II is still fine, so is AMD Geode..

Admin
Andreas Baumann commented on 24.01.2019 10:10

Finally got around to tackle this one
installing a minimal chroot with:

pacstrap /test bash

Then debugging the chroot call:

gdb --args /usr/bin/chroot /test

yields:

Dump of assembler code for function memcpy:
   0xb7ff22f0 <+0>:     test   %al,%al
   0xb7ff22f2 <+2>:     jne    0xb7ff22e8
   0xb7ff22f4 <+4>:     xor    %eax,%eax
   0xb7ff22f6 <+6>:     ret    
   0xb7ff22f7 <+7>:     mov    $0x1,%eax
   0xb7ff22fc <+12>:    mov    $0xffffffff,%ecx
> 0xb7ff2301 <+17>:    cmovb  %ecx,%eax
   0xb7ff2304 <+20>:    ret    
End of assembler dump.

So, we got cmov creeping in.

/proc/cpuinfo tells us that neither early Pentiums nor AMD K6 had a CMOV opcode.

Now the trick question is, why is it creeping into the C library?

Is the C library compiled with the wrong flags?
Is the gcc assuming that every CPU has a CMOV instruction? Are flags wrong there
or is CMOV suddenly the default?

Admin
Andreas Baumann commented on 24.01.2019 10:39

Checking in glibc: this is the offending opcode

i686/strcmp.S:  cmovbl  %ecx, %eax

L(neq): movl    $1, %eax
        movl    $-1, %ecx
        cmovbl  %ecx, %eax

Now the question is, why does glibc think it's ok to use i686 optimizations
when compiling with -march-i486.

Admin
Andreas Baumann commented on 24.01.2019 11:09

Not found an obvious reason, retriggering rebuild on known-good (hopefully) i486 build slave.

Admin
Andreas Baumann commented on 24.01.2019 20:44

config.log shows me i686 as build host. This is guessed with config.guess.
Manually executing config.guess on the build machine results in i486-pc-linux-gnu.
setarch i486 ./config.guess results in i686-pc-linux-gnu.
setarch i486 uname -m results in i686.

This breaks every build on i486!

/usr/bin/setarch is owned by util-linux 2.33.1-2.3 and is is completly broken!

And of course, it's used in setarch "${arch}" mkarchroot in staging-i486-build.

So the consequenses are:
- devtools32 must NOT use setarch anywhere in the *i486* files
- the whole i486 toolchain and all packages have to be rebuilt (basically from the stage of last bootstrapping, every package above could contain bad opcodes!).

The irony is, that building just with makepkg on a emulated i486 virtual machine works
fine, using the devtools breaks things..

Admin
Andreas Baumann commented on 24.01.2019 21:11

Actually, thinking about it: I should try to patch setarch in coreutils for i486.
So we don't have to fork devtools32 too much from upstream..

binutils and gcc have an explicit host and build flags, so they should be fine.
Maybe rebuilding just glibc with a fixed setarch is sufficient.

Admin
Andreas Baumann commented on 24.01.2019 21:15

If we are unlucky, utsname information in setarch.c is wrong and it's not
a coreutils problem..

Admin
Andreas Baumann commented on 25.01.2019 08:05

The man page of setarch documents the bug:

The execution domains currently only affects the output of uname -m.  For example, on an AMD64 sys-
       tem, running setarch i386 program will cause program to see i686 instead of x86_64 as  the  machine
       type.  It also allows to set various personality options.  The default program is /bin/sh.

So, we are not allowed to fix this, as other programs may rely on the bug.

So, fixing the devtools32 it is...

Admin
Andreas Baumann commented on 25.01.2019 09:15

setarch bug reported here:

https://github.com/karelzak/util-linux/issues/707

and here:

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=506632

uname -p reports unknown, this explains why config.guess relies
on uname -m to guess the CPU.

We came to those possible solutions:
- fix setarch.c (rather let it report something different than what the kernel is providing)
- add flags to devtools32 to switch off setarch usage (means, we can no longer build i486 on x86_64 slaves)
- add –build=i486-pc-linux-gnu in every configure call necessary
- go with the CLFS uname hack
- hack setarch of the host machine

Admin
Andreas Baumann commented on 27.01.2019 16:05
Admin
Andreas Baumann commented on 27.01.2019 18:04
wget http://clfs.org/files/extras/uname_hack-20080713.tar.bz2

PKGBUILD of linux:
_srcver=4.20.4-arch1
pkgver=${_srcver//-/.}
pkgrel=1.0
make modules_prepare

make -C /root/linux/src/archlinux-linux SUBDIRS=$PWD uname_hack_fake_machine=i486

insmod uname_hack.ko

setarch i486 uname -m
i686
setarch i486 ./config.guess 
i686-pc-linux-gnu

Ok, the uname hack no longer works, or setarch doesn't rely on this module information.

Loading...

Available keyboard shortcuts

Tasklist

Task Details

Task Editing