OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgcc/] [config/] [s390/] [linux-unwind.h] - Blame information for rev 734

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 734 jeremybenn
/* DWARF2 EH unwinding support for S/390 Linux.
2
   Copyright (C) 2004, 2005, 2006, 2009 Free Software Foundation, Inc.
3
 
4
This file is part of GCC.
5
 
6
GCC is free software; you can redistribute it and/or modify it under
7
the terms of the GNU General Public License as published by the Free
8
Software Foundation; either version 3, or (at your option) any later
9
version.
10
 
11
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12
WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
for more details.
15
 
16
Under Section 7 of GPL version 3, you are granted additional
17
permissions described in the GCC Runtime Library Exception, version
18
3.1, as published by the Free Software Foundation.
19
 
20
You should have received a copy of the GNU General Public License and
21
a copy of the GCC Runtime Library Exception along with this program;
22
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23
<http://www.gnu.org/licenses/>.  */
24
 
25
/* Do code reading to identify a signal frame, and set the frame
26
   state data appropriately.  See unwind-dw2.c for the structs.  */
27
 
28
#define MD_FALLBACK_FRAME_STATE_FOR s390_fallback_frame_state
29
 
30
static _Unwind_Reason_Code
31
s390_fallback_frame_state (struct _Unwind_Context *context,
32
                           _Unwind_FrameState *fs)
33
{
34
  unsigned char *pc = context->ra;
35
  long new_cfa;
36
  int i;
37
 
38
  typedef struct
39
  {
40
    unsigned long psw_mask;
41
    unsigned long psw_addr;
42
    unsigned long gprs[16];
43
    unsigned int  acrs[16];
44
    unsigned int  fpc;
45
    unsigned int  __pad;
46
    double        fprs[16];
47
  } __attribute__ ((__aligned__ (8))) sigregs_;
48
 
49
  sigregs_ *regs;
50
  int *signo;
51
 
52
  /* svc $__NR_sigreturn or svc $__NR_rt_sigreturn  */
53
  if (pc[0] != 0x0a || (pc[1] != 119 && pc[1] != 173))
54
    return _URC_END_OF_STACK;
55
 
56
  /* Legacy frames:
57
       old signal mask (8 bytes)
58
       pointer to sigregs (8 bytes) - points always to next location
59
       sigregs
60
       retcode
61
     This frame layout was used on kernels < 2.6.9 for non-RT frames,
62
     and on kernels < 2.4.13 for RT frames as well.  Note that we need
63
     to look at RA to detect this layout -- this means that if you use
64
     sa_restorer to install a different signal restorer on a legacy
65
     kernel, unwinding from signal frames will not work.  */
66
  if (context->ra == context->cfa + 16 + sizeof (sigregs_))
67
    {
68
      regs = (sigregs_ *)(context->cfa + 16);
69
      signo = NULL;
70
    }
71
 
72
  /* New-style RT frame:
73
     retcode + alignment (8 bytes)
74
     siginfo (128 bytes)
75
     ucontext (contains sigregs)  */
76
  else if (pc[1] == 173 /* __NR_rt_sigreturn */)
77
    {
78
      struct ucontext_
79
      {
80
        unsigned long     uc_flags;
81
        struct ucontext_ *uc_link;
82
        unsigned long     uc_stack[3];
83
        sigregs_          uc_mcontext;
84
      } *uc = context->cfa + 8 + 128;
85
 
86
      regs = &uc->uc_mcontext;
87
      signo = context->cfa + sizeof(long);
88
    }
89
 
90
  /* New-style non-RT frame:
91
     old signal mask (8 bytes)
92
     pointer to sigregs (followed by signal number)  */
93
  else
94
    {
95
      regs = *(sigregs_ **)(context->cfa + 8);
96
      signo = (int *)(regs + 1);
97
    }
98
 
99
  new_cfa = regs->gprs[15] + 16*sizeof(long) + 32;
100
  fs->regs.cfa_how = CFA_REG_OFFSET;
101
  fs->regs.cfa_reg = 15;
102
  fs->regs.cfa_offset =
103
    new_cfa - (long) context->cfa + 16*sizeof(long) + 32;
104
 
105
  for (i = 0; i < 16; i++)
106
    {
107
      fs->regs.reg[i].how = REG_SAVED_OFFSET;
108
      fs->regs.reg[i].loc.offset =
109
        (long)&regs->gprs[i] - new_cfa;
110
    }
111
  for (i = 0; i < 16; i++)
112
    {
113
      fs->regs.reg[16+i].how = REG_SAVED_OFFSET;
114
      fs->regs.reg[16+i].loc.offset =
115
        (long)&regs->fprs[i] - new_cfa;
116
    }
117
 
118
  /* Load return addr from PSW into dummy register 32.  */
119
 
120
  fs->regs.reg[32].how = REG_SAVED_OFFSET;
121
  fs->regs.reg[32].loc.offset = (long)&regs->psw_addr - new_cfa;
122
  fs->retaddr_column = 32;
123
  /* SIGILL, SIGFPE and SIGTRAP are delivered with psw_addr
124
     after the faulting instruction rather than before it.
125
     Don't set FS->signal_frame in that case.  */
126
  if (!signo || (*signo != 4 && *signo != 5 && *signo != 8))
127
    fs->signal_frame = 1;
128
 
129
  return _URC_NO_REASON;
130
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.