public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/58744] New: Illegal Memory Access on 3-byte packed struct ARCH: x86_64
@ 2013-10-16  4:18 marcovanotti15+gcc at gmail dot com
  2013-10-16  4:23 ` [Bug c/58744] " marcovanotti15+gcc at gmail dot com
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: marcovanotti15+gcc at gmail dot com @ 2013-10-16  4:18 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 58744
           Summary: Illegal Memory Access on 3-byte packed struct ARCH:
                    x86_64
           Product: gcc
           Version: 4.8.1
            Status: UNCONFIRMED
          Severity: minor
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: marcovanotti15+gcc at gmail dot com

Created attachment 31016
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=31016&action=edit
Minimum test case. Compile it and look at the assembly.

There is a illegal memory access while trying to access an array of packed
struct with 3 unsigned chars as members.

If you have an array of such elems, and want to call a function with one of its
elems (a copy, not a pointer), while copying it to RDI, it moves a QWORD
instead of just 3 bytes. This could end in an illegal memory access (valgrind
detects it). 

Example assembly output (rax is a pointer to the struct elem):
    mov    rdi, QWORD PTR [rax]
    call    apply_filter

Attached File:
    The attached file has a minimal test-case, tested in multiple gcc versions
(described below). It defines a pixel struct, and two functions, one that
receives a pointer to pixel and another that receives a pixel (not a pointer). 
    The function is called for each pixel, dereferencing it on the function
call. 

How to reproduce:
    Compile file.
    Look at the assembly output before the call to apply_filter
    If it moves more than 3 bytes from [RAX] to RDI, it's a bug.

Workaround:
    If you copy the elem to a local variable before the function call, and then
call apply_filter with that variable, it works, because the variable is copied
byte by byte.
    For example (change line 11 for these two lines):
        k = src[i];
        dst[i] = apply_filter(k);


Related Notes:
    If the struct is of 4 chars instead of 3, it moves a DWORD, not a QWORD, if
the struct is of 5 o 6, it moves a QWORD again. With 2 chars and 1 chars it
moves WORD and BYTE respectively.


Compiler Flags: gcc -std=c99 -Wall -Wextra -O0 -c color_filter_c.c -pedantic -o
color_filter_bug.asm -S -masm=intel

Architecture: x86_64

Tested this bug in:

gcc (GCC) 4.8.1 20130725 (prerelease)
gcc (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
gcc (Debian 4.7.2-5) 4.7.2
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3


Output of gcc -v (for the latest version):

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.1/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: /build/gcc/src/gcc-4.8-20130725/configure --prefix=/usr
--libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man
--infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/
--enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared
--enable-threads=posix --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch
--enable-gnu-unique-object --enable-linker-build-id --enable-cloog-backend=isl
--disable-cloog-version-check --enable-lto --enable-gold --enable-ld=default
--enable-plugin --with-plugin-ld=ld.gold --with-linker-hash-style=gnu
--disable-install-libiberty --disable-multilib --disable-libssp
--disable-werror --enable-checking=release
Thread model: posix
gcc version 4.8.1 20130725 (prerelease) (GCC)


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug c/58744] Illegal Memory Access on 3-byte packed struct ARCH: x86_64
  2013-10-16  4:18 [Bug c/58744] New: Illegal Memory Access on 3-byte packed struct ARCH: x86_64 marcovanotti15+gcc at gmail dot com
@ 2013-10-16  4:23 ` marcovanotti15+gcc at gmail dot com
  2013-10-23 11:49 ` [Bug target/58744] " rguenth at gcc dot gnu.org
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: marcovanotti15+gcc at gmail dot com @ 2013-10-16  4:23 UTC (permalink / raw)
  To: gcc-bugs

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

Marco Vanotti <marcovanotti15+gcc at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                URL|                            |https://gist.github.com/mva
                   |                            |notti/5a8756d27e77b608518d
                 CC|                            |marcovanotti15+gcc at gmail dot co
                   |                            |m
      Known to fail|                            |4.6.3, 4.7.2, 4.8.1

--- Comment #1 from Marco Vanotti <marcovanotti15+gcc at gmail dot com> ---
This is my first reported bug, please let me know if I left something out or
the description is missing something.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug target/58744] Illegal Memory Access on 3-byte packed struct ARCH: x86_64
  2013-10-16  4:18 [Bug c/58744] New: Illegal Memory Access on 3-byte packed struct ARCH: x86_64 marcovanotti15+gcc at gmail dot com
  2013-10-16  4:23 ` [Bug c/58744] " marcovanotti15+gcc at gmail dot com
