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