This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug dynamic-link/15128] New: dynamic loader may clobber floating-point parameters on AArch64


http://sourceware.org/bugzilla/show_bug.cgi?id=15128

             Bug #: 15128
           Summary: dynamic loader may clobber floating-point parameters
                    on AArch64
           Product: glibc
           Version: 2.17
            Status: NEW
          Severity: normal
          Priority: P2
         Component: dynamic-link
        AssignedTo: unassigned@sourceware.org
        ReportedBy: mikpe@it.uu.se
    Classification: Unclassified


If glibc-2.17 is compiled for aarch64 with -O3 in CFLAGS, then gcc (from
aarch64-4.7-branch of GCC svn) will convert some memory stores in the dynamic
loader to use vector registers and vector instructions.  Vector registers alias
the FP registers.  The code path into the dynamic loader does not preserve the
application's FP registers, so those vector instructions may clobber FP
arguments in the call being resolved.

As the following test case shows, at least printf and log10 are broken by this:

genericarmv8_195_cat aarch64-fp-bug.c 
#include <errno.h>
#include <math.h>
#include <stdio.h>

double x = 100.0;

int main(void)
{
    double y;

    errno = 0;
    y = log10(x);
    printf("log10(%f) = %f, errno = %d\n", x, y, errno);

    return 0;
}
genericarmv8_196_gcc -O aarch64-fp-bug.c -lm ; ./a.out
log10(0.000000) = -inf, errno = 34
genericarmv8_197_gcc -static -O aarch64-fp-bug.c -lm ; ./a.out
log10(100.000000) = 2.000000, errno = 0

When debugging the test case I found that the FP argument to log10 was
clobbered by a fragment like the following in _dl_lookup_symbol_x:

    1094:       910303b8        add     x24, x29, #0xc0
...
    10a0:       4f000400        movi    v0.4s, #0x0
    10a4:       f90073a2        str     x2, [x29,#224]
    10a8:       4c007f00        st1     {v0.2d}, [x24]

When compiled at -O2 or with -mgeneral-regs-only that code is

    10a4:       f9006fa2        str     x2, [x29,#216]
    10a8:       f90063bf        str     xzr, [x29,#192]
    10ac:       f90067bf        str     xzr, [x29,#200]

Further inspection of the object files in the elf directory showed v0 being
clobbered in six of them (dl-addr, dl-libc, dl-load, dl-lookup, dl-reloc, and
rtld), and also in the memset that gets linked in there.

Compiling glibc with -O2 appears to avoid the problem, but it's a blunt and
possibly incomplete solution.  -mgeneral-regs-only is guaranteed to avoid the
problem, but that also prevents FP code, so it can't be used for all of glibc. 
My current solution is to add -mgeneral-regs-only to the seven files listed
above via CFLAGS overrides in the aarch64-specific Makefile.  Doing that runs
into BZ 15005 however, so the fix for that is also needed.

I don't have a copyright assignment, but the patch is small:

 elf/Makefile                   |    4 ++--
 ports/sysdeps/aarch64/Makefile |   10 ++++++++++
 2 files changed, 12 insertions(+), 2 deletions(-)

Does this sound Ok?  Is there a better way to fix this issue?

-- 
Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]