https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80759
--- Comment #52 from ro at CeBiTec dot Uni-Bielefeld.DE <ro at CeBiTec dot Uni-Bielefeld.DE> --- > The attached patch (on top of v6) *might* solve the problem on Darwin, but I > don't understand exactly how GOTPCREL works, other than it's using a global > offset table for linking. Hopefully, the linker can translate this directly > into a constant rip-rel offset. What I'm doing here is that instead of > feeding > addresses to the asm template, I'm giving in the offsets and schlepping > together an address operand from that, e.g.: > > lea %p0 + test_data@GOTPCREL(%%rip), %%rax > > Now if this fix *does* work, then I might need to investigate if this is a > performance problem for Darwin -- why use an extra instruction to copy the > address to a register before modifying it? If it doesn't work then it's > probably because it really *needs* two instructions. I'm curious what the > disassembly of the linked program looks like. Unfortunately, the patch doesn't work, apart from the +# define PCREL "@GETPCREL" -> @GOTPCREL typo ;-) At -O0 -g3, it SEGVs at Program received signal SIGSEGV, Segmentation fault. 0x0000000000000000 in ?? () 1: x/i $pc => 0x0: <error: Cannot access memory at address 0x0> (gdb) where #0 0x0000000000000000 in ?? () #1 0x0000000100031c58 in do_test_body0 () at /vol/gcc/src/hg/trunk/solaris/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/ms-sysv.c:178 Backtrace stopped: previous frame inner to this frame (corrupt stack?) where %rip is 0x0. This happens because most of the addresses are off by 0x680 bytes. Here's the disassembly: (gdb) x/12i 0x0000000100031c58-42 0x100031c2e <do_test_body0>: push %rbp 0x100031c2f <do_test_body0+1>: mov %rsp,%rbp 0x100031c32 <do_test_body0>: lea 0x1b407(%rip),%rax # 0x10004d040 0x100031c39 <do_test_body0+7>: callq 0x10003247c <regs_to_mem> 0x100031c3e <do_test_body0+12>: lea 0x1b4db(%rip),%rax # 0x10004d120 <do_tests_0004_noinfo> 0x100031c45 <do_test_body0+19>: callq 0x1000324ea <mem_to_regs> 0x100031c4a <do_test_body0+24>: pop %rax 0x100031c4b <do_test_body0+25>: mov %rax,0x1b696(%rip) # 0x10004d2e8 <buffer.5456+104> 0x100031c52 <do_test_body0+32>: callq *0x1b688(%rip) # 0x10004d2e0 <buffer.5456+96> 0x100031c58 <do_test_body0+38>: mov 0x1bd09(%rip),%rcx # 0x10004d968 <test_data+680> Here are the addresses that are supposed to be used: %p0 (gdb) p/x &test_data.regdata[0] $11 = 0x10004d6c0 %p1 (gdb) p/x &test_data.regdata[1] $12 = 0x10004d7a0 %p4 (gdb) p/x &test_data.retaddr $13 = 0x10004d968 %p3 (gdb) p/x &test_data.fn $14 = 0x10004d960 Only the second use of %p4 is right. Rainer