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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgcc/] [config/] [mips/] [irix6-unwind.h] - Blame information for rev 801

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 734 jeremybenn
/* DWARF2 EH unwinding support for MIPS IRIX 6.
2
   Copyright (C) 2011 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
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 3, or (at your option)
9
any later version.
10
 
11
GCC is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License 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
/* This code was developed-for and only tested-in limited ABI
29
   configurations.  Characterize that.  */
30
 
31
#if defined (_ABIN32) || defined (_ABI64)
32
#define SUPPORTED_ABI 1
33
#else
34
#define SUPPORTED_ABI 0
35
#endif
36
 
37
#include <signal.h>
38
 
39
#define MD_FALLBACK_FRAME_STATE_FOR mips_fallback_frame_state
40
 
41
/* Look at the code around RA to see if it matches a sighandler caller with a
42
   sigcontext_t * argument (SA_SIGINFO cleared).  Return that pointer argument
43
   if it does match, or 0 otherwise.  */
44
 
45
static sigcontext_t *
46
sigcontext_for (unsigned int *ra, void *cfa)
47
{
48
  /* IRIX 6.5, mono-threaded application.  We're lucky enough to be able
49
     to expect a short very sighandler specific sequence around.
50
 
51
     <_sigtramp+124>:   li      v0,1088 (SYS_sigreturn)
52
     <_sigtramp+128>:   syscall  */
53
 
54
  if (   ra[6] == 0x24020440
55
      && ra[7] == 0x0000000c)
56
    return (sigcontext_t *)(cfa + 0x30);
57
 
58
  /* IRIX 6.5 variants, multi-threaded application, pthreads.  Nothing really
59
     sighandler specific handy, so match a fairly long constant sequence.  */
60
 
61
#if _MIPS_SIM == _ABIN32
62
  /*
63
     <sig_fixup_mask+40>:       sd      s0,0(sp)
64
     <sig_fixup_mask+44>:       sll     ra,a0,0x2
65
     <sig_fixup_mask+48>:       addiu   t9,t9,-28584/-28456/-28448
66
     <sig_fixup_mask+52>:       lw      s0,3804(at)
67
     <sig_fixup_mask+56>:       addu    t9,t9,ra
68
     <sig_fixup_mask+60>:       lw      t9,0(t9)
69
     <sig_fixup_mask+64>:       ld      at,3696(at)
70
     <sig_fixup_mask+68>:       ld      s2,88(s0)
71
     <sig_fixup_mask+72>:       jalr    t9
72
     <sig_fixup_mask+76>:       sd      at,88(s0)  */
73
   if (   ra[-10] == 0xffb00000
74
      && ra[ -9] == 0x0004f880
75
      && (ra[-8] == 0x27399058
76
          || ra[-8] == 0x273990d8
77
          || ra[-8] == 0x273990e0)
78
      && ra[ -7] == 0x8c300edc
79
      && ra[ -6] == 0x033fc821
80
      && ra[ -5] == 0x8f390000
81
      && ra[ -4] == 0xdc210e70
82
      && ra[ -3] == 0xde120058
83
      && ra[ -2] == 0x0320f809
84
      && ra[ -1] == 0xfe010058)
85
 
86
#elif _MIPS_SIM == _ABI64
87
  /*
88
     <sig_fixup_mask+44>:       sd      s0,0(sp)
89
     <sig_fixup_mask+48>:       daddu   t9,t9,ra
90
     <sig_fixup_mask+52>:       dsll    ra,a0,0x3
91
     <sig_fixup_mask+56>:       ld      s0,3880(at)
92
     <sig_fixup_mask+60>:       daddu   t9,t9,ra
93
     <sig_fixup_mask+64>:       ld      t9,0(t9)
94
     <sig_fixup_mask+68>:       ld      at,3696(at)
95
     <sig_fixup_mask+72>:       ld      s2,152(s0)
96
     <sig_fixup_mask+76>:       jalr    t9
97
     <sig_fixup_mask+80>:       sd      at,152(s0)  */
98
  if (   ra[-10] == 0xffb00000
99
      && ra[ -9] == 0x033fc82d
100
      && ra[ -8] == 0x0004f8f8
101
      && ra[ -7] == 0xdc300f28
102
      && ra[ -6] == 0x033fc82d
103
      && ra[ -5] == 0xdf390000
104
      && ra[ -4] == 0xdc210e70
105
      && ra[ -3] == 0xde120098
106
      && ra[ -2] == 0x0320f809
107
      && ra[ -1] == 0xfe010098)
108
#endif
109
    return (sigcontext_t *)(cfa + 0x60);
110
 
111
  return 0;
112
}
113
 
