public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/21957] New: IA-64 register stack is not preserved after getcontext call
@ 2005-06-08  6:15 akr at m17n dot org
  2005-06-08  6:19 ` [Bug c/21957] " akr at m17n dot org
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: akr at m17n dot org @ 2005-06-08  6:15 UTC (permalink / raw)
  To: gcc-bugs

I found that following code causes SEGV on IA-64 Debian GNU/Linux (sarge) with gcc-4.0 -O1. The code uses getcontext and setcontext which is defined by Single Unix Specification.  rx1620% cat tst.i          typedef long unsigned int size_t;  struct ia64_fpreg {         union {                 unsigned long bits[2];                 long double __dummy;         } u; };  typedef struct sigaltstack   {     void * ss_sp;     int ss_flags;     size_t ss_size;   } stack_t;  struct sigcontext {   unsigned long int sc_flags;   unsigned long int sc_nat;   stack_t sc_stack;    unsigned long int sc_ip;   unsigned long int sc_cfm;   unsigned long int sc_um;   unsigned long int sc_ar_rsc;   unsigned long int sc_ar_bsp;   unsigned long int sc_ar_rnat;   unsigned long int sc_ar_ccv;   unsigned long int sc_ar_unat;   unsigned long int sc_ar_fpsr;   unsigned long int sc_ar_pfs;   unsigned long int sc_ar_lc;   unsigned long int sc_pr;   unsigned long int sc_br[8];   unsigned long int sc_gr[32];   struct ia64_fpreg sc_fr[128];   unsigned long int sc_rbs_base;   unsigned long int sc_loadrs;   unsigned long int sc_ar25;   unsigned long int sc_ar26;   unsigned long int sc_rsvd[12];    unsigned long int sc_mask; };  typedef struct sigcontext mcontext_t;  typedef struct ucontext   {     union       {         mcontext_t _mc;         struct           {             unsigned long _pad[(((char *) &((struct sigcontext *) 0)->sc_gr[0]) - (char *) 0)/8];             struct ucontext *_link;           }         _uc;       }     _u;   } ucontext_t;  extern int getcontext (ucontext_t *__ucp) ;  extern int setcontext (__const ucontext_t *__ucp) ;  int flag; ucontext_t cont;  static void f(void) {   flag = 1;   setcontext(&cont); }  static int g(void) {   int ret;    flag = 0;   getcontext(&cont);   ret = flag;   if (ret == 0) {     f();   }   return ret; }  int main(int argc, char **argv) {   g();   return 0; } rx1620% /home/src/gcc/4.0/bin/gcc -v -g -O1 tst.i Using built-in specs. Target: ia64-unknown-linux-gnu Configured with: ../gcc/configure --prefix=/home/src/gcc/4.0 --enable-languages=c Thread model: posix gcc version 4.0.1 20050607 (prerelease)  /home/src/gcc/4.0/libexec/gcc/ia64-unknown-linux-gnu/4.0.1/cc1 -fpreprocessed tst.i -quiet -dumpbase tst.i -auxbase tst -g -O1 -version -o /tmp/ccGs6ixv.s GNU C version 4.0.1 20050607 (prerelease) (ia64-unknown-linux-gnu)         compiled by GNU C version 4.0.1 20050607 (prerelease). GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072  as -x -o /tmp/ccgROVXU.o /tmp/ccGs6ixv.s  /home/src/gcc/4.0/libexec/gcc/ia64-unknown-linux-gnu/4.0.1/collect2 -dynamic-linker /lib/ld-linux-ia64.so.2 /usr/lib/crt1.o /usr/lib/crti.o /home/src/gcc/4.0/lib/gcc/ia64-unknown-linux-gnu/4.0.1/crtbegin.o -L/home/src/gcc/4.0/lib/gcc/ia64-unknown-linux-gnu/4.0.1 -L/home/src/gcc/4.0/lib/gcc/ia64-unknown-linux-gnu/4.0.1/../../.. /tmp/ccgROVXU.o -lgcc --as-needed -lgcc_s -lunwind --no-as-needed -lc -lgcc --as-needed -lgcc_s -lunwind --no-as-needed /home/src/gcc/4.0/lib/gcc/ia64-unknown-linux-gnu/4.0.1/crtend.o /usr/lib/crtn.o rx1620% ./a.out                                   zsh: segmentation fault (core dumped)  ./a.out rx1620% uname -a Linux rx1620 2.4.25-hpe-9-mckinley-smp #1 SMP Wed Aug 11 11:59:05 UTC 2004 ia64 GNU/Linux  ------------------------------------------------ The generated assembly code is follows.  | rx1620% /home/src/gcc/4.0/bin/gcc -O1 -S tst.i    | rx1620% cat tst.s                              |         .file   "tst.i" |         .pred.safe_across_calls p1-p5,p16-p63 |         .text |         .align 16 |         .proc f# | f: |         .prologue 12, 32 |         .save ar.pfs, r33 |         alloc r33 = ar.pfs, 0, 3, 1, 0 |         mov r34 = r1 |         .save rp, r32 |         mov r32 = b0 |         .body |         addl r15 = 1, r0 |         addl r14 = @ltoffx(flag#), r1 |         ;; |         ld8.mov r14 = [r14], flag# |         ;; |         st4 [r14] = r15 |         addl r35 = @ltoffx(cont#), r1 |         ;; |         ld8.mov r35 = [r35], cont# |         br.call.sptk.many b0 = setcontext# |         mov r1 = r34 |         ;; |         mov ar.pfs = r33 |         mov b0 = r32 |         br.ret.sptk.many b0 |         ;; |         .endp f# |         .align 16 |         .proc g# | g: |         .prologue 12, 33 |         .save ar.pfs, r34 |         alloc r34 = ar.pfs, 0, 4, 1, 0 |         mov r35 = r1 |         .save rp, r33 |         mov r33 = b0 |         .body |         addl r32 = @ltoffx(flag#), r1 |         ;; |         ld8.mov r32 = [r32], flag#  r32 is set.  |         ;; |         st4 [r32] = r0 |         addl r36 = @ltoffx(cont#), r1 |         ;; |         ld8.mov r36 = [r36], cont# |         br.call.sptk.many b0 = getcontext#  getcontext is called.  |         mov r1 = r35 |         ld4 r32 = [r32]  r32 is used. This means that the code expects r32 is preserved after getcontext returns.  |         ;; |         cmp4.ne p6, p7 = 0, r32 |         (p6) br.cond.dptk .L4 |         br.call.sptk.many b0 = f# |         mov r1 = r35 | .L4: |         mov r8 = r32 |         ;; |         mov ar.pfs = r34 |         mov b0 = r33 |         br.ret.sptk.many b0 |         ;; |         .endp g# |         .align 16 |         .global main# |         .proc main# | main: |         .prologue 12, 32 |         .save ar.pfs, r33 |         alloc r33 = ar.pfs, 0, 3, 0, 0 |         mov r34 = r1 |         .save rp, r32 |         mov r32 = b0 |         .body |         ;; |         br.call.sptk.many b0 = g# |         mov r1 = r34 |         mov r8 = r0 |         ;; |         mov ar.pfs = r33 |         mov b0 = r32 |         br.ret.sptk.many b0 |         ;; |         .endp main# |         .common flag#,4,4 |         .common cont#,2656,16 |         .ident  "GCC: (GNU) 4.0.1 20050607 (prerelease)" |    -------------------  The source code is follows.  | rx1620% cat tst.c | #include <ucontext.h> |  | int flag; | ucontext_t cont; |  | static void f(void) | { |   flag = 1; |   setcontext(&cont); | } |  | static int | g(void) | { |   int ret; |  |   flag = 0; |   getcontext(&cont); |   ret = flag; |   if (ret == 0) { |     f(); |   } |   return ret; | } |  | int main(int argc, char **argv) | { |   g(); |   return 0; | }  I investigated the problem as follows.  | rx1620% gdb a.out  | GNU gdb 6.3-debian | Copyright 2004 Free Software Foundation, Inc. | GDB is free software, covered by the GNU General Public License, and you are | welcome to change it and/or distribute copies of it under certain conditions. | Type "show copying" to see the conditions. | There is absolutely no warranty for GDB.  Type "show warranty" for details. | This GDB was configured as "ia64-linux"...Using host libthread_db library "/lib/libthread_db.so.1". |  | (gdb) display/i $pc | (gdb) run | Starting program: /home/akr/z/z/a.out  |  | Program received signal SIGSEGV, Segmentation fault. | g () at tst.i:85 | 85        ret = flag; | 1: x/i $pc  0x4000000000000901 <g+65>:              ld4 r32=[r32] | (gdb) p $r32 | $1 = 0  SEGV is caused because r32 is zero.  | (gdb) break *0x4000000000000901 | Breakpoint 1 at 0x4000000000000901: file tst.i, line 85.  The breakpoint is on the instruction to use r32.  | (gdb) disassemble  | Dump of assembler code for function g: | 0x40000000000008c0 <g+0>:       [MII]       alloc r34=ar.pfs,5,4,0 | 0x40000000000008c1 <g+1>:                   mov r35=r1 | 0x40000000000008c2 <g+2>:                   mov r33=b0 | 0x40000000000008d0 <g+16>:      [MMI]       addl r32=160,r1;; | 0x40000000000008d1 <g+17>:                  nop.m 0x0 | 0x40000000000008d2 <g+18>:                  nop.i 0x0;; | 0x40000000000008e0 <g+32>:      [MFI]       st4 [r32]=r0 | 0x40000000000008e1 <g+33>:                  nop.f 0x0 | 0x40000000000008e2 <g+34>:                  addl r36=184,r1;; | 0x40000000000008f0 <g+48>:      [MFB]       nop.m 0x0 | 0x40000000000008f1 <g+49>:                  nop.f 0x0 | 0x40000000000008f2 <g+50>:                  br.call.sptk.many b0=0x40000000000005c0 <_init+208> | 0x4000000000000900 <g+64>:      [MMI]       mov r1=r35 | 0x4000000000000901 <g+65>:                  ld4 r32=[r32] | 0x4000000000000902 <g+66>:                  nop.i 0x0;; | 0x4000000000000910 <g+80>:      [MBB]       cmp4.eq p7,p6=0,r32 | 0x4000000000000911 <g+81>:            (p06) br.cond.dptk.few 0x4000000000000930 <g+112> | 0x4000000000000912 <g+82>:                  br.call.sptk.many b0=0x4000000000000860 <f> | 0x4000000000000920 <g+96>:      [MFB]       mov r1=r35 | 0x4000000000000921 <g+97>:                  nop.f 0x0 | 0x4000000000000922 <g+98>:                  nop.b 0x0 | 0x4000000000000930 <g+112>:     [MMI]       mov r8=r32;; | 0x4000000000000931 <g+113>:                 nop.m 0x0 | 0x4000000000000932 <g+114>:                 mov.i ar.pfs=r34 | 0x4000000000000940 <g+128>:     [MIB]       nop.m 0x0 | 0x4000000000000941 <g+129>:                 mov b0=r33 | 0x4000000000000942 <g+130>:                 br.ret.sptk.many b0;; | End of assembler dump. | (gdb) break *0x40000000000008f2 | Breakpoint 2 at 0x40000000000008f2: file tst.i, line 84.  The breakpoint is on the instruction to call getcontext.  | (gdb) run | The program being debugged has been started already. | Start it from the beginning? (y or n) y | Starting program: /home/akr/z/z/a.out  |  | Breakpoint 2, g () at tst.i:84 | 84        getcontext(&cont); | 1: x/i $pc  0x40000000000008f2 <g+50>:              br.call.sptk.many b0=0x40000000000005c0 <_init+208> | (gdb) p $r32 | $2 = 6917529027641086280  r32 is not zero before getcontext call.  | (gdb) c | Continuing. |  | Breakpoint 1, g () at tst.i:85 | 85        ret = flag; | 1: x/i $pc  0x4000000000000901 <g+65>:              ld4 r32=[r32] | (gdb) p $r32 | $3 = 6917529027641086280  r32 is preserved after first getcontext return.  | (gdb) c | Continuing. |  | Breakpoint 1, g () at tst.i:85 | 85        ret = flag; | 1: x/i $pc  0x4000000000000901 <g+65>:              ld4 r32=[r32] | (gdb) p $r32 | $4 = 0  r32 is zero after second getcontext return. Note that this return is from setcontext, like longjmp to setjmp.  | (gdb) si |  | Program received signal SIGSEGV, Segmentation fault. | g () at tst.i:85 | 85        ret = flag; | 1: x/i $pc  0x4000000000000901 <g+65>:              ld4 r32=[r32]  I think the getcontext behavior is not a bug because setjmp behaves like so.  "Intel(R) Itanium(R) Software Conventions & Runtime Architecture Guide"'s section 10.3 describes setjmp may not preserve the contents of registers in  register stack (r32 to r127). http://www.intel.com/design/itanium/downloads/245358.htm  It seems that setjmp has no such problem because  gcc knows setjmp may return twice.  | rx1620% cd /home/src/gcc/4.0/gcc  | rx1620% grep -C8 '"setjmp"' gcc/calls.c |             tname += 2; |           else |             tname += 1; |         } |  |       if (tname[0] == 's') |         { |           if ((tname[1] == 'e' |                && (! strcmp (tname, "setjmp") |                    || ! strcmp (tname, "setjmp_syscall"))) |               || (tname[1] == 'i' |                   && ! strcmp (tname, "sigsetjmp")) |               || (tname[1] == 'a' |                   && ! strcmp (tname, "savectx"))) |             flags |= ECF_RETURNS_TWICE; |  |           if (tname[1] == 'i'  So I guess the problem can be fixed if gcc knows getcontext returns twice.

-- 
           Summary: IA-64 register stack is not preserved after getcontext
                    call
           Product: gcc
           Version: 4.0.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: akr at m17n dot org
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: ia64-unknown-linux-gnu
  GCC host triplet: ia64-unknown-linux-gnu
GCC target triplet: ia64-unknown-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21957


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c/21957] IA-64 register stack is not preserved after getcontext call
  2005-06-08  6:15 [Bug c/21957] New: IA-64 register stack is not preserved after getcontext call akr at m17n dot org
@ 2005-06-08  6:19 ` akr at m17n dot org
  2005-06-08  6:43 ` [Bug middle-end/21957] " pinskia at gcc dot gnu dot org
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: akr at m17n dot org @ 2005-06-08  6:19 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From akr at m17n dot org  2005-06-08 06:19 -------
Oops. The newlines are squashed.  I repeat the report as this comment.

I found that following code causes SEGV on IA-64 Debian GNU/Linux (sarge)
with gcc-4.0 -O1.
The code uses getcontext and setcontext which is defined by
Single Unix Specification.

rx1620% cat tst.i         
typedef long unsigned int size_t;

struct ia64_fpreg {
        union {
                unsigned long bits[2];
                long double __dummy;
        } u;
};

typedef struct sigaltstack
  {
    void * ss_sp;
    int ss_flags;
    size_t ss_size;
  } stack_t;

struct sigcontext
{
  unsigned long int sc_flags;
  unsigned long int sc_nat;
  stack_t sc_stack;

  unsigned long int sc_ip;
  unsigned long int sc_cfm;
  unsigned long int sc_um;
  unsigned long int sc_ar_rsc;
  unsigned long int sc_ar_bsp;
  unsigned long int sc_ar_rnat;
  unsigned long int sc_ar_ccv;
  unsigned long int sc_ar_unat;
  unsigned long int sc_ar_fpsr;
  unsigned long int sc_ar_pfs;
  unsigned long int sc_ar_lc;
  unsigned long int sc_pr;
  unsigned long int sc_br[8];
  unsigned long int sc_gr[32];
  struct ia64_fpreg sc_fr[128];
  unsigned long int sc_rbs_base;
  unsigned long int sc_loadrs;
  unsigned long int sc_ar25;
  unsigned long int sc_ar26;
  unsigned long int sc_rsvd[12];

  unsigned long int sc_mask;
};

typedef struct sigcontext mcontext_t;

typedef struct ucontext
  {
    union
      {
        mcontext_t _mc;
        struct
          {
            unsigned long _pad[(((char *) &((struct sigcontext *) 0)->sc_gr[0])
- (char *) 0)/8];
            struct ucontext *_link;
          }
        _uc;
      }
    _u;
  }
ucontext_t;

extern int getcontext (ucontext_t *__ucp) ;

extern int setcontext (__const ucontext_t *__ucp) ;

int flag;
ucontext_t cont;

static void f(void)
{
  flag = 1;
  setcontext(&cont);
}

static int
g(void)
{
  int ret;

  flag = 0;
  getcontext(&cont);
  ret = flag;
  if (ret == 0) {
    f();
  }
  return ret;
}

int main(int argc, char **argv)
{
  g();
  return 0;
}
rx1620% /home/src/gcc/4.0/bin/gcc -v -g -O1 tst.i
Using built-in specs.
Target: ia64-unknown-linux-gnu
Configured with: ../gcc/configure --prefix=/home/src/gcc/4.0 --enable-languages=c
Thread model: posix
gcc version 4.0.1 20050607 (prerelease)
 /home/src/gcc/4.0/libexec/gcc/ia64-unknown-linux-gnu/4.0.1/cc1 -fpreprocessed
tst.i -quiet -dumpbase tst.i -auxbase tst -g -O1 -version -o /tmp/ccGs6ixv.s
GNU C version 4.0.1 20050607 (prerelease) (ia64-unknown-linux-gnu)
        compiled by GNU C version 4.0.1 20050607 (prerelease).
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
 as -x -o /tmp/ccgROVXU.o /tmp/ccGs6ixv.s
 /home/src/gcc/4.0/libexec/gcc/ia64-unknown-linux-gnu/4.0.1/collect2
-dynamic-linker /lib/ld-linux-ia64.so.2 /usr/lib/crt1.o /usr/lib/crti.o
/home/src/gcc/4.0/lib/gcc/ia64-unknown-linux-gnu/4.0.1/crtbegin.o
-L/home/src/gcc/4.0/lib/gcc/ia64-unknown-linux-gnu/4.0.1
-L/home/src/gcc/4.0/lib/gcc/ia64-unknown-linux-gnu/4.0.1/../../..
/tmp/ccgROVXU.o -lgcc --as-needed -lgcc_s -lunwind --no-as-needed -lc -lgcc
--as-needed -lgcc_s -lunwind --no-as-needed
/home/src/gcc/4.0/lib/gcc/ia64-unknown-linux-gnu/4.0.1/crtend.o /usr/lib/crtn.o
rx1620% ./a.out                                  
zsh: segmentation fault (core dumped)  ./a.out
rx1620% uname -a
Linux rx1620 2.4.25-hpe-9-mckinley-smp #1 SMP Wed Aug 11 11:59:05 UTC 2004 ia64
GNU/Linux

------------------------------------------------
The generated assembly code is follows.

| rx1620% /home/src/gcc/4.0/bin/gcc -O1 -S tst.i   
| rx1620% cat tst.s                             
|         .file   "tst.i"
|         .pred.safe_across_calls p1-p5,p16-p63
|         .text
|         .align 16
|         .proc f#
| f:
|         .prologue 12, 32
|         .save ar.pfs, r33
|         alloc r33 = ar.pfs, 0, 3, 1, 0
|         mov r34 = r1
|         .save rp, r32
|         mov r32 = b0
|         .body
|         addl r15 = 1, r0
|         addl r14 = @ltoffx(flag#), r1
|         ;;
|         ld8.mov r14 = [r14], flag#
|         ;;
|         st4 [r14] = r15
|         addl r35 = @ltoffx(cont#), r1
|         ;;
|         ld8.mov r35 = [r35], cont#
|         br.call.sptk.many b0 = setcontext#
|         mov r1 = r34
|         ;;
|         mov ar.pfs = r33
|         mov b0 = r32
|         br.ret.sptk.many b0
|         ;;
|         .endp f#
|         .align 16
|         .proc g#
| g:
|         .prologue 12, 33
|         .save ar.pfs, r34
|         alloc r34 = ar.pfs, 0, 4, 1, 0
|         mov r35 = r1
|         .save rp, r33
|         mov r33 = b0
|         .body
|         addl r32 = @ltoffx(flag#), r1
|         ;;
|         ld8.mov r32 = [r32], flag#

r32 is set.

|         ;;
|         st4 [r32] = r0
|         addl r36 = @ltoffx(cont#), r1
|         ;;
|         ld8.mov r36 = [r36], cont#
|         br.call.sptk.many b0 = getcontext#

getcontext is called.

|         mov r1 = r35
|         ld4 r32 = [r32]

r32 is used.
This means that the code expects r32 is preserved after getcontext returns.

|         ;;
|         cmp4.ne p6, p7 = 0, r32
|         (p6) br.cond.dptk .L4
|         br.call.sptk.many b0 = f#
|         mov r1 = r35
| .L4:
|         mov r8 = r32
|         ;;
|         mov ar.pfs = r34
|         mov b0 = r33
|         br.ret.sptk.many b0
|         ;;
|         .endp g#
|         .align 16
|         .global main#
|         .proc main#
| main:
|         .prologue 12, 32
|         .save ar.pfs, r33
|         alloc r33 = ar.pfs, 0, 3, 0, 0
|         mov r34 = r1
|         .save rp, r32
|         mov r32 = b0
|         .body
|         ;;
|         br.call.sptk.many b0 = g#
|         mov r1 = r34
|         mov r8 = r0
|         ;;
|         mov ar.pfs = r33
|         mov b0 = r32
|         br.ret.sptk.many b0
|         ;;
|         .endp main#
|         .common flag#,4,4
|         .common cont#,2656,16
|         .ident  "GCC: (GNU) 4.0.1 20050607 (prerelease)"
| 


-------------------

The source code is follows.

| rx1620% cat tst.c
| #include <ucontext.h>
| 
| int flag;
| ucontext_t cont;
| 
| static void f(void)
| {
|   flag = 1;
|   setcontext(&cont);
| }
| 
| static int
| g(void)
| {
|   int ret;
| 
|   flag = 0;
|   getcontext(&cont);
|   ret = flag;
|   if (ret == 0) {
|     f();
|   }
|   return ret;
| }
| 
| int main(int argc, char **argv)
| {
|   g();
|   return 0;
| }

I investigated the problem as follows.

| rx1620% gdb a.out 
| GNU gdb 6.3-debian
| Copyright 2004 Free Software Foundation, Inc.
| GDB is free software, covered by the GNU General Public License, and you are
| welcome to change it and/or distribute copies of it under certain conditions.
| Type "show copying" to see the conditions.
| There is absolutely no warranty for GDB.  Type "show warranty" for details.
| This GDB was configured as "ia64-linux"...Using host libthread_db library
"/lib/libthread_db.so.1".
| 
| (gdb) display/i $pc
| (gdb) run
| Starting program: /home/akr/z/z/a.out 
| 
| Program received signal SIGSEGV, Segmentation fault.
| g () at tst.i:85
| 85        ret = flag;
| 1: x/i $pc  0x4000000000000901 <g+65>:              ld4 r32=[r32]
| (gdb) p $r32
| $1 = 0

SEGV is caused because r32 is zero.

| (gdb) break *0x4000000000000901
| Breakpoint 1 at 0x4000000000000901: file tst.i, line 85.

The breakpoint is on the instruction to use r32.

| (gdb) disassemble 
| Dump of assembler code for function g:
| 0x40000000000008c0 <g+0>:       [MII]       alloc r34=ar.pfs,5,4,0
| 0x40000000000008c1 <g+1>:                   mov r35=r1
| 0x40000000000008c2 <g+2>:                   mov r33=b0
| 0x40000000000008d0 <g+16>:      [MMI]       addl r32=160,r1;;
| 0x40000000000008d1 <g+17>:                  nop.m 0x0
| 0x40000000000008d2 <g+18>:                  nop.i 0x0;;
| 0x40000000000008e0 <g+32>:      [MFI]       st4 [r32]=r0
| 0x40000000000008e1 <g+33>:                  nop.f 0x0
| 0x40000000000008e2 <g+34>:                  addl r36=184,r1;;
| 0x40000000000008f0 <g+48>:      [MFB]       nop.m 0x0
| 0x40000000000008f1 <g+49>:                  nop.f 0x0
| 0x40000000000008f2 <g+50>:                  br.call.sptk.many
b0=0x40000000000005c0 <_init+208>
| 0x4000000000000900 <g+64>:      [MMI]       mov r1=r35
| 0x4000000000000901 <g+65>:                  ld4 r32=[r32]
| 0x4000000000000902 <g+66>:                  nop.i 0x0;;
| 0x4000000000000910 <g+80>:      [MBB]       cmp4.eq p7,p6=0,r32
| 0x4000000000000911 <g+81>:            (p06) br.cond.dptk.few
0x4000000000000930 <g+112>
| 0x4000000000000912 <g+82>:                  br.call.sptk.many
b0=0x4000000000000860 <f>
| 0x4000000000000920 <g+96>:      [MFB]       mov r1=r35
| 0x4000000000000921 <g+97>:                  nop.f 0x0
| 0x4000000000000922 <g+98>:                  nop.b 0x0
| 0x4000000000000930 <g+112>:     [MMI]       mov r8=r32;;
| 0x4000000000000931 <g+113>:                 nop.m 0x0
| 0x4000000000000932 <g+114>:                 mov.i ar.pfs=r34
| 0x4000000000000940 <g+128>:     [MIB]       nop.m 0x0
| 0x4000000000000941 <g+129>:                 mov b0=r33
| 0x4000000000000942 <g+130>:                 br.ret.sptk.many b0;;
| End of assembler dump.
| (gdb) break *0x40000000000008f2
| Breakpoint 2 at 0x40000000000008f2: file tst.i, line 84.

The breakpoint is on the instruction to call getcontext.

| (gdb) run
| The program being debugged has been started already.
| Start it from the beginning? (y or n) y
| Starting program: /home/akr/z/z/a.out 
| 
| Breakpoint 2, g () at tst.i:84
| 84        getcontext(&cont);
| 1: x/i $pc  0x40000000000008f2 <g+50>:              br.call.sptk.many
b0=0x40000000000005c0 <_init+208>
| (gdb) p $r32
| $2 = 6917529027641086280

r32 is not zero before getcontext call.

| (gdb) c
| Continuing.
| 
| Breakpoint 1, g () at tst.i:85
| 85        ret = flag;
| 1: x/i $pc  0x4000000000000901 <g+65>:              ld4 r32=[r32]
| (gdb) p $r32
| $3 = 6917529027641086280

r32 is preserved after first getcontext return.

| (gdb) c
| Continuing.
| 
| Breakpoint 1, g () at tst.i:85
| 85        ret = flag;
| 1: x/i $pc  0x4000000000000901 <g+65>:              ld4 r32=[r32]
| (gdb) p $r32
| $4 = 0

r32 is zero after second getcontext return.
Note that this return is from setcontext, like longjmp to setjmp.

| (gdb) si
| 
| Program received signal SIGSEGV, Segmentation fault.
| g () at tst.i:85
| 85        ret = flag;
| 1: x/i $pc  0x4000000000000901 <g+65>:              ld4 r32=[r32]

I think the getcontext behavior is not a bug because setjmp behaves like so.

"Intel(R) Itanium(R) Software Conventions & Runtime Architecture Guide"'s
section 10.3 describes setjmp may not preserve the contents of registers in
 register stack (r32 to r127).
http://www.intel.com/design/itanium/downloads/245358.htm

It seems that setjmp has no such problem because 
gcc knows setjmp may return twice.

| rx1620% cd /home/src/gcc/4.0/gcc 
| rx1620% grep -C8 '"setjmp"' gcc/calls.c
|             tname += 2;
|           else
|             tname += 1;
|         }
| 
|       if (tname[0] == 's')
|         {
|           if ((tname[1] == 'e'
|                && (! strcmp (tname, "setjmp")
|                    || ! strcmp (tname, "setjmp_syscall")))
|               || (tname[1] == 'i'
|                   && ! strcmp (tname, "sigsetjmp"))
|               || (tname[1] == 'a'
|                   && ! strcmp (tname, "savectx")))
|             flags |= ECF_RETURNS_TWICE;
| 
|           if (tname[1] == 'i'

So I guess the problem can be fixed if gcc knows getcontext returns twice. 

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21957


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug middle-end/21957] IA-64 register stack is not preserved after getcontext call
  2005-06-08  6:15 [Bug c/21957] New: IA-64 register stack is not preserved after getcontext call akr at m17n dot org
  2005-06-08  6:19 ` [Bug c/21957] " akr at m17n dot org
