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

            Bug ID: 81653
           Summary: gcc configured with --enable-default-pie on SPARC
                    miscompiles hand-written .s files
           Product: gcc
           Version: 6.4.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: driver
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bruno at clisp dot org
  Target Milestone: ---

Created attachment 41884
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41884&action=edit
Test case program, part 1

GCC, configured with --enable-default-pie on SPARC, miscompiles hand-written .s
files that happen to access global variables. The cause is that it passes the
option "-K PIC" to the assembler; the assembler then interprets the .s file
differently (by putting different relocations into the .o file). The resulting
executable does not work.

Test case: Find attached main.c and getter.s.

With a GCC not configured with --enable-default-pie:

$ gcc -m32 main.c getter.s
$ ./a.out 
$ echo $?
42

With a GCC configured with --enable-default-pie:

$ gcc -m32 main.c getter.s
$ ./a.out 
Segmentation fault

$ gdb a.out
(gdb) run
Starting program: /home/haible/a.out 

Program received signal SIGSEGV, Segmentation fault.
0x700006c8 in getter ()
(gdb) disassemble getter
Dump of assembler code for function getter:
   0x700006c0 <+0>:     sethi  %hi(0), %g1
   0x700006c4 <+4>:     or  %g1, 0x10, %g1      ! 0x10
=> 0x700006c8 <+8>:     ld  [ %g1 ], %o0
   0x700006cc <+12>:    retl 
   0x700006d0 <+16>:    nop 
End of assembler dump.
(gdb) print $g1
$1 = 16

Details about this GCC version:

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/sparc64-linux-gnu/6/lto-wrapper
Target: sparc64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 6.4.0-2'
--with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs
--enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-6 --program-prefix=sparc64-linux-gnu- --enable-shared
--enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext
--enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/
--enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes
--with-default-libstdcxx-abi=new --enable-gnu-unique-object
--disable-libquadmath --enable-plugin --enable-default-pie --with-system-zlib
--disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo
--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-6-sparc64/jre --enable-java-home
--with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-6-sparc64
--with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-6-sparc64
--with-arch-directory=sparc64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar
--enable-objc-gc=auto --enable-multiarch --enable-targets=all
--with-cpu-32=ultrasparc --with-long-double-128 --enable-multilib
--enable-checking=release --build=sparc64-linux-gnu --host=sparc64-linux-gnu
--target=sparc64-linux-gnu
Thread model: posix
gcc version 6.4.0 20170724 (Debian 6.4.0-2) 

Analysis of the difference between that and this GCC:

1) The "as" invocation was
as -v -s -Av9a -32 -relax -o /tmp/cci9hbn2.o getter.s
and in this GCC version is
as -v -s -K PIC -Av9a -32 -relax -o /tmp/ccYeBhLa.o getter.s

2) The relocations in the object file:

That GCC:

$ gcc -m32 -c getter.s -o getter.o
$ objdump --disassemble --reloc getter.o

getter.o:     file format elf32-sparc


Disassembly of section .text:

00000000 <getter>:
   0:   03 00 00 00     sethi  %hi(0), %g1
                        0: R_SPARC_HI22 variable
   4:   82 10 60 00     mov  %g1, %g1   ! 0 <getter>
                        4: R_SPARC_LO10 variable
   8:   d0 00 40 00     ld  [ %g1 ], %o0
   c:   81 c3 e0 08     retl 
  10:   01 00 00 00     nop 

This GCC:

$ gcc -m32 -c getter.s -o getter.o
$ objdump --disassemble --reloc getter.o

getter.o:     file format elf32-sparc


Disassembly of section .text:

00000000 <getter>:
   0:   03 00 00 00     sethi  %hi(0), %g1
                        0: R_SPARC_GOT22        variable
   4:   82 10 60 00     mov  %g1, %g1   ! 0 <getter>
                        4: R_SPARC_GOT10        variable
   8:   d0 00 40 00     ld  [ %g1 ], %o0
   c:   81 c3 e0 08     retl 
  10:   01 00 00 00     nop 

As you can see, the assembler has inserted different relocations with "-K PIC"
than without.

3) The instructions in the linked a.out file:

That GCC:

$ objdump --disassemble a.out
00010480 <main>:
   10480:       9d e3 bf a0     save  %sp, -96, %sp
   10484:       03 00 00 88     sethi  %hi(0x22000), %g1
   10488:       82 10 60 68     or  %g1, 0x68, %g1      ! 22068 <variable>
   1048c:       84 10 20 2a     mov  0x2a, %g2
   10490:       c4 20 40 00     st  %g2, [ %g1 ]
   10494:       40 00 00 06     call  104ac <getter>
   10498:       01 00 00 00     nop 
   1049c:       82 10 00 08     mov  %o0, %g1
   104a0:       b0 10 00 01     mov  %g1, %i0
   104a4:       81 cf e0 08     rett  %i7 + 8
   104a8:       01 00 00 00     nop 

000104ac <getter>:
   104ac:       03 00 00 88     sethi  %hi(0x22000), %g1
   104b0:       82 10 60 68     or  %g1, 0x68, %g1      ! 22068 <variable>
   104b4:       d0 00 40 00     ld  [ %g1 ], %o0
   104b8:       81 c3 e0 08     retl 
   104bc:       01 00 00 00     nop 

This GCC:

$ objdump --disassemble a.out
00000680 <main>:
 680:   9d e3 bf a0     save  %sp, -96, %sp
 684:   2f 00 00 46     sethi  %hi(0x11800), %l7
 688:   ae 05 e1 74     add  %l7, 0x174, %l7    ! 11974 <__FRAME_END__+0x111e4>
 68c:   7f ff ff 85     call  4a0 <__sparc_get_pc_thunk.l7>
 690:   01 00 00 00     nop 
 694:   03 00 00 00     sethi  %hi(0), %g1
 698:   82 18 60 9c     xor  %g1, 0x9c, %g1
 69c:   82 05 c0 01     add  %l7, %g1, %g1
 6a0:   84 10 20 2a     mov  0x2a, %g2
 6a4:   c4 20 40 00     st  %g2, [ %g1 ]
 6a8:   40 00 00 06     call  6c0 <getter>
 6ac:   01 00 00 00     nop 
 6b0:   82 10 00 08     mov  %o0, %g1
 6b4:   b0 10 00 01     mov  %g1, %i0
 6b8:   81 cf e0 08     return  %i7 + 8
 6bc:   01 00 00 00     nop 

000006c0 <getter>:
 6c0:   03 00 00 00     sethi  %hi(0), %g1
 6c4:   82 10 60 10     or  %g1, 0x10, %g1      ! 10 <_init-0x3e4>
 6c8:   d0 00 40 00     ld  [ %g1 ], %o0
 6cc:   81 c3 e0 08     retl 
 6d0:   01 00 00 00     nop 
 6d4:   01 00 00 00     nop 
 6d8:   01 00 00 00     nop 
 6dc:   01 00 00 00     nop 

You can see the effect: The 'getter' function no longer references 'variable'.

Reply via email to