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