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

            Bug ID: 67183
           Summary: Darwin stub vs. non_lazy pointer ordering incompatible
                    with clang assembler.
           Product: gcc
           Version: 5.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jay.krell at cornell dot edu
  Target Milestone: ---

Darwin stub vs. non_lazy pointer ordering incompatible with clang assembler.
Incorrect code results when targeting 32bit older than 10.5.
Request to output in the same order as clang for compatibility -- all stubs
before all non-lazy pointers.


This is really obscure.


It did hit me and I spent a long while debugging it, though still not fully.


There appears to be a bug in the LLVM assembler.


gcc by default does not run it.
 i.e.:
   gcc -S foo.c
   clang foo.s
  usually works, but hits a problem here. 


It probably only occurs when targeting less than 10.5.
 i.e. gcc -mmacosx-version-min=10.4
 That switch works with both gcc and clang. 


 gcc outputs a presumably valid mix of stubs and non-lazy pointers.
  You only get the stubs for earlier than 10.5.


clang front end outputs all stubs before all the non-lazy pointers.
gcc outputs them in a jumbled order. Presumably that is ok.
The clang assembler gets confused matching things up when there are non-lazy
pointers before stubs. 


The bug is also 32bit specific as 64bit never has stubs.


Here is the bug in action:  

  jair:~ jay$ cat 1.c  
  void F1(int);  
  void F2(int);  
  extern int i;  

  void F3() { F1(i); }  
  void F4() { F2(i); }  
  jair:~ jay$ $HOME/gcc-5.2.0/bin/gcc -mmacosx-version-min=10.4 -m32 1.c -fPIC 
-c -S  
  jair:~ jay$ clang -c 1.s -m32  
  jair:~ jay$ otool -tVv 1.o  
  1.o:  
  (__TEXT,__text) section  
  _F3:
  00000000      pushl   %ebp
  00000001      movl    %esp, %ebp
  00000003      subl    $0x8, %esp
  00000006      calll   ___x86.get_pc_thunk.ax
  0000000b      leal    86-11(%eax), %eax
  00000011      movl    _F3(%eax), %eax
  00000013      movl    _F3(%eax), %eax  
  00000015      subl    $0xc, %esp  
  00000018      pushl   %eax  
  00000019      calll   0x4c                    ## symbol stub for: _F1  
  0000001e      addl    $0x10, %esp  
  00000021      nop  
  00000022      leave  
  00000023      retl  
  _F4:  
  00000024      pushl   %ebp  
  00000025      movl    %esp, %ebp  
  00000027      subl    $0x8, %esp  
  0000002a      calll   ___x86.get_pc_thunk.ax  
  0000002f      leal    86-47(%eax), %eax  
  00000035      movl    _F3(%eax), %eax  
  00000037      movl    _F3(%eax), %eax  
  00000039      subl    $0xc, %esp  
  0000003c      pushl   %eax  
  0000003d      calll   0x51                    ## symbol stub for: _i  
  00000042      addl    $0x10, %esp  
  00000045      nop  
  00000046      leave  
  00000047      retl  


  Where is says "symbol stub for: _i", it should for _F2.  


  Having gcc output the stubs/non-lazy pointers in the same order as clang  
  in order to be compatible with the clang assembler might be nice.  


  For my part, I will either run non-LLVM assembler, or target 10.5 or newer,  
  at least until I develop or get a patch for gcc to reorder.  


  Thank you,
 - Jay

Reply via email to