Hi,

I get a piece of code to be compiled by gcc with the combined '-Os
-mregparm=3' options to generate the x86 32-bit codes, and I found gcc
created broken codes.

The test codes that can be used to trigger this issue: (save the
following to test.c.)

typedef struct {
     int     a;
     int     b;
} TEST_INFO;

typedef struct {
     int     a;
} PCALL_PARAM;

typedef int (*PCALL)(PCALL_PARAM *);

extern TEST_INFO * dont_care(void);

#undef WORKAROUND

int test (TEST_INFO *info, int d)
{
     PCALL          pcall;
     PCALL_PARAM     params;
     PCALL_PARAM     *params_ptr;
     int          status;
     TEST_INFO     *r;

     if (!info) {
          r = (TEST_INFO *)dont_care();
     } else {
          r = info;
     }

     pcall = (PCALL)(r->a + r->b);
     params.a = d;
#ifdef WORKAROUND
     status = pcall (&params);
#endif
     params_ptr = &params;

     asm volatile (
     "pushl      %1;"
     "call       *%%eax;"
     "addl       $4, %%esp;"
     : "=a"(status) : "m"(params_ptr), "a"(pcall)
     );

     return status;
}

The gcc command I am using to compile the file:

$ gcc -v -Os -mregparm=3 -march=i386 -m32 -c -o test.o test.c
Using built-in specs.
COLLECT_GCC=gcc
Target: x86_64-CentOS-linux
Configured with: ../configure
--prefix=/opt/centos/devtoolset-1.1/root/usr
--mandir=/opt/centos/devtoolset-1.1/root/usr/share/man
--infodir=/opt/centos/devtoolset-1.1/root/usr/share/info
--with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap
--enable-shared --enable-threads=posix --enable-checking=release
--disable-build-with-cxx --disable-build-poststage1-with-cxx
--with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --disable-gnu-unique-object
--enable-linker-build-id --enable-languages=c,c++,fortran,lto
--enable-plugin --with-linker-hash-style=gnu --enable-initfini-array
--disable-libgcj
--with-gmp=/home/centos/rpm/BUILD/gcc-4.7.2-20121015/obj-x86_64-CentOS-linux/gmp-install
--with-mpfr=/home/centos/rpm/BUILD/gcc-4.7.2-20121015/obj-x86_64-CentOS-linux/mpfr-install
--with-ppl=/home/centos/rpm/BUILD/gcc-4.7.2-20121015/obj-x86_64-CentOS-linux/ppl-install
--with-cloog=/home/centos/rpm/BUILD/gcc-4.7.2-20121015/obj-x86_64-CentOS-linux/cloog-install
--with-mpc=/home/centos/rpm/BUILD/gcc-4.7.2-20121015/obj-x86_64-CentOS-linux/mpc-install
--with-tune=generic --with-arch_32=i586 --build=x86_64-CentOS-linux
Thread model: posix
gcc version 4.7.2 20121015 (Red Hat 4.7.2-5) (GCC)
COLLECT_GCC_OPTIONS='-v' '-Os' '-mregparm=3' '-march=i386' '-m32' '-c'
'-o' 'test.o'
 /opt/centos/devtoolset-1.1/root/usr/libexec/gcc/x86_64-CentOS-linux/4.7.2/cc1
-quiet -v -imultilib 32 test.c -quiet -dumpbase test.c -mregparm=3
-march=i386 -m32 -auxbase-strip test.o -Os -version -o /tmp/ccrfMdFf.s
GNU C (GCC) version 4.7.2 20121015 (Red Hat 4.7.2-5) (x86_64-CentOS-linux)
        compiled by GNU C version 4.7.2 20121015 (Red Hat 4.7.2-5),
GMP version 4.3.1, MPFR version 2.4.1, MPC version 0.8.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory
"/opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-CentOS-linux/4.7.2/include-fixed"
ignoring nonexistent directory
"/opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-CentOS-linux/4.7.2/../../../../x86_64-CentOS-linux/include"
#include "..." search starts here:
#include <...> search starts here:
 /opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-CentOS-linux/4.7.2/include
 /usr/local/include
 /opt/centos/devtoolset-1.1/root/usr/include
 /usr/include
End of search list.
GNU C (GCC) version 4.7.2 20121015 (Red Hat 4.7.2-5) (x86_64-CentOS-linux)
        compiled by GNU C version 4.7.2 20121015 (Red Hat 4.7.2-5),
GMP version 4.3.1, MPFR version 2.4.1, MPC version 0.8.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 08198519a1e798dc5da060bad8011478
COLLECT_GCC_OPTIONS='-v' '-Os' '-mregparm=3' '-march=i386' '-m32' '-c'
'-o' 'test.o'
 /opt/centos/devtoolset-1.1/root/usr/libexec/gcc/x86_64-CentOS-linux/4.7.2/as
-v --32 -o test.o /tmp/ccrfMdFf.s
GNU assembler version 2.23.51.0.3 (x86_64-CentOS-linux) using BFD
version version 2.23.51.0.3-3.el5 20120918
COMPILER_PATH=/opt/centos/devtoolset-1.1/root/usr/libexec/gcc/x86_64-CentOS-linux/4.7.2/:/opt/centos/devtoolset-1.1/root/usr/libexec/gcc/x86_64-CentOS-linux/4.7.2/:/opt/centos/devtoolset-1.1/root/usr/libexec/gcc/x86_64-CentOS-linux/:/opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-CentOS-linux/4.7.2/:/opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-CentOS-linux/
LIBRARY_PATH=/opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-CentOS-linux/4.7.2/32/:/opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-CentOS-linux/4.7.2/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-CentOS-linux/4.7.2/:/opt/centos/devtoolset-1.1/root/usr/lib/gcc/x86_64-CentOS-linux/4.7.2/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-Os' '-mregparm=3' '-march=i386' '-m32' '-c'
'-o' 'test.o'

Using objdump to disassemble the test.o
$ objdump -D test.o > asm.txt

And the generated codes are:

00000000 <test>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 ec 18                sub    $0x18,%esp
   6:   85 c0                   test   %eax,%eax
   8:   75 05                   jne    f <test+0xf>
   a:   e8 fc ff ff ff          call   b <test+0xb>
   f:   8b 10                   mov    (%eax),%edx
  11:   03 50 04                add    0x4(%eax),%edx
  14:   8d 45 f0                lea    -0x10(%ebp),%eax
  17:   89 45 f4                mov    %eax,-0xc(%ebp)
  1a:   89 d0                   mov    %edx,%eax
  1c:   ff 75 f4                pushl  -0xc(%ebp)
  1f:   ff d0                   call   *%eax
  21:   83 c4 04                add    $0x4,%esp
  24:   c9                      leave
  25:   c3                      ret

See the edx gets overwritten at address 0xf 'mov    (%eax),%edx' while
edx holds the 2nd parameter of function test when given option
'-mregparm=3'.

I believe this is a bug. Could someone confirm this? Thanks,

Regards,
Bin

Reply via email to