@ 2005-06-08  6:43 ` pinskia at gcc dot gnu dot org
  2005-06-20 17:05 ` pinskia at gcc dot gnu dot org
  2005-06-29  3:50 ` akr at m17n dot org
  3 siblings, 0 replies; 6+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-06-08  6:43 UTC (permalink / raw)
  To: gcc-bugs



-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|c                           |middle-end
           Keywords|                            |wrong-code


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21957


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug middle-end/21957] IA-64 register stack is not preserved after getcontext call
  2005-06-08  6:15 [Bug c/21957] New: IA-64 register stack is not preserved after getcontext call akr at m17n dot org
  2005-06-08  6:19 ` [Bug c/21957] " akr at m17n dot org
  2005-06-08  6:43 ` [Bug middle-end/21957] " pinskia at gcc dot gnu dot org
@ 2005-06-20 17:05 ` pinskia at gcc dot gnu dot org
  2005-06-29  3:50 ` akr at m17n dot org
  3 siblings, 0 replies; 6+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-06-20 17:05 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2005-06-20 17:04 -------
Hmm, why do you think getcontext should return twice?
It does not, GCC is emmitting correct asm for a normal function, why should getcontext be different?

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21957


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug middle-end/21957] IA-64 register stack is not preserved after getcontext call
  2005-06-08  6:15 [Bug c/21957] New: IA-64 register stack is not preserved after getcontext call akr at m17n dot org
                   ` (2 preceding siblings ...)
  2005-06-20 17:05 ` pinskia at gcc dot gnu dot org
@ 2005-06-29  3:50 ` akr at m17n dot org
  3 siblings, 0 replies; 6+ messages in thread