@ 2013-10-23 11:49 ` rguenth at gcc dot gnu.org
  2013-10-28 22:32 ` marcovanotti15+gcc at gmail dot com
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: rguenth at gcc dot gnu.org @ 2013-10-23 11:49 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-code
             Target|                            |x86_64-*-*
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2013-10-23
          Component|c                           |target
     Ever confirmed|0                           |1
      Known to fail|                            |4.9.0

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
Confirmed.  On i?86 we properly do a 16byte and a 8byte access (but we copy to
stack anyway).

typedef struct{
    unsigned char B;
    unsigned char G;
    unsigned char R;
} __attribute__((packed)) pixel ;

void apply_filter(pixel p);

void color_filter_c(pixel *src)
{
  apply_filter(*src);
}


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug target/58744] Illegal Memory Access on 3-byte packed struct ARCH: x86_64
  2013-10-16  4:18 [Bug c/58744] New: Illegal Memory Access on 3-byte packed struct ARCH: x86_64 marcovanotti15+gcc at gmail dot com
  2013-10-16  4:23 ` [Bug c/58744] " marcovanotti15+gcc at gmail dot com
  2013-10-23 11:49 ` [Bug target/58744] " rguenth at gcc dot gnu.org
@ 2013-10-28 22:32 ` marcovanotti15+gcc at gmail dot com
  2015-03-14  3:56 ` amodra at gmail dot com
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: marcovanotti15+gcc at gmail dot com @ 2013-10-28 22:32 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Marco Vanotti <marcovanotti15+gcc at gmail dot com> ---
(In reply to Richard Biener from comment #2)
> Confirmed.  On i?86 we properly do a 16byte and a 8byte access (but we copy
> to stack anyway).
>

Yes, if the value is passed on the stack, it gets copied right. (For example,
if it is the seventh parameter of a function, it will be passed on the stack
and will be copied right).

The thing is that in the x86_64 calling convention it has to be passed on
registers while the are available (rdi, rsi, rdx, rcx, r8 and r9).

Reading the source code, precisely the gcc/calls.c file:
http://gcc.gnu.org/viewcvs/gcc/trunk/gcc/calls.c?revision=203967&view=markup

---

The params that are passed on the stack are handled in line 3027, which says:

/* Now store (and compute if necessary) all non-register parms.
These come before register parms, since they can require block-moves,
which could clobber the registers used for register parms.
Parms which have partial registers are not stored here,
but we do preallocate space here if they want that.  */

Assuming that the registers may not require block-moves.

It uses the function "store_one_arg" to store the arg in the stack (it doesn't
work with a non-partial register).

---

After a while, the function "load_register_parameters" (line 1860) is called,
in this function, it falls in the case:

move_block_to_reg (REGNO (reg), mem, nregs, args[i].mode);

where nregs == 1.

So a whole register is copied.

---

I don't know how this issue should be fixed, should we copy the register into
pseudos before the "load_register_parameters" ? Or should we change the
move_block_to_reg function to make the right size of move instructions, for
x86_64 we don't need "backup-registers", but maybe this bug is also in another
arch. 

size 3:

mov di, [rax]
sal rdi, 16
mov dil, [rax]

---

size 5:

mov edi, [rax]
sal rdi, 8
mov dil, [rax]

---

size 6:

mov edi, [rax]
sal rdi, 16
mov di, [rax]

---

size 7:

mov edi, [rax] ;move 4
sal rdi, 24
mov di, [rax]  ;move 3
sal rdi, 16
mov dil, [rax]

-----------------------------

I would gladly submit a patch if I can get some advice on how this should be
fixed :)


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug target/58744] Illegal Memory Access on 3-byte packed struct ARCH: x86_64
  2013-10-16  4:18 [Bug c/58744] New: Illegal Memory Access on 3-byte packed struct ARCH: x86_64 marcovanotti15+gcc at gmail dot com
                   ` (2 preceding siblings ...)
  2013-10-28 22:32 ` marcovanotti15+gcc at gmail dot com
@ 2015-03-14  3:56 ` amodra at gmail dot com
  2015-04-15  7:29 ` amodra at gcc dot gnu.org
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: amodra at gmail dot com @ 2015-03-14  3:56 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58744

Alan Modra <amodra at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
           Assignee|unassigned at gcc dot gnu.org      |amodra at gmail dot com


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug target/58744] Illegal Memory Access on 3-byte packed struct ARCH: x86_64
  2013-10-16  4:18 [Bug c/58744] New: Illegal Memory Access on 3-byte packed struct ARCH: x86_64 marcovanotti15+gcc at gmail dot com
                   ` (3 preceding siblings ...)
  2015-03-14  3:56 ` amodra at gmail dot com
@ 2015-04-15  7:29 ` amodra at gcc dot gnu.org
  2015-04-30 11:12 ` amodra at gcc dot gnu.org
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: amodra at gcc dot gnu.org @ 2015-04-15  7:29 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58744

