public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug inline-asm/56621] New: Misaligned stack with inline assembly
@ 2013-03-14 18:32 auc42 at yahoo dot com
  2013-03-14 18:58 ` [Bug inline-asm/56621] " jakub at gcc dot gnu.org
  2013-03-14 20:01 ` auc42 at yahoo dot com
  0 siblings, 2 replies; 3+ messages in thread
From: auc42 at yahoo dot com @ 2013-03-14 18:32 UTC (permalink / raw)
  To: gcc-bugs


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

             Bug #: 56621
           Summary: Misaligned stack with inline assembly
    Classification: Unclassified
           Product: gcc
           Version: 4.7.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: inline-asm
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: auc42@yahoo.com


The following minimal program (compiled merely by "gcc test.c -o test") is
intended to write "test" to standard output using the write system call, and
then exit:

int main() {
    int tmp;
    char message[8] = "test\n";
    int message_size = 5;

    // Comment out this loop and it suddenly works correctly.
    for (tmp = 0; tmp < 1; ++tmp) { }

    __asm__ __volatile__
    (
        "movq $1, %%rax;"       // System call 1 (write)
        "movq $1, %%rdi;"       // File descriptor 1 (stdout)
        "movq %0, %%rsi;"       // %0 is message
        "movq %1, %%rdx;"       // %1 is message_size
        "syscall"
        :
        : "q"(message), "g"(message_size)
        : "%rax", "%rdi", "%rsi", "%rdx", "%rcx", "%r11"
    );

    return(0);
}

This version produces no output, and exits immediately.  If the marked "for"
loop is commented out, the program *does* produce the expected output. 
(Obviously, the original version where I discovered this problem had a loop
that did actual work).

Examining the binary via objdump (or the intermediate test.s file when
preserving temporary files), I find that it uses an instruction of "movq
-8(%rbp), %rdx" in the non-working version, as compared to "movq -4(%rbp,
%rdx)" in the working version.  Similarly, the initial assignment is done by an
offset of -8 or -4 in the stack, respectively.  If I directly edit the binary
file to change the instruction to the correct offset, the non-working version
then starts working as expected.

This problem is present in the default Debian "wheezy" gcc version 4.7.2
(output of gcc -v below); it is also present in the latest development version
as of the time of this bug report, which I downloaded and compiled in order to
test the problem.  The bug is *not* present in the Debian "squeeze" version
4.4.5 of gcc, so I can only conclude that this became an issue somewhere in an
intervening version.

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.7.2-5'
--with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs
--enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-4.7 --enable-shared --enable-linker-build-id
--with-system-zlib --libexecdir=/usr/lib --without-included-gettext
--enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7
--libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu
--enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object
--enable-plugin --enable-objc-gc --with-arch-32=i586 --with-tune=generic
--enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu
--target=x86_64-linux-gnu
Thread model: posix
gcc version 4.7.2 (Debian 4.7.2-5)


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

* [Bug inline-asm/56621] Misaligned stack with inline assembly
  2013-03-14 18:32 [Bug inline-asm/56621] New: Misaligned stack with inline assembly auc42 at yahoo dot com
@ 2013-03-14 18:58 ` jakub at gcc dot gnu.org
  2013-03-14 20:01 ` auc42 at yahoo dot com
  1 sibling, 0 replies; 3+ messages in thread
From: jakub at gcc dot gnu.org @ 2013-03-14 18:58 UTC (permalink / raw)
  To: gcc-bugs


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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
                 CC|                            |jakub at gcc dot gnu.org
         Resolution|                            |INVALID

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> 2013-03-14 18:58:12 UTC ---
No, that is just bogus inline asm, for multiple reasons.
message_size is 32-bit, so using movq on it means you can end up with arbitrary
garbage in the high 32-bits.  E.g. I see:
write(1,
"test\n\0\0\0\5\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0005\27\202\351?\0\0\0"...,
4294967301) = -1 EFAULT (Bad address)
where 4294967301 is 0x100000005.  You'd want movl instead, which will zero the
upper 32 bits.
Also, nothing tells the compiler that the clobbered registers are clobbered
before consuming the inputs, the compiler could assign one of the two inputs to
the clobbered registers.  Better just use long dummy; int dummy2; ... "=S"
(dummy), "=d" (dummy2) ... : "0" (message), "1" (message_size) ...
then you don't need to do any of the bogus moves first, the compiler will
arrange all of that.  Or why aren't you just using syscall function, or write?


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

* [Bug inline-asm/56621] Misaligned stack with inline assembly
  2013-03-14 18:32 [Bug inline-asm/56621] New: Misaligned stack with inline assembly auc42 at yahoo dot com
  2013-03-14 18:58 ` [Bug inline-asm/56621] " jakub at gcc dot gnu.org
@ 2013-03-14 20:01 ` auc42 at yahoo dot com
  1 sibling, 0 replies; 3+ messages in thread
From: auc42 at yahoo dot com @ 2013-03-14 20:01 UTC (permalink / raw)
  To: gcc-bugs


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

--- Comment #2 from auc42 at yahoo dot com 2013-03-14 20:00:56 UTC ---
Ah, I had forgotten to change "tmp" back to a long in the code snippet
provided.  I was experimenting to see variations of the generated assembly
while using different types.  The failure is present with both the 8-byte long
and 4-byte int, in this case.

I accept your explanation about the clobbered registers, though.  I apparently
misunderstood how clobber declarations worked (and in re-reading the manual,
either I'm still missing something or the text isn't very clear).  Placing the
variables directly in the S and d registers and skipping the movX instructions
eliminates the problem.  I suppose that the sequence only worked by
happenstance in earlier versions of gcc.

(As for the reason of doing it this way: the original code was avoiding use of
the C standard library and/or any include files, as a personal learning
exercise toward a later program.)


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

end of thread, other threads:[~2013-03-14 20:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-14 18:32 [Bug inline-asm/56621] New: Misaligned stack with inline assembly auc42 at yahoo dot com
2013-03-14 18:58 ` [Bug inline-asm/56621] " jakub at gcc dot gnu.org
2013-03-14 20:01 ` auc42 at yahoo 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).