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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgcc/] [config/] [i386/] [linux-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 AMD x86-64 and x86.
2
   Copyright (C) 2004, 2005, 2006, 2009, 2010, 2011
3
   Free Software Foundation, Inc.
4
 
5
This file is part of GCC.
6
 
7
GCC is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 3, or (at your option)
10
any later version.
11
 
12
GCC is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
Under Section 7 of GPL version 3, you are granted additional
18
permissions described in the GCC Runtime Library Exception, version
19
3.1, as published by the Free Software Foundation.
20
 
21
You should have received a copy of the GNU General Public License and
22
a copy of the GCC Runtime Library Exception along with this program;
23
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24
<http://www.gnu.org/licenses/>.  */
25
 
26
/* Do code reading to identify a signal frame, and set the frame
27
   state data appropriately.  See unwind-dw2.c for the structs.
28
   Don't use this at all if inhibit_libc is used.  */
29
 
30
#ifndef inhibit_libc
31
 
32
#ifdef __x86_64__
33
 
34
#include <signal.h>
35
#include <sys/ucontext.h>
36
 
37
#define MD_FALLBACK_FRAME_STATE_FOR x86_64_fallback_frame_state
38
 
39
static _Unwind_Reason_Code
40
x86_64_fallback_frame_state (struct _Unwind_Context *context,
41
                             _Unwind_FrameState *fs)
42
{
43
  unsigned char *pc = context->ra;
44
  struct sigcontext *sc;
45
  long new_cfa;
46
 
47
  /* movq $__NR_rt_sigreturn, %rax ; syscall.  */
48
#ifdef __LP64__
49
#define RT_SIGRETURN_SYSCALL    0x050f0000000fc0c7ULL
50
#else
51
#define RT_SIGRETURN_SYSCALL    0x050f40002006c0c7ULL
52
#endif
53
  if (*(unsigned char *)(pc+0) == 0x48
54
      && *(unsigned long long *)(pc+1) == RT_SIGRETURN_SYSCALL)
55
    {
56
      struct ucontext *uc_ = context->cfa;
57
      /* The void * cast is necessary to avoid an aliasing warning.
58
         The aliasing warning is correct, but should not be a problem
59
         because it does not alias anything.  */
60
      sc = (struct sigcontext *) (void *) &uc_->uc_mcontext;
61
    }
62
  else
63
    return _URC_END_OF_STACK;
64
 
65
  new_cfa = sc->rsp;
66
  fs->regs.cfa_how = CFA_REG_OFFSET;
67
  /* Register 7 is rsp  */
68
  fs->regs.cfa_reg = 7;
69
  fs->regs.cfa_offset = new_cfa - (long) context->cfa;
70
 
71
  /* The SVR4 register numbering macros aren't usable in libgcc.  */
72
  fs->regs.reg[0].how = REG_SAVED_OFFSET;
73
  fs->regs.reg[0].loc.offset = (long)&sc->rax - new_cfa;
74
  fs->regs.reg[1].how = REG_SAVED_OFFSET;
75
  fs->regs.reg[1].loc.offset = (long)&sc->rdx - new_cfa;
76
  fs->regs.reg[2].how = REG_SAVED_OFFSET;
77
  fs->regs.reg[2].loc.offset = (long)&sc->rcx - new_cfa;
78
  fs->regs.reg[3].how = REG_SAVED_OFFSET;
79
  fs->regs.reg[3].loc.offset = (long)&sc->rbx - new_cfa;
80
  fs->regs.reg[4].how = REG_SAVED_OFFSET;
81
  fs->regs.reg[4].loc.offset = (long)&sc->rsi - new_cfa;
82
  fs->regs.reg[5].how = REG_SAVED_OFFSET;
83
  fs->regs.reg[5].loc.offset = (long)&sc->rdi - new_cfa;
84
  fs->regs.reg[6].how = REG_SAVED_OFFSET;
85
  fs->regs.reg[6].loc.offset = (long)&sc->rbp - new_cfa;
86
  fs->regs.reg[8].how = REG_SAVED_OFFSET;
87
  fs->regs.reg[8].loc.offset = (long)&sc->r8 - new_cfa;
88
  fs->regs.reg[9].how = REG_SAVED_OFFSET;
89
  fs->regs.reg[9].loc.offset = (long)&sc->r9 - new_cfa;
90
  fs->regs.reg[10].how = REG_SAVED_OFFSET;
91
  fs->regs.reg[10].loc.offset = (long)&sc->r10 - new_cfa;
92
  fs->regs.reg[11].how = REG_SAVED_OFFSET;
93
  fs->regs.reg[11].loc.offset = (long)&sc->r11 - new_cfa;
94
  fs->regs.reg[12].how = REG_SAVED_OFFSET;
95
  fs->regs.reg[12].loc.offset = (long)&sc->r12 - new_cfa;
96
  fs->regs.reg[13].how = REG_SAVED_OFFSET;
97
  fs->regs.reg[13].loc.offset = (long)&sc->r13 - new_cfa;
98
  fs->regs.reg[14].how = REG_SAVED_OFFSET;
99
  fs->regs.reg[14].loc.offset = (long)&sc->r14 - new_cfa;
100
  fs->regs.reg[15].how = REG_SAVED_OFFSET;
101
  fs->regs.reg[15].loc.offset = (long)&sc->r15 - new_cfa;
102
  fs->regs.reg[16].how = REG_SAVED_OFFSET;
103
  fs->regs.reg[16].loc.offset = (long)&sc->rip - new_cfa;
104
  fs->retaddr_column = 16;
105
  fs->signal_frame = 1;
106
  return _URC_NO_REASON;
107
}
108
 
109
#else /* ifdef __x86_64__  */
110
 
111
/* There's no sys/ucontext.h for glibc 2.0, so no
112
   signal-turned-exceptions for them.  There's also no configure-run for
113
   the target, so we can't check on (e.g.) HAVE_SYS_UCONTEXT_H.  Using the
114
   target libc version macro should be enough.  */
115
#if defined __GLIBC__ && !(__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
116
 
117
#include <signal.h>
118
#include <sys/ucontext.h>
119
 
120
#define MD_FALLBACK_FRAME_STATE_FOR x86_fallback_frame_state
121
 
122
static _Unwind_Reason_Code
123
x86_fallback_frame_state (struct _Unwind_Context *context,
124
                          _Unwind_FrameState *fs)
125
{
126
  unsigned char *pc = context->ra;
127
  struct sigcontext *sc;
128
  long new_cfa;
129
 
130
  /* popl %eax ; movl $__NR_sigreturn,%eax ; int $0x80  */
131
  if (*(unsigned short *)(pc+0) == 0xb858
132
      && *(unsigned int *)(pc+2) == 119
133
      && *(unsigned short *)(pc+6) == 0x80cd)
134
    sc = context->cfa + 4;
135
  /* movl $__NR_rt_sigreturn,%eax ; int $0x80  */
136
  else if (*(unsigned char *)(pc+0) == 0xb8
137
           && *(unsigned int *)(pc+1) == 173
138
           && *(unsigned short *)(pc+5) == 0x80cd)
139
    {
140
      struct rt_sigframe {
141
        int sig;
142
        struct siginfo *pinfo;
143
        void *puc;
144
        struct siginfo info;
145
        struct ucontext uc;
146
      } *rt_ = context->cfa;
147
      /* The void * cast is necessary to avoid an aliasing warning.
148
         The aliasing warning is correct, but should not be a problem
149
         because it does not alias anything.  */
150
      sc = (struct sigcontext *) (void *) &rt_->uc.uc_mcontext;
151
    }
152
  else
153
    return _URC_END_OF_STACK;
154
 
155
  new_cfa = sc->esp;
156
  fs->regs.cfa_how = CFA_REG_OFFSET;
157
  fs->regs.cfa_reg = 4;
158
  fs->regs.cfa_offset = new_cfa - (long) context->cfa;
159
 
160
  /* The SVR4 register numbering macros aren't usable in libgcc.  */
161
  fs->regs.reg[0].how = REG_SAVED_OFFSET;
162
  fs->regs.reg[0].loc.offset = (long)&sc->eax - new_cfa;
163
  fs->regs.reg[3].how = REG_SAVED_OFFSET;
164
  fs->regs.reg[3].loc.offset = (long)&sc->ebx - new_cfa;
165
  fs->regs.reg[1].how = REG_SAVED_OFFSET;
166
  fs->regs.reg[1].loc.offset = (long)&sc->ecx - new_cfa;
167
  fs->regs.reg[2].how = REG_SAVED_OFFSET;
168
  fs->regs.reg[2].loc.offset = (long)&sc->edx - new_cfa;
169
  fs->regs.reg[6].how = REG_SAVED_OFFSET;
170
  fs->regs.reg[6].loc.offset = (long)&sc->esi - new_cfa;
171
  fs->regs.reg[7].how = REG_SAVED_OFFSET;
172
  fs->regs.reg[7].loc.offset = (long)&sc->edi - new_cfa;
173
  fs->regs.reg[5].how = REG_SAVED_OFFSET;
174
  fs->regs.reg[5].loc.offset = (long)&sc->ebp - new_cfa;
175
  fs->regs.reg[8].how = REG_SAVED_OFFSET;
176
  fs->regs.reg[8].loc.offset = (long)&sc->eip - new_cfa;
177
  fs->retaddr_column = 8;
178
  fs->signal_frame = 1;
179
  return _URC_NO_REASON;
180
}
181
 
182
#define MD_FROB_UPDATE_CONTEXT x86_frob_update_context
183
 
184
/* Fix up for kernels that have vDSO, but don't have S flag in it.  */
185
 
186
static void
187
x86_frob_update_context (struct _Unwind_Context *context,
188
                         _Unwind_FrameState *fs ATTRIBUTE_UNUSED)
189
{
190
  unsigned char *pc = context->ra;
191
 
192
  /* movl $__NR_rt_sigreturn,%eax ; {int $0x80 | syscall}  */
193
  if (*(unsigned char *)(pc+0) == 0xb8
194
      && *(unsigned int *)(pc+1) == 173
195
      && (*(unsigned short *)(pc+5) == 0x80cd
196
          || *(unsigned short *)(pc+5) == 0x050f))
197
    _Unwind_SetSignalFrame (context, 1);
198
}
199
 
200
#endif /* not glibc 2.0 */
201
#endif /* ifdef __x86_64__  */
202
#endif /* ifdef inhibit_libc  */

powered by: WebSVN 2.1.0

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