Bug 34742

Summary: InitValuatorClassDeviceStruct doesn't align doubles properly
Product: xorg Reporter: Julien Cristau <jcristau>
Component: Server/Input/CoreAssignee: Peter Hutterer <peter.hutterer>
Status: RESOLVED FIXED QA Contact: Xorg Project Team <xorg-team>
Severity: normal    
Priority: medium CC: kibi
Version: gitKeywords: patch
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:
Bug Depends on:    
Bug Blocks: 31018    

Description Julien Cristau 2011-02-25 14:25:40 UTC
The input and xtest tests for xserver 1.10 rc are failing on sparc with bus errors (unaligned memory accesses) in InitValuatorClassDeviceStruct.  For once that doesn't seem to be a bug in the tests.

Program received signal SIGBUS, Bus error.
0x0002f028 in InitValuatorClassDeviceStruct (dev=0xffd28b70, numAxes=2, labels=0xffd28e70, numMotionEvents=0, mode=1) at ../../dix/devices.c:1264
1264        for (i=0; i<numAxes; i++) {
(gdb) bt
#0  0x0002f028 in InitValuatorClassDeviceStruct (dev=0xffd28b70, numAxes=2, labels=0xffd28e70, numMotionEvents=0, mode=1) at ../../dix/devices.c:1264
#1  0x0001ab50 in dix_init_valuators () at ../../test/input.c:64
#2  0xf7ce732c in test_case_run (suite=0x1e4b70, path=0xf7d59bc8 "") at /build/buildd-glib2.0_2.28.1-1+b1-sparc-HVavEr/glib2.0-2.28.1/./glib/gtestutils.c:1174
#3  g_test_run_suite_internal (suite=0x1e4b70, path=0xf7d59bc8 "") at /build/buildd-glib2.0_2.28.1-1+b1-sparc-HVavEr/glib2.0-2.28.1/./glib/gtestutils.c:1223
#4  0xf7ce74c0 in g_test_run_suite_internal (suite=<value optimized out>, path=0xf7d59bc8 "") at /build/buildd-glib2.0_2.28.1-1+b1-sparc-HVavEr/glib2.0-2.28.1/./glib/gtestutils.c:1233
#5  0xf7ce74c0 in g_test_run_suite_internal (suite=<value optimized out>, path=0xf7d59bc8 "") at /build/buildd-glib2.0_2.28.1-1+b1-sparc-HVavEr/glib2.0-2.28.1/./glib/gtestutils.c:1233
#6  0xf7ce7810 in g_test_run_suite (suite=0x1e4b10) at /build/buildd-glib2.0_2.28.1-1+b1-sparc-HVavEr/glib2.0-2.28.1/./glib/gtestutils.c:1274
#7  0x0001a0e0 in main (argc=1, argv=0xffd29324) at ../../test/input.c:1221

Here's my understanding of the bug:

    valc = (ValuatorClassPtr)calloc(1, sizeof(ValuatorClassRec) +
                                    numAxes * sizeof(AxisInfo) +
                                    numAxes * sizeof(double));
[...]
    valc->axes = (AxisInfoPtr)(valc + 1);
    valc->axisVal = (double *)(valc->axes + numAxes);
[...]
    for (i=0; i<numAxes; i++) {
        InitValuatorAxisStruct(dev, i, labels[i], NO_AXIS_LIMITS, NO_AXIS_LIMITS,
                               0, 0, 0, mode);
        valc->axisVal[i]=0;
    }

The crash is in that last loop:

   0x0002efe8 <+168>:   ld  [ %i2 + %l0 ], %o2
   0x0002efec <+172>:   mov  %l1, %o1
   0x0002eff0 <+176>:   mov  %i0, %o0
   0x0002eff4 <+180>:   mov  -1, %o3
   0x0002eff8 <+184>:   mov  -1, %o4
   0x0002effc <+188>:   clr  [ %sp + 0x5c ]
   0x0002f000 <+192>:   clr  %o5
   0x0002f004 <+196>:   clr  [ %sp + 0x60 ]
   0x0002f008 <+200>:   inc  %l1
   0x0002f00c <+204>:   call  0xf6e40 <InitValuatorAxisStruct>
   0x0002f010 <+208>:   st  %i4, [ %sp + 0x64 ]
   0x0002f014 <+212>:   ld  [ %l2 + 0x20 ], %g2
   0x0002f018 <+216>:   add  %l0, %l0, %g1
   0x0002f01c <+220>:   cmp  %i1, %l1
   0x0002f020 <+224>:   add  %l0, 4, %l0
   0x0002f024 <+228>:   bg  %icc, 0x2efe8 <InitValuatorClassDeviceStruct+168>
=> 0x0002f028 <+232>:   clrx  [ %g2 + %g1 ]

and the faulting instruction is clearing valc->axisVal[0].

We have sizeof(ValuatorClassRec) == 52, sizeof(AxisInfo) == 28 and numAxis == 2.  A double on sparc needs 8-byte alignment, but valc->axisVal is (char *)valc + 52 + 2*28, which is not aligned.  The calloc and setting of valc->axisVal need to account for the required alignment.
Comment 1 Julien Cristau 2011-02-25 15:02:33 UTC
http://patchwork.freedesktop.org/patch/4258/
Comment 2 Julien Cristau 2011-02-25 21:52:35 UTC
commit 678f5396c91b3d0c7572ed579b0a4fb62b2b4655
Author: Keith Packard <keithp@keithp.com>
Date:   Fri Feb 25 21:10:21 2011 -0800

    input: Ensure Valuator axes are aligned as needed
    
    Let the compiler figure out the correct alignment for the axes data
    for a valuator by using a union to force double alignment of the
    initial ValuatorClassRec structure in the allocation.
    
    Signed-off-by: Keith Packard <keithp@keithp.com>
    Tested-by: Julien Cristau <jcristau@debian.org>
    Reviewed-by: Julien Cristau <jcristau@debian.org>

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.