114
#define SIGCTX_GREG_ADDR(REGNO,SIGCTX) \
115
  ((void *) &(SIGCTX)->sc_regs[REGNO])
116
 
117
#define SIGCTX_FPREG_ADDR(REGNO,SIGCTX) \
118
  ((void *) &(SIGCTX)->sc_fpregs[REGNO])
119
 
120
static _Unwind_Reason_Code
121
mips_fallback_frame_state (struct _Unwind_Context *context,
122
                           _Unwind_FrameState *fs)
123
{
124
  /* Return address and CFA of the frame we're attempting to unwind through,
125
     possibly a signal handler.  */
126
  void *ctx_ra  = (void *)context->ra;
127
  void *ctx_cfa = (void *)context->cfa;
128
 
129
  /* CFA of the intermediate abstract kernel frame between the interrupted
130
     code and the signal handler, if we're indeed unwinding through a signal
131
     handler.  */
132
  void *k_cfa;
133
 
134
  /* Pointer to the sigcontext_t structure pushed by the kernel when we're
135
     unwinding through a signal handler setup with SA_SIGINFO cleared.  */
136
  sigcontext_t *sigctx;
137
  int i;
138
 
139
  if (! SUPPORTED_ABI)
140
    return _URC_END_OF_STACK;
141
 
142
  sigctx = sigcontext_for (ctx_ra, ctx_cfa);
143
 
144
  if (sigctx == 0)
145
    return _URC_END_OF_STACK;
146
 
147
  /* The abstract kernel frame's CFA is extactly the stack pointer
148
     value at the interruption point.  */
149
  k_cfa = *(void **)SIGCTX_GREG_ADDR (CTX_SP, sigctx);
150
 
151
  /* State the rules to compute the CFA we have the value of: use the
152
     previous CFA and offset by the difference between the two.  See
153
     uw_update_context_1 for the supporting details.  */
154
  fs->regs.cfa_how = CFA_REG_OFFSET;
155
  fs->regs.cfa_reg = __builtin_dwarf_sp_column ();
156
  fs->regs.cfa_offset = k_cfa - ctx_cfa;
157
 
158
  /* Fill the internal frame_state structure with information stating where
159
     each register of interest can be found from the CFA.  */
160
  for (i = 0; i <= 31; i ++)
161
    {
162
      fs->regs.reg[i].how = REG_SAVED_OFFSET;
163
      fs->regs.reg[i].loc.offset = SIGCTX_GREG_ADDR (i, sigctx) - k_cfa;
164
    }
165
 
166
  for (i = 0; i <= 31; i ++)
167
    {
168
      fs->regs.reg[32+i].how = REG_SAVED_OFFSET;
169
      fs->regs.reg[32+i].loc.offset = SIGCTX_FPREG_ADDR (i, sigctx) - k_cfa;
170
    }
171
 
172
  /* State the rules to find the kernel's code "return address", which is the
173
     address of the active instruction when the signal was caught.  */
174
  fs->retaddr_column = DWARF_FRAME_RETURN_COLUMN;
175
  fs->regs.reg[fs->retaddr_column].how = REG_SAVED_OFFSET;
176
  fs->regs.reg[fs->retaddr_column].loc.offset = (void *)&sigctx->sc_pc - k_cfa;
177
  fs->signal_frame = 1;
178
 
179
  return _URC_NO_REASON;
180
}

powered by: WebSVN 2.1.0

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