--- Comment #4 from Alan Modra <amodra at gcc dot gnu.org> ---
Author: amodra
Date: Wed Apr 15 07:29:01 2015
New Revision: 222115

URL: https://gcc.gnu.org/viewcvs?rev=222115&root=gcc&view=rev
Log:
    PR target/65408
    PR target/58744
    PR middle-end/36043
    * calls.c (load_register_parameters): Don't load past end of
    mem unless suitably aligned.


Added:
    trunk/gcc/testsuite/gcc.dg/pr65408.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/calls.c
    trunk/gcc/testsuite/ChangeLog


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug target/58744] Illegal Memory Access on 3-byte packed struct ARCH: x86_64
  2013-10-16  4:18 [Bug c/58744] New: Illegal Memory Access on 3-byte packed struct ARCH: x86_64 marcovanotti15+gcc at gmail dot com
                   ` (4 preceding siblings ...)
  2015-04-15  7:29 ` amodra at gcc dot gnu.org
@ 2015-04-30 11:12 ` amodra at gcc dot gnu.org
  2015-04-30 11:15 ` amodra at gmail dot com
  2015-04-30 11:15 ` amodra at gmail dot com
  7 siblings, 0 replies; 9+ messages in thread
From: amodra at gcc dot gnu.org @ 2015-04-30 11:12 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58744

--- Comment #5 from Alan Modra <amodra at gcc dot gnu.org> ---
Author: amodra
Date: Thu Apr 30 11:11:34 2015
New Revision: 222616

URL: https://gcc.gnu.org/viewcvs?rev=222616&root=gcc&view=rev
Log:
gcc/
        PR target/65408
        PR target/58744
        PR middle-end/36043
        * calls.c (load_register_parameters): Don't load past end of
        mem unless suitably aligned.
gcc/testsuite/
        * gcc.dg/pr65408.c: New.


Added:
    branches/gcc-5-branch/gcc/testsuite/gcc.dg/pr65408.c
Modified:
    branches/gcc-5-branch/gcc/ChangeLog
    branches/gcc-5-branch/gcc/calls.c
    branches/gcc-5-branch/gcc/testsuite/ChangeLog


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug target/58744] Illegal Memory Access on 3-byte packed struct ARCH: x86_64
  2013-10-16  4:18 [Bug c/58744] New: Illegal Memory Access on 3-byte packed struct ARCH: x86_64 marcovanotti15+gcc at gmail dot com
                   ` (5 preceding siblings ...)
  2015-04-30 11:12 ` amodra at gcc dot gnu.org
@ 2015-04-30 11:15 ` amodra at gmail dot com
  2015-04-30 11:15 ` amodra at gmail dot com
  7 siblings, 0 replies; 9+ messages in thread
From: amodra at gmail dot com @ 2015-04-30 11:15 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58744

Alan Modra <amodra at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |RESOLVED
         Resolution|---                         |FIXED
   Target Milestone|---                         |5.2

--- Comment #6 from Alan Modra <amodra at gmail dot com> ---
Fixed for 5.2


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug target/58744] Illegal Memory Access on 3-byte packed struct ARCH: x86_64
  2013-10-16  4:18 [Bug c/58744] New: Illegal Memory Access on 3-byte packed struct ARCH: x86_64 marcovanotti15+gcc at gmail dot com
                   ` (6 preceding siblings ...)
  2015-04-30 11:15 ` amodra at gmail dot com
@ 2015-04-30 11:15 ` amodra at gmail dot com
  7 siblings, 0 replies; 9+ messages in thread
From: amodra at gmail dot com @ 2015-04-30 11:15 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58744
Bug 58744 depends on bug 36043, which changed state.

Bug 36043 Summary: gcc reads 8 bytes for a struct of size 6 which leads to sigsegv
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36043

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |RESOLVED
         Resolution|---                         |FIXED


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2015-04-30 11:15 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-10-16  4:18 [Bug c/58744] New: Illegal Memory Access on 3-byte packed struct ARCH: x86_64 marcovanotti15+gcc at gmail dot com
2013-10-16  4:23 ` [Bug c/58744] " marcovanotti15+gcc at gmail dot com
2013-10-23 11:49 ` [Bug target/58744] " rguenth at gcc dot gnu.org
2013-10-28 22:32 ` marcovanotti15+gcc at gmail dot com
2015-03-14  3:56 ` amodra at gmail dot com
2015-04-15  7:29 ` amodra at gcc dot gnu.org
2015-04-30 11:12 ` amodra at gcc dot gnu.org
2015-04-30 11:15 ` amodra at gmail dot com
2015-04-30 11:15 ` amodra at gmail dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).