From: akr at m17n dot org @ 2005-06-29  3:50 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From akr at m17n dot org  2005-06-29 03:50 -------
I think getcontext should return twice because getcontext is similar to setjmp.

First, getcontext returns from usual function call.
Second, getcontext returns from setcontext.

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21957


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug middle-end/21957] IA-64 register stack is not preserved after getcontext call
       [not found] <bug-21957-2489@http.gcc.gnu.org/bugzilla/>
@ 2005-11-09 12:08 ` ebotcazou at gcc dot gnu dot org
  0 siblings, 0 replies; 6+ messages in thread
From: ebotcazou at gcc dot gnu dot org @ 2005-11-09 12:08 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #4 from ebotcazou at gcc dot gnu dot org  2005-11-09 12:08 -------


*** This bug has been marked as a duplicate of 22127 ***


-- 

ebotcazou at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |DUPLICATE


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21957


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2005-11-09 12:08 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-06-08  6:15 [Bug c/21957] New: IA-64 register stack is not preserved after getcontext call akr at m17n dot org
2005-06-08  6:19 ` [Bug c/21957] " akr at m17n dot org
2005-06-08  6:43 ` [Bug middle-end/21957] " pinskia at gcc dot gnu dot org
2005-06-20 17:05 ` pinskia at gcc dot gnu dot org
2005-06-29  3:50 ` akr at m17n dot org
     [not found] <bug-21957-2489@http.gcc.gnu.org/bugzilla/>
2005-11-09 12:08 ` ebotcazou at gcc dot gnu dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).