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).