]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgcc/config/tilepro/linux-unwind.h
* symtab.c (dump_symtab_base): Fix dumping of asm lists.
[thirdparty/gcc.git] / libgcc / config / tilepro / linux-unwind.h
CommitLineData
dd552284
WL
1/* DWARF2 EH unwinding support for TILEPro.
2 Copyright (C) 2011, 2012
3 Free Software Foundation, Inc.
4 Contributed by Walter Lee (walt@tilera.com)
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3, or (at your option)
11any later version.
12
13GCC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18Under Section 7 of GPL version 3, you are granted additional
19permissions described in the GCC Runtime Library Exception, version
203.1, as published by the Free Software Foundation.
21
22You should have received a copy of the GNU General Public License and
23a copy of the GCC Runtime Library Exception along with this program;
24see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25<http://www.gnu.org/licenses/>. */
26
27#ifndef inhibit_libc
28
29#include <arch/abi.h>
30#include <signal.h>
31#include <sys/ucontext.h>
32#include <linux/unistd.h>
33
34/* Macro to define a copy of the kernel's __rt_sigreturn function
35 (in arch/tile/kernel/entry.S). If that function is changed,
36 this one needs to be changed to match it. */
37#define _sigreturn_asm(REG, NR) asm( \
38 ".pushsection .text.__rt_sigreturn,\"a\"\n" \
39 ".global __rt_sigreturn\n" \
40 ".type __rt_sigreturn,@function\n" \
41 "__rt_sigreturn:\n" \
42 "moveli " #REG ", " #NR "\n" \
43 "swint1\n" \
44 ".size __rt_sigreturn, . - __rt_sigreturn\n" \
45 ".popsection")
46#define sigreturn_asm(REG, NR) _sigreturn_asm(REG, NR)
47sigreturn_asm (TREG_SYSCALL_NR_NAME, __NR_rt_sigreturn);
48#define SIGRETURN_LEN 16
49extern char __rt_sigreturn[];
50
51#define MD_FALLBACK_FRAME_STATE_FOR tile_fallback_frame_state
52
53static _Unwind_Reason_Code
54tile_fallback_frame_state (struct _Unwind_Context *context,
55 _Unwind_FrameState *fs)
56{
57 unsigned char *pc = context->ra;
58 struct sigcontext *sc;
59 long new_cfa;
60 int i;
61
62 struct rt_sigframe {
63 unsigned char save_area[C_ABI_SAVE_AREA_SIZE];
64 struct siginfo info;
65 struct ucontext uc;
66 } *rt_;
67
68 /* Return if this is not a signal handler. */
69 if (memcmp (pc, __rt_sigreturn, SIGRETURN_LEN) != 0)
70 return _URC_END_OF_STACK;
71
72 /* It was a signal handler; update the reported PC to point to our
73 copy, since that will be findable with dladdr() and therefore
74 somewhat easier to help understand what actually happened. */
75 context->ra = __rt_sigreturn;
76
77 rt_ = context->cfa;
78 sc = &rt_->uc.uc_mcontext;
79
80 new_cfa = sc->sp;
81 fs->regs.cfa_how = CFA_REG_OFFSET;
82 fs->regs.cfa_reg = STACK_POINTER_REGNUM;
83 fs->regs.cfa_offset = new_cfa - (long) context->cfa;
84
85 for (i = 0; i < 56; ++i)
86 {
87 fs->regs.reg[i].how = REG_SAVED_OFFSET;
88 fs->regs.reg[i].loc.offset
89 = (long)&sc->gregs[i] - new_cfa;
90 }
91
92 fs->regs.reg[56].how = REG_SAVED_OFFSET;
93 fs->regs.reg[56].loc.offset = (long)&sc->pc - new_cfa;
94 fs->retaddr_column = 56;
95 fs->signal_frame = 1;
96
97 return _URC_NO_REASON;
98}
99
100#endif /* ifdef inhibit_libc */