]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgcc/config/i386/gnu-unwind.h
Update copyright years.
[thirdparty/gcc.git] / libgcc / config / i386 / gnu-unwind.h
CommitLineData
5e2eebc8 1/* DWARF2 EH unwinding support for GNU Hurd: x86.
a945c346 2 Copyright (C) 2020-2024 Free Software Foundation, Inc.
5e2eebc8
ST
3 Contributed by Samuel Thibault <samuel.thibault@gnu.org>
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17Under Section 7 of GPL version 3, you are granted additional
18permissions described in the GCC Runtime Library Exception, version
193.1, as published by the Free Software Foundation.
20
21You should have received a copy of the GNU General Public License and
22a copy of the GCC Runtime Library Exception along with this program;
23see 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
29#ifndef inhibit_libc
30
31#include <signal.h>
32
5f8950b4
FC
33#ifdef __x86_64__
34
35/*
36 * TODO: support for 64 bits needs to be implemented.
37 */
38
39#else /* ifdef __x86_64__ */
40
5e2eebc8
ST
41#define MD_FALLBACK_FRAME_STATE_FOR x86_gnu_fallback_frame_state
42
43static _Unwind_Reason_Code
44x86_gnu_fallback_frame_state
45(struct _Unwind_Context *context, _Unwind_FrameState *fs)
46{
47 struct handler_args {
48 int signo;
2b356e68
ST
49 union
50 {
51 struct
52 {
53 long int sigcode;
54 struct sigcontext *scp;
55 } legacy;
56 struct
57 {
58 siginfo_t *siginfop;
59 ucontext_t *uctxp;
60 } posix;
61 };
5e2eebc8 62 } *handler_args;
2b356e68 63 long int sigcode;
5e2eebc8
ST
64 unsigned long usp;
65
66/*
67 * i386 sigtramp frame we are looking for follows.
68 * (see glibc/sysdeps/mach/hurd/i386/trampoline.c assembly)
69 *
70 * rpc_wait_trampoline:
71 * 0: b8 e7 ff ff ff mov $-25,%eax mach_msg_trap
72 * 5: 9a 00 00 00 00 07 00 lcall $7,$0
73 * 12: 89 01 movl %eax, (%ecx)
74 * 14: 89 dc movl %ebx, %esp switch to signal stack
75 *
76 * trampoline:
77 * 16: ff d2 call *%edx call the handler function
78 * RA HERE
79 * 18: 83 c4 0c addl $12, %esp pop its args
80 * 21: c3 ret return to sigreturn
81 *
82 * firewall:
83 * 22: f4 hlt
84 */
85
86 if (!( *(unsigned int *)(context->ra ) == 0xc30cc483
87 && *(unsigned char *)(context->ra + 4) == 0xf4
88
89 && *(unsigned int *)(context->ra - 4) == 0xd2ffdc89
90 && *(unsigned int *)(context->ra - 8) == 0x01890007
91 && *(unsigned int *)(context->ra - 12) == 0x00000000
92 && *(unsigned int *)(context->ra - 16) == 0x9affffff
93 && *(unsigned short *)(context->ra - 18) == 0xe7b8))
94 return _URC_END_OF_STACK;
95
96 handler_args = context->cfa;
2b356e68
ST
97 sigcode = handler_args->legacy.sigcode;
98 if (sigcode >= -16 && sigcode < 4096)
99 {
100 /* This cannot be a SIGINFO pointer, assume legacy. */
101 struct sigcontext *scp = handler_args->legacy.scp;
102 usp = scp->sc_uesp;
103
104 fs->regs.reg[0].loc.offset = (unsigned long)&scp->sc_eax - usp;
105 fs->regs.reg[1].loc.offset = (unsigned long)&scp->sc_ecx - usp;
106 fs->regs.reg[2].loc.offset = (unsigned long)&scp->sc_edx - usp;
107 fs->regs.reg[3].loc.offset = (unsigned long)&scp->sc_ebx - usp;
108 fs->regs.reg[5].loc.offset = (unsigned long)&scp->sc_ebp - usp;
109 fs->regs.reg[6].loc.offset = (unsigned long)&scp->sc_esi - usp;
110 fs->regs.reg[7].loc.offset = (unsigned long)&scp->sc_edi - usp;
111 fs->regs.reg[8].loc.offset = (unsigned long)&scp->sc_eip - usp;
112 }
113 else
114 {
115 /* This is not a valid sigcode, assume SIGINFO. */
116 ucontext_t *uctxp = handler_args->posix.uctxp;
117 gregset_t *gregset = &uctxp->uc_mcontext.gregs;
118 usp = (*gregset)[REG_UESP];
119
120 fs->regs.reg[0].loc.offset = (unsigned long)&(*gregset)[REG_EAX] - usp;
121 fs->regs.reg[1].loc.offset = (unsigned long)&(*gregset)[REG_ECX] - usp;
122 fs->regs.reg[2].loc.offset = (unsigned long)&(*gregset)[REG_EDX] - usp;
123 fs->regs.reg[3].loc.offset = (unsigned long)&(*gregset)[REG_EBX] - usp;
124 fs->regs.reg[5].loc.offset = (unsigned long)&(*gregset)[REG_EBP] - usp;
125 fs->regs.reg[6].loc.offset = (unsigned long)&(*gregset)[REG_ESI] - usp;
126 fs->regs.reg[7].loc.offset = (unsigned long)&(*gregset)[REG_EDI] - usp;
127 fs->regs.reg[8].loc.offset = (unsigned long)&(*gregset)[REG_EIP] - usp;
128 }
5e2eebc8
ST
129
130 fs->regs.cfa_how = CFA_REG_OFFSET;
131 fs->regs.cfa_reg = 4;
132 fs->regs.cfa_offset = usp - (unsigned long) context->cfa;
133
146e4591
JJ
134 fs->regs.how[0] = REG_SAVED_OFFSET;
135 fs->regs.how[1] = REG_SAVED_OFFSET;
136 fs->regs.how[2] = REG_SAVED_OFFSET;
137 fs->regs.how[3] = REG_SAVED_OFFSET;
138 fs->regs.how[5] = REG_SAVED_OFFSET;
139 fs->regs.how[6] = REG_SAVED_OFFSET;
140 fs->regs.how[7] = REG_SAVED_OFFSET;
141 fs->regs.how[8] = REG_SAVED_OFFSET;
2b356e68 142
5e2eebc8
ST
143 fs->retaddr_column = 8;
144 fs->signal_frame = 1;
145
146 return _URC_NO_REASON;
147}
148
5f8950b4
FC
149#endif /* ifdef __x86_64__ */
150
5e2eebc8 151#endif /* ifndef inhibit_libc */