This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/50678] [4.7 Regression] FAIL: c52104y on x86_64-apple-darwin10
- From: "ebotcazou at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 17 Oct 2011 15:36:11 +0000
- Subject: [Bug target/50678] [4.7 Regression] FAIL: c52104y on x86_64-apple-darwin10
- Auto-submitted: auto-generated
- References: <bug-50678-4@http.gcc.gnu.org/bugzilla/>
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50678
--- Comment #35 from Eric Botcazou <ebotcazou at gcc dot gnu.org> 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, <signal handler called>
(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.