This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC 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 target/46644] New: Built-in memcpy() does not test for unaligned destination address on ARM


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46644

           Summary: Built-in memcpy() does not test for unaligned
                    destination address on ARM
           Product: gcc
           Version: 4.4.3
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: target
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: eblot.ml@gmail.com


Foreword: this bug might be related to 46483 (over-aggresive memcpy()
optimization) although the input instructions to trigger the issue seem to be
different.

Using GCC 4.4.3 up to at least 4.5.1, with a ARM-EABI target (AAPCS variant,
not tested with a Linux-modified EABI), for ARMv4/ARMv5 architectures - at
least.

GCC performs aggressive memcpy() optimization, replacing the memcpy() function
call with direct ARM instructions.

When a 16-bit value is copied, GCC "forgets" to handle the un-aligned
destination address cases.

Code example:

void memcpy_test(void)
{
    extern uint16_t * msrc; // actual address is not known on purpose
    extern uint16_t * mdst; // actual address is not known on purpose

    memcpy(mdst, msrc, sizeof(uint16_t));
}

Generated code:

00000000 <memcpy_test>:
   0:    e59f2014     ldr    r2, [pc, #20]    ; 1c <memcpy_test+0x1c>
   4:    e59f3014     ldr    r3, [pc, #20]    ; 20 <memcpy_test+0x20>
   8:    e5922000     ldr    r2, [r2]
   c:    e5933000     ldr    r3, [r3]
  10:    e1d220b0     ldrh    r2, [r2]
  14:    e1c320b0     strh    r2, [r3]
  18:    e12fff1e     bx    lr

Here 'ldrh' and 'strh' have replaced the memcpy() call.
However, if mdst or msrc are not aligned, the ARM CPU cannot properly copy the
16-bit values: destination contains a wrong value, and surrounding bytes may be
overridden with the actual value.

This issue does NOT occurs if:
 * mdst or msrc are not 16-bit pointers
 * -O0 is used (memcpy() optimization is disabled)

In the above cases, the code looks like the expected one, that is:

00000000 <memcpy_test>:
   0:    e92d4008     push    {r3, lr}
   4:    e59f3018     ldr    r3, [pc, #24]    ; 24 <memcpy_test+0x24>
   8:    e5930000     ldr    r0, [r3]
   c:    e59f3014     ldr    r3, [pc, #20]    ; 28 <memcpy_test+0x28>
  10:    e3a02002     mov    r2, #2
  14:    e5931000     ldr    r1, [r3]
  18:    ebfffffe     bl    0 <memcpy>
  1c:    e8bd4008     pop    {r3, lr}
  20:    e12fff1e     bx    lr

However, the same issue can be reproduced if msrc and mdst pointer are 32-bit
value pointers (uint32_t *). In this case, the generated and invalid code is:

00000000 <memcpy_test>:
   0:    e59f2014     ldr    r2, [pc, #20]    ; 1c <memcpy_test+0x1c>
   4:    e59f3014     ldr    r3, [pc, #20]    ; 20 <memcpy_test+0x20>
   8:    e5922000     ldr    r2, [r2]
   c:    e5933000     ldr    r3, [r3]
  10:    e1d220b0     ldrh    r2, [r2]
  14:    e1c320b0     strh    r2, [r3]
  18:    e12fff1e     bx    lr


GCC build options:

Target: arm-eabi
Configured with: ../configure
--prefix=/usr/local/homebrew/Cellar/gcc-arm-ecos/4.4.3 --target=arm-eabi
--disable-shared --with-gnu-as --with-gnu-ld --with-newlib --enable-softfloat
--disable-bigendian --disable-fpu --disable-underscore --enable-multilibs
--with-float=soft --enable-interwork --with-fpu=fpa
--with-multilib-list=interwork --with-abi=aapcs --enable-languages=c,c++
--disable-__cxa_atexit --with-gmp=/usr/local/homebrew/Cellar/gmp/5.0.1
--with-mpfr=/usr/local/homebrew/Cellar/mpfr/2.4.2
--with-ppl=/usr/local/homebrew/Cellar/ppl/0.10.2
--with-cloog=/usr/local/homebrew/Cellar/cloog-ppl/0.15.7
--with-libelf=/usr/local/homebrew/Cellar/libelf/0.8.13
--with-gxx-include-dir=/usr/local/homebrew/Cellar/gcc-arm-ecos/4.4.3/arm-eabi/include
Thread model: single
gcc version 4.4.3


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