Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Thu, 26 Sep 2019 18:45:21 -0400
From: Rich Felker <dalias@...c.org>
To: musl@...ts.openwall.com
Subject: mips fp32/fpxx/fp64 issues, r6 sjlj broken

It's come to my attention that there's something of a mess around the
mips floating point ABI variants. The original site on the matter
seems down, but is accessible here:

https://web.archive.org/web/20180829093351/https://dmz-portal.mips.com/wiki/MIPS_O32_ABI_-_FR0_and_FR1_Interlinking

The different fp ABI models are ways of dealing with 2 different mips
fpu modes/variants, one which has 32 32-bit registers, even/odd pairs
of which are used to store doubles, and the other of which has 32
64-bit registers that can each store a single or a double.

The original o32 ABI is fp32 (for hardware mode with 32 32-bit regs),
and this is what we implement in asm where it matters (setjmp and
longjmp). Modern compiler versions default to fpxx, which is
compatible with fp32, and also compatible with fp64, but not both at
the same time.

The intent from the mips ABI folks' side seems to have been that the
dynamic linker should juggle arbitrary workable mixes of libraries as
long as they don't conflict (fpxx can be mixed with either of the
others but not both). This has never been supported in musl, and
probably never will be; it conflicts with our ABI model of naming
incompatible ABIs differently and not mixing them.

Unfortunately, clang's internal assembler in fpxx mode (the default)
reportedly barfs on the asm instructions needed to implement a
conforming setjmp and longjmp that respect fp32 callers. As I
understand it, this means it's presently impossible to build musl for
mips (32-bit, o32) with clang.

Also, mipsr6 (the new mips-family ISA that's not compatible with
previous mips) always uses the 64-bit register mode. We presently do
not have setjmp/longjmp code that works with this case at all
(existing code will wrongly save low 32-bits of 2 registers instead of
single whole double register); somehow nobody has noticed that this is
broken. Making this conditional on __mips_isa_rev >= 6 should not be
hard.

I'm not sure whether we also have a problem with normal mips (non-r6)
musl run in FR=1 (64-bit registers) mode, because I'm not clear
whether that's a situation you can get into involuntarily (some
hardware that only supports it?) or just unsupported usage (see above
about "probably never will be"). If non-r6 fpxx binaries are supposed
to be able to run on FR=1-only hardware, some action might be needed
here.

At least the r6 thing is a real problem making the subarch totally
broken right now, and the clang thing is a nuisance to anyone wanting
to build with pure clang/llvm tooling. I'd welcome input on how to fix
them, as well as on whether the last potential issue is actually an
issue or not.

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.