181418a27Smrg /* DWARF2 EH unwinding support for OpenRISC Linux.
2*8d286336Smrg Copyright (C) 2018-2020 Free Software Foundation, Inc.
362a470c0Smatt
462a470c0Smatt This file is part of GCC.
562a470c0Smatt
662a470c0Smatt GCC is free software; you can redistribute it and/or modify
762a470c0Smatt it under the terms of the GNU General Public License as published by
862a470c0Smatt the Free Software Foundation; either version 3, or (at your option)
962a470c0Smatt any later version.
1062a470c0Smatt
1162a470c0Smatt GCC is distributed in the hope that it will be useful,
1262a470c0Smatt but WITHOUT ANY WARRANTY; without even the implied warranty of
1362a470c0Smatt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1462a470c0Smatt GNU General Public License for more details.
1562a470c0Smatt
1662a470c0Smatt Under Section 7 of GPL version 3, you are granted additional
1762a470c0Smatt permissions described in the GCC Runtime Library Exception, version
1862a470c0Smatt 3.1, as published by the Free Software Foundation.
1962a470c0Smatt
2062a470c0Smatt You should have received a copy of the GNU General Public License and
2162a470c0Smatt a copy of the GCC Runtime Library Exception along with this program;
2262a470c0Smatt see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2362a470c0Smatt <http://www.gnu.org/licenses/>. */
2462a470c0Smatt
2562a470c0Smatt #ifndef inhibit_libc
2681418a27Smrg /* Do code reading to identify a signal frame, and set the frame
2781418a27Smrg state data appropriately. See unwind-dw2.c for the structs. */
2862a470c0Smatt
2962a470c0Smatt #include <signal.h>
3062a470c0Smatt #include <sys/ucontext.h>
3162a470c0Smatt
3262a470c0Smatt #define MD_FALLBACK_FRAME_STATE_FOR or1k_fallback_frame_state
3362a470c0Smatt
3462a470c0Smatt static _Unwind_Reason_Code
or1k_fallback_frame_state(struct _Unwind_Context * context,_Unwind_FrameState * fs)3562a470c0Smatt or1k_fallback_frame_state (struct _Unwind_Context *context,
3662a470c0Smatt _Unwind_FrameState *fs)
3762a470c0Smatt {
3881418a27Smrg unsigned int *pc = context->ra;
3962a470c0Smatt struct rt_sigframe {
4062a470c0Smatt siginfo_t info;
4181418a27Smrg ucontext_t uc;
4281418a27Smrg } *rt;
4362a470c0Smatt struct sigcontext *sc;
4462a470c0Smatt long new_cfa;
4562a470c0Smatt int i;
4662a470c0Smatt
4781418a27Smrg if (pc[0] != 0xa960008b /* l.ori r11, r0, NR_rt_sigreturn */
4881418a27Smrg || pc[1] != 0x20000001) /* l.sys 1 */
4981418a27Smrg return _URC_END_OF_STACK;
5081418a27Smrg if (context->cfa == 0)
5162a470c0Smatt return _URC_END_OF_STACK;
5262a470c0Smatt
5381418a27Smrg rt = context->cfa;
5481418a27Smrg sc = &rt->uc.uc_mcontext;
5562a470c0Smatt
5662a470c0Smatt new_cfa = sc->regs.gpr[1];
5762a470c0Smatt fs->regs.cfa_how = CFA_REG_OFFSET;
5881418a27Smrg fs->regs.cfa_reg = 1;
5962a470c0Smatt fs->regs.cfa_offset = new_cfa - (long) context->cfa;
6081418a27Smrg for (i = 2; i < 32; ++i)
6162a470c0Smatt {
6262a470c0Smatt fs->regs.reg[i].how = REG_SAVED_OFFSET;
6362a470c0Smatt fs->regs.reg[i].loc.offset = (long) &sc->regs.gpr[i] - new_cfa;
6462a470c0Smatt }
6581418a27Smrg fs->regs.reg[32].how = REG_SAVED_OFFSET;
6681418a27Smrg fs->regs.reg[32].loc.offset = (long)&sc->regs.pc - new_cfa;
6781418a27Smrg fs->retaddr_column = 32;
6862a470c0Smatt fs->signal_frame = 1;
6962a470c0Smatt
7062a470c0Smatt return _URC_NO_REASON;
7162a470c0Smatt }
7262a470c0Smatt
7381418a27Smrg #define MD_FROB_UPDATE_CONTEXT or1k_frob_update_context
7481418a27Smrg
7581418a27Smrg /* Fix up for signal handlers that don't have S flag set. */
7681418a27Smrg
7781418a27Smrg static void
or1k_frob_update_context(struct _Unwind_Context * context,_Unwind_FrameState * fs ATTRIBUTE_UNUSED)7881418a27Smrg or1k_frob_update_context (struct _Unwind_Context *context,
7981418a27Smrg _Unwind_FrameState *fs ATTRIBUTE_UNUSED)
8081418a27Smrg {
8181418a27Smrg unsigned int *pc = context->ra;
8281418a27Smrg
8381418a27Smrg if (pc[0] == 0xa960008b /* l.ori r11, r0, NR_rt_sigreturn */
8481418a27Smrg && pc[1] == 0x20000001) /* l.sys 1 */
8581418a27Smrg _Unwind_SetSignalFrame (context, 1);
8681418a27Smrg }
8781418a27Smrg #endif
88