Re: Support Solaris 11/SPARC in MD_FALLBACK_FRAME_STATE_FOR (PR ada/41929)
Unfortunately, this version completely breaks Solaris 11. Given that your primary (only?) justification for this patch seems to be a 7-year old Beta version of Solaris 10 (s10_72) nobody in his right mind should be running right now, I suggest simply reverting this patch. I think that we shoudn't have changed the pattern matching code in the first place, as it had gradually evolved over almost an entire decade. It was quite robust as a consequence and the new code is clearly inferior in this respect. Usually adapting it to a new version of the OS only takes a handful of minutes. Would you mind having a quick look? I don't have access to Solaris 11 myself. -- Eric Botcazou
Re: Support Solaris 11/SPARC in MD_FALLBACK_FRAME_STATE_FOR (PR ada/41929)
Eric Botcazou ebotca...@adacore.com writes: Unfortunately, this version completely breaks Solaris 11. Given that your primary (only?) justification for this patch seems to be a 7-year old Beta version of Solaris 10 (s10_72) nobody in his right mind should be running right now, I suggest simply reverting this patch. I think that we shoudn't have changed the pattern matching code in the first place, as it had gradually evolved over almost an entire decade. It was quite robust as a consequence and the new code is clearly inferior in this respect. Usually adapting it to a new version of the OS only takes a handful of minutes. That's not my experience in the first place: when I tried to get it working on Solaris 11, I failed so completely that I decided to instead follow the route already trodden by the Solaris/x86 file. Would you mind having a quick look? I don't have access to Solaris 11 myself. I doubt I'll have the time: there's quite a lot on my plate before 4.7.0 and I don't have that much time left for gcc issues these days. Again: what's the justification for changing this code so late in the game when it has been like this since 4.6.0 with no issues? I don't buy it that support for s10_72 (a 7-year old Solaris 10 Beta) is enough to break Solaris 11 (the current shipping release). Rainer -- - Rainer Orth, Center for Biotechnology, Bielefeld University
Re: Support Solaris 11/SPARC in MD_FALLBACK_FRAME_STATE_FOR (PR ada/41929)
Eric Botcazou ebotca...@adacore.com writes: All EH-related tests fail with a recent upgrade on Solaris 10. Interestingly, the old implementation keeps working with the upgrade. I've applied the attached patch to mainline and 4.6 branch. It reverts back to the old pattern matching code in the Solaris 8+ multi-threaded case, which is clearly more robust. The rest is left unchanged. Tested on 5 different OS versions (Solaris 8, Solaris 8 Containers, Solaris 9, old Solaris 10, recent Solaris 10). Unfortunately, this version completely breaks Solaris 11. Given that your primary (only?) justification for this patch seems to be a 7-year old Beta version of Solaris 10 (s10_72) nobody in his right mind should be running right now, I suggest simply reverting this patch. Rainer -- - Rainer Orth, Center for Biotechnology, Bielefeld University
Re: Support Solaris 11/SPARC in MD_FALLBACK_FRAME_STATE_FOR (PR ada/41929)
All EH-related tests fail with a recent upgrade on Solaris 10. Interestingly, the old implementation keeps working with the upgrade. I've applied the attached patch to mainline and 4.6 branch. It reverts back to the old pattern matching code in the Solaris 8+ multi-threaded case, which is clearly more robust. The rest is left unchanged. Tested on 5 different OS versions (Solaris 8, Solaris 8 Containers, Solaris 9, old Solaris 10, recent Solaris 10). 2012-01-09 Eric Botcazou ebotca...@adacore.com PR ada/41929 * config/sparc/sol2-unwind.h (sparc64_is_sighandler): Remove SAVPC and add CFA. Revert back to old code for Solaris 8+ multi-threaded. (sparc_is_sighandler): Likewise. (MD_FALLBACK_FRAME_STATE_FOR): Adjust call to IS_SIGHANDLER. -- Eric Botcazou Index: config/sparc/sol2-unwind.h === --- config/sparc/sol2-unwind.h (revision 183001) +++ config/sparc/sol2-unwind.h (working copy) @@ -1,5 +1,5 @@ /* DWARF2 EH unwinding support for SPARC Solaris. - Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This file is part of GCC. @@ -34,7 +34,7 @@ see the files COPYING3 and COPYING.RUNTI #define IS_SIGHANDLER sparc64_is_sighandler static int -sparc64_is_sighandler (unsigned int *pc, unsigned int *savpc, int *nframes) +sparc64_is_sighandler (unsigned int *pc, void *cfa, int *nframes) { if (/* Solaris 8 - single-threaded @@ -110,38 +110,59 @@ sparc64_is_sighandler (unsigned int *pc, pc[ 0] == 0x81c7e008 pc[ 1] == 0x81e8) { - if (/* Solaris 8 /usr/lib/sparcv9/libthread.so.1 - -- - Before patch 108827-08: - sigacthandler+1760: st %g4, [ %i1 + 0x1c ] - - Since patch 108827-08: - sigacthandler+1816: st %l0, [ %i4 + 0x10 ] */ - savpc[-1] == 0xc826601c - || savpc[-1] == 0xe0272010) + /* We have observed different calling frames among different + versions of the operating system, so that we need to + discriminate using the upper frame. We look for the return + address of the caller frame (there is an offset of 15 double + words between the frame address and the place where this return + address is stored) in order to do some more pattern matching. */ + unsigned int cuh_pattern + = *(unsigned int *)(*(unsigned long *)(cfa + 15*8) - 4); + + if (cuh_pattern == 0xd25fa7ef) { - /* We need to move up three frames: + /* This matches the call_user_handler pattern for Solaris 10. + There are 2 cases so we look for the return address of the + caller's caller frame in order to do more pattern matching. */ + unsigned int sah_pattern + = *(unsigned int *)(*(unsigned long *)(cfa + 176 + 15*8) - 4); + + if (sah_pattern == 0x92100019) + /* This is the same setup as for Solaris 9, see below. */ + *nframes = 3; + else + /* The sigacthandler frame isn't present in the chain. + We need to move up two frames: signal handler -- context-cfa __sighndlr - sigacthandler + call_user_handler frame kernel - */ - *nframes = 2; + */ + *nframes = 2; } - else /* Solaris 8 /usr/lib/lwp/sparcv9/libthread.so.1, Solaris 9+ - -- */ - { - /* We need to move up three frames: + else if (cuh_pattern == 0x9410001a || cuh_pattern == 0x94100013) + /* This matches the call_user_handler pattern for Solaris 9 and + for Solaris 8 running inside Solaris Containers respectively + We need to move up three frames: signal handler -- context-cfa __sighndlr call_user_handler sigacthandler kernel - */ - *nframes = 3; - } + */ + *nframes = 3; + else + /* This is the default Solaris 8 case. + We need to move up two frames: + + signal handler -- context-cfa + __sighndlr + sigacthandler + kernel + */ + *nframes = 2; return 1; } @@ -181,7 +202,7 @@ sparc64_frob_update_context (struct _Unw #define IS_SIGHANDLER sparc_is_sighandler static int -sparc_is_sighandler (unsigned int *pc, unsigned int * savpc, int *nframes) +sparc_is_sighandler (unsigned int *pc, void *cfa, int *nframes) { if (/* Solaris 8, 9 - single-threaded --- @@ -209,7 +230,7 @@ sparc_is_sighandler (unsigned int *pc, u pc[-1] == 0x9410001a pc[ 0] == 0x80a62008) { - /* Need to move up one frame: + /* We need to move up one frame: signal handler -- context-cfa sigacthandler @@ -240,7 +261,7 @@ sparc_is_sighandler (unsigned int *pc, u pc[ 1] == 0x81e8 pc[ 2] == 0x80a26000) { - /* Need to move up one frame: + /* We need to move up one frame: signal handler -- context-cfa __libthread_segvhdlr @@ -267,33 +288,59 @@
Re: Support Solaris 11/SPARC in MD_FALLBACK_FRAME_STATE_FOR (PR ada/41929)
The result has been bootstrapped by Eric (thanks for this and debugging why a first version caused some regressions on Solaris 8) and myself on Solaris 8, 9, 10 and 11, and I've performed quite a bit of software archaeology (i.e. stared at old libc.so.1 and libthread.so.1 patches) to make sure noting got missed in the process. All EH-related tests fail with a recent upgrade on Solaris 10. Interestingly, the old implementation keeps working with the upgrade. It seems that the __sighndlr case has been over-simplified: /* Look for the __sighndlr pattern. */ else if (*(unsigned int *)(pc-(4*5)) == sighndlr_pattern[0] *(unsigned int *)(pc-(4*4)) == sighndlr_pattern[1] *(unsigned int *)(pc-(4*3)) == sighndlr_pattern[2] *(unsigned int *)(pc-(4*2)) == sighndlr_pattern[3] *(unsigned int *)(pc-(4*1)) == sighndlr_pattern[4] *(unsigned int *)(pc-(4*0)) == sighndlr_pattern[5] *(unsigned int *)(pc+(4*1)) == sighndlr_pattern[6] ) { /* We have observed different calling frames among different versions of the operating system, so that we need to discriminate using the upper frame. We look for the return address of the caller frame (there is an offset of 15 words between the frame address and the place where this return address is stored) in order to do some more pattern matching. */ unsigned int cuh_pattern = *(unsigned int *)(*(unsigned int *)(this_cfa + 15*4) - 4); if (cuh_pattern == 0xd407a04c) { /* This matches the call_user_handler pattern for Solaris 10. There are 2 cases so we look for the return address of the caller's caller frame in order to do more pattern matching. */ unsigned int sah_pattern = *(unsigned int *)(*(unsigned int *)(this_cfa + 96 + 15*4) - 4); if (sah_pattern == 0x92100019) /* This is the same setup as for Solaris 9, see below. */ regs_off = 96 + 96 + 96 + 160; else /* We need to move up three frames (the kernel frame, the call_user_handler frame, the __sighndlr frame). Two of them have the minimum stack frame size (kernel and __sighndlr frames) of 96 bytes, and there is another with a stack frame of 160 bytes (the call_user_handler frame). The ucontext_t structure is after this offset. */ regs_off = 96 + 96 + 160; } else if (cuh_pattern == 0x9410001a || cuh_pattern == 0x9410001b) /* This matches the call_user_handler pattern for Solaris 9 and for Solaris 8 running inside Solaris Containers respectively. We need to move up four frames (the kernel frame, the signal frame, the call_user_handler frame, the __sighndlr frame). Three of them have the minimum stack frame size (kernel, signal, and __sighndlr frames) of 96 bytes, and there is another with a stack frame of 160 bytes (the call_user_handler frame). The ucontext_t structure is after this offset. */ regs_off = 96 + 96 + 96 + 160; else /* We need to move up three frames (the kernel frame, the sigacthandler frame, and the __sighndlr frame). Two of them have the minimum stack frame size (kernel and __sighndlr frames) of 96 bytes, and there is another with a stack frame of 216 bytes (the sigacthandler frame). The ucontext_t structure is after this offset. */ regs_off = 96 + 96 + 216; } to if(/* Solaris 8+ - multi-threaded __sighndlr:save %sp, -96, %sp __sighndlr+4: mov %i0, %o0 __sighndlr+8: mov %i1, %o1 __sighndlr+12: call %i3 __sighndlr+16: mov %i2, %o2 __sighndlr+20: ret --- PC __sighndlr+24: restore */ pc[-5] == 0x9de3bfa0 pc[-4] == 0x90100018 pc[-3] == 0x92100019 pc[-2] == 0x9fc6c000 pc[-1] == 0x9410001a pc[ 0] == 0x81c7e008 pc[ 1] == 0x81e8) { if (/* Solaris 8 /usr/lib/libthread.so.1 -- sigacthandler+1796: mov %i0, %o0 */ savpc[-1] == 0x90100018) { /* We need to move up two frames: signal handler-- context-cfa __sighndlr sigacthandler kernel */ *nframes = 2; } else /* Solaris 8 /usr/lib/lwp/libthread.so.1, Solaris 9+ -- */ { /* We need to move up three frames: signal handler-- context-cfa __sighndlr call_user_handler sigacthandler kernel