From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15983 invoked by alias); 17 Oct 2011 15:38:59 -0000 Received: (qmail 15776 invoked by uid 22791); 17 Oct 2011 15:38:57 -0000 X-SWARE-Spam-Status: No, hits=-2.9 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from localhost (HELO gcc.gnu.org) (127.0.0.1) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 17 Oct 2011 15:38:43 +0000 From: "ebotcazou at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug target/50678] [4.7 Regression] FAIL: c52104y on x86_64-apple-darwin10 Date: Mon, 17 Oct 2011 15:38:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: target X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: ebotcazou at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Priority: P4 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: 4.7.0 X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated Content-Type: text/plain; charset="UTF-8" MIME-Version: 1.0 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2011-10/txt/msg01637.txt.bz2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50678 --- Comment #35 from Eric Botcazou 2011-10-17 15:36:11 UTC --- > 1. the code for the D10 libSystem unwind library is available from here: > http://www.opensource.apple.com/tarballs/libunwind/ Thanks for the pointer. > 2. Looking at a build of this, the order of the assignments (R newRegisters = > register) seems generally scrambled when the getCFA function is inlined. This > is reproducible with the vendor's tools and the source in 1 at optimization > levels > 0 and not Os. > > 3. The scrambling is consistent (in and out) - and I'm not 100% sure about > whether this is the fault... ISTM that so long as the re-ordering is local > (and consistent) to optimized code, it could be harmless. It wasn't so much the order of assignments as the difference in the offsets between the contexts. But, you're right, this isn't the problem as the local variable newRegisters is very likely scalarized, so the final offsets are entirely meaningless. In any case, the problem is elsewhere, namely in the unwind info for the _sigtramp function of the libc: (gdb) b *0x00007fff85b9b1b8 Breakpoint 1 at 0x7fff85b9b1b8 (gdb) run Starting program: /nfs/nas/homes/botcazou/c52104y_0 C52104Y CHECK THAT IN ARRAY ASSIGNMENTS AND IN SLICE ASSIGNMENTS, THE LENGTHS MUST MATCH. - C52104Y NO CONSTRAINT_ERROR FOR NON-NULL ARRAY SUBTYPE WHEN ONE DIMENSION HAS INTEGER'LAST + 3 COMPONENTS. Program received signal SIGSEGV, Segmentation fault. 0x0000000100002428 in c52104y_0 () (gdb) continue Continuing. Breakpoint 1, (gdb) disass Dump of assembler code for function _sigtramp: 0x00007fff85b9b1a0 <+0>: push %rbp 0x00007fff85b9b1a1 <+1>: mov %rsp,%rbp 0x00007fff85b9b1a4 <+4>: mov %rdi,%rax 0x00007fff85b9b1a7 <+7>: incl -0x15261b75(%rip) # 0x7fff70939638 0x00007fff85b9b1ad <+13>: mov %r8,%rbx 0x00007fff85b9b1b0 <+16>: mov %edx,%edi 0x00007fff85b9b1b2 <+18>: mov %rcx,%rsi 0x00007fff85b9b1b5 <+21>: mov %r8,%rdx => 0x00007fff85b9b1b8 <+24>: callq *%rax 0x00007fff85b9b1ba <+26>: decl -0x15261b88(%rip) # 0x7fff70939638 0x00007fff85b9b1c0 <+32>: mov %rbx,%rdi 0x00007fff85b9b1c3 <+35>: mov $0x1e,%esi 0x00007fff85b9b1c8 <+40>: jmpq 0x7fff85b9b1d0 <__sigreturn> 0x00007fff85b9b1cd <+45>: nop 0x00007fff85b9b1ce <+46>: nop 0x00007fff85b9b1cf <+47>: nop End of assembler dump. The CFI of the unwind info for _sigtramp is at this address: (gdb) x/167bx 0x00007fff85ccff59 0x7fff85ccff59: 0x10 0x00 0x05 0x73 0x30 0x06 0x23 0x10 0x7fff85ccff61: 0x10 0x01 0x05 0x73 0x30 0x06 0x23 0x18 0x7fff85ccff69: 0x10 0x02 0x05 0x73 0x30 0x06 0x23 0x20 0x7fff85ccff71: 0x10 0x03 0x05 0x73 0x30 0x06 0x23 0x28 0x7fff85ccff79: 0x10 0x04 0x05 0x73 0x30 0x06 0x23 0x38 0x7fff85ccff81: 0x10 0x05 0x05 0x73 0x30 0x06 0x23 0x30 0x7fff85ccff89: 0x10 0x06 0x05 0x73 0x30 0x06 0x23 0x40 0x7fff85ccff91: 0x10 0x07 0x05 0x73 0x30 0x06 0x23 0x48 0x7fff85ccff99: 0x10 0x08 0x05 0x73 0x30 0x06 0x23 0x50 0x7fff85ccffa1: 0x10 0x09 0x05 0x73 0x30 0x06 0x23 0x58 0x7fff85ccffa9: 0x10 0x0a 0x05 0x73 0x30 0x06 0x23 0x60 0x7fff85ccffb1: 0x10 0x0b 0x05 0x73 0x30 0x06 0x23 0x68 0x7fff85ccffb9: 0x10 0x0c 0x05 0x73 0x30 0x06 0x23 0x70 0x7fff85ccffc1: 0x10 0x0d 0x05 0x73 0x30 0x06 0x23 0x78 0x7fff85ccffc9: 0x10 0x0e 0x06 0x73 0x30 0x06 0x23 0x80 DW_CFA_expression reg_num len DW_OP_breg3 off deref DW_OP_plus_uconst offset So, for example, register 1 is at offset 0x18 of the deref of (%rdx + 0x30): (gdb) x/gx ($rdx + 0x30) 0x100038958: 0x00000001000384bc (gdb) x/gx 0x00000001000384bc + 0x18 0x1000384d4: 0x00007fff5fbff910 And register 3 is at offset 0x18 of the deref of (%rdx + 0x30): (gdb) x/gx 0x00000001000384bc + 0x28 0x1000384e4: 0x0000000010000000 The former is the saved %rbx and the latter is the saved %rdx. The problem is that they are numbered differently by libunwind.h: // 64-bit x86_64 registers enum { UNW_X86_64_RAX = 0, UNW_X86_64_RDX = 1, UNW_X86_64_RCX = 2, UNW_X86_64_RBX = 3, UNW_X86_64_RSI = 4, UNW_X86_64_RDI = 5, UNW_X86_64_RBP = 6, UNW_X86_64_RSP = 7, UNW_X86_64_R8 = 8, UNW_X86_64_R9 = 9, UNW_X86_64_R10 = 10, UNW_X86_64_R11 = 11, UNW_X86_64_R12 = 12, UNW_X86_64_R13 = 13, UNW_X86_64_R14 = 14, UNW_X86_64_R15 = 15 }; so %rbx is register 3 and %rdx is register 1 for libunwind. Therefore, if you swap the saved values, the program works fine: (gdb) set { unsigned long } 0x1000384d4 = 0x0000000010000000 (gdb) set { unsigned long } 0x1000384e4 = 0x00007fff5fbff910 (gdb) continue Continuing. - C52104Y STORAGE_ERROR RAISED WHEN DECLARING ONE PACKED BOOLEAN ARRAY WITH INTEGER'LAST + 3 COMPONENTS. ==== C52104Y PASSED ============================. The unwind info for _sigtramp is in i386/sys/_sigtramp.s for i386: /* Now for the expressions, which all compute uctx->uc_mcontext->register for each register. Describe even the registers that are not call-saved because they might be being used in the prologue to save other registers. Only integer registers are described at present. */ loc_expr_for_reg (0, MCONTEXT_SS_EAX) loc_expr_for_reg (1, MCONTEXT_SS_ECX) loc_expr_for_reg (2, MCONTEXT_SS_EDX) loc_expr_for_reg (3, MCONTEXT_SS_EBX) loc_expr_for_reg (4, MCONTEXT_SS_EBP) # note that GCC switches loc_expr_for_reg (5, MCONTEXT_SS_ESP) # DWARF registers 4 & 5 loc_expr_for_reg (6, MCONTEXT_SS_ESI) loc_expr_for_reg (7, MCONTEXT_SS_EDI) loc_expr_for_reg (9, MCONTEXT_SS_EFLAGS) It is in keeping with libunwind.h: // 32-bit x86 registers enum { UNW_X86_EAX = 0, UNW_X86_ECX = 1, UNW_X86_EDX = 2, UNW_X86_EBX = 3, UNW_X86_EBP = 4, UNW_X86_ESP = 5, UNW_X86_ESI = 6, UNW_X86_EDI = 7 }; The unwind info for _sigtramp is in x86_64/sys/_sigtramp.s for x86-64: /* Now for the expressions, which all compute uctx->uc_mcontext->register for each register. Describe even the registers that are not call-saved because they might be being used in the prologue to save other registers. Only integer registers are described at present. */ loc_expr_for_reg (0, MCONTEXT_SS_RAX) loc_expr_for_reg (1, MCONTEXT_SS_RBX) loc_expr_for_reg (2, MCONTEXT_SS_RCX) loc_expr_for_reg (3, MCONTEXT_SS_RDX) loc_expr_for_reg (4, MCONTEXT_SS_RSI) loc_expr_for_reg (5, MCONTEXT_SS_RDI) loc_expr_for_reg (6, MCONTEXT_SS_RBP) loc_expr_for_reg (7, MCONTEXT_SS_RSP) loc_expr_rN (8) loc_expr_rN (9) loc_expr_rN (10) loc_expr_rN (11) loc_expr_rN (12) loc_expr_rN (13) loc_expr_rN_long (14) loc_expr_rN_long (15) and it is _not_ in keeping with libunwind.h: // 64-bit x86_64 registers enum { UNW_X86_64_RAX = 0, UNW_X86_64_RDX = 1, UNW_X86_64_RCX = 2, UNW_X86_64_RBX = 3, UNW_X86_64_RSI = 4, UNW_X86_64_RDI = 5, UNW_X86_64_RBP = 6, UNW_X86_64_RSP = 7, UNW_X86_64_R8 = 8, UNW_X86_64_R9 = 9, UNW_X86_64_R10 = 10, UNW_X86_64_R11 = 11, UNW_X86_64_R12 = 12, UNW_X86_64_R13 = 13, UNW_X86_64_R14 = 14, UNW_X86_64_R15 = 15 }; The discrepancy in the x86-64 case is the bug. This should be reported to Apple and probably fixed in the libc. In the meantime, we can work around it in ada/init.c/__gnat_error_handler: static void __gnat_error_handler (int sig, siginfo_t *si, void *ucontext ATTRIBUTE_UNUSED) { by patching up the context reachable through the ucontext argument. According to the comment in the libc file, it is at ucontext->uc_mcontext.