1
# DP: DWARF2 EH unwinding support for AMD x86-64 and x86 KFreeBSD.
3
--- a/src/libgcc/config.host
4
+++ b/src/libgcc/config.host
6
tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm i386/t-crtstuff t-dfprules"
7
md_unwind_header=i386/linux-unwind.h
9
-i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-knetbsd*-gnu | i[34567]86-*-gnu* | i[34567]86-*-kopensolaris*-gnu)
10
+i[34567]86-*-kfreebsd*-gnu)
11
+ extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o"
12
+ tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm i386/t-crtstuff t-dfprules"
13
+ md_unwind_header=i386/freebsd-unwind.h
15
+i[34567]86-*-knetbsd*-gnu | i[34567]86-*-gnu* | i[34567]86-*-kopensolaris*-gnu)
16
extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o"
17
tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm i386/t-crtstuff t-dfprules"
20
tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm i386/t-crtstuff t-dfprules"
21
md_unwind_header=i386/linux-unwind.h
23
-x86_64-*-kfreebsd*-gnu | x86_64-*-knetbsd*-gnu)
24
+x86_64-*-kfreebsd*-gnu)
25
+ extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o"
26
+ tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm i386/t-crtstuff t-dfprules"
27
+ md_unwind_header=i386/freebsd-unwind.h
29
+x86_64-*-knetbsd*-gnu)
30
extra_parts="$extra_parts crtprec32.o crtprec64.o crtprec80.o crtfastmath.o"
31
tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm i386/t-crtstuff t-dfprules"
33
--- a/src/libgcc/config/i386/freebsd-unwind.h
34
+++ b/src/libgcc/config/i386/freebsd-unwind.h
36
+/* DWARF2 EH unwinding support for AMD x86-64 and x86.
37
+ Copyright (C) 2004-2013 Free Software Foundation, Inc.
39
+This file is part of GCC.
41
+GCC is free software; you can redistribute it and/or modify
42
+it under the terms of the GNU General Public License as published by
43
+the Free Software Foundation; either version 3, or (at your option)
46
+GCC is distributed in the hope that it will be useful,
47
+but WITHOUT ANY WARRANTY; without even the implied warranty of
48
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
49
+GNU General Public License for more details.
51
+Under Section 7 of GPL version 3, you are granted additional
52
+permissions described in the GCC Runtime Library Exception, version
53
+3.1, as published by the Free Software Foundation.
55
+You should have received a copy of the GNU General Public License and
56
+a copy of the GCC Runtime Library Exception along with this program;
57
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
58
+<http://www.gnu.org/licenses/>. */
60
+/* Do code reading to identify a signal frame, and set the frame
61
+ state data appropriately. See unwind-dw2.c for the structs.
62
+ Don't use this at all if inhibit_libc is used. */
67
+#include <sys/ucontext.h>
68
+#include <machine/sigframe.h>
72
+#define MD_FALLBACK_FRAME_STATE_FOR x86_64_fb_fallback_frame_state
74
+static _Unwind_Reason_Code
75
+x86_64_fb_fallback_frame_state (struct _Unwind_Context *context,
76
+ _Unwind_FrameState *fs)
78
+ unsigned int *pc = context->ra;
79
+ struct sigframe *sf;
82
+/* sys/amd64/amd64/sigtramp.S:
84
+ 48 8d 7c 24 10 lea 0x10(%rsp),%rdi
86
+ 48 c7 c0 a1 01 00 00 mov $0x1a1,%rax
90
+ if ( (pc[0] == 0x247c8d48U)
91
+ && (pc[1] == 0x48006a10U)
92
+ && (pc[2] == 0x01a1c0c7U)
93
+ && (pc[3] == 0x050f0000U))
95
+ sf = (struct sigframe *) context->cfa;
98
+ return _URC_END_OF_STACK;
100
+ new_cfa = sf->sf_uc.uc_mcontext.mc_rsp;
101
+ fs->regs.cfa_how = CFA_REG_OFFSET;
102
+ /* Register 7 is rsp */
103
+ fs->regs.cfa_reg = 7;
104
+ fs->regs.cfa_offset = new_cfa - (long) context->cfa;
106
+ /* The SVR4 register numbering macros aren't usable in libgcc. */
107
+ fs->regs.reg[0].how = REG_SAVED_OFFSET;
108
+ fs->regs.reg[0].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_rax - new_cfa;
109
+ fs->regs.reg[1].how = REG_SAVED_OFFSET;
110
+ fs->regs.reg[1].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_rdx - new_cfa;
111
+ fs->regs.reg[2].how = REG_SAVED_OFFSET;
112
+ fs->regs.reg[2].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_rcx - new_cfa;
113
+ fs->regs.reg[3].how = REG_SAVED_OFFSET;
114
+ fs->regs.reg[3].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_rbx - new_cfa;
115
+ fs->regs.reg[4].how = REG_SAVED_OFFSET;
116
+ fs->regs.reg[4].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_rsi - new_cfa;
117
+ fs->regs.reg[5].how = REG_SAVED_OFFSET;
118
+ fs->regs.reg[5].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_rdi - new_cfa;
119
+ fs->regs.reg[6].how = REG_SAVED_OFFSET;
120
+ fs->regs.reg[6].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_rbp - new_cfa;
121
+ fs->regs.reg[8].how = REG_SAVED_OFFSET;
122
+ fs->regs.reg[8].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_r8 - new_cfa;
123
+ fs->regs.reg[9].how = REG_SAVED_OFFSET;
124
+ fs->regs.reg[9].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_r9 - new_cfa;
125
+ fs->regs.reg[10].how = REG_SAVED_OFFSET;
126
+ fs->regs.reg[10].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_r10 - new_cfa;
127
+ fs->regs.reg[11].how = REG_SAVED_OFFSET;
128
+ fs->regs.reg[11].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_r11 - new_cfa;
129
+ fs->regs.reg[12].how = REG_SAVED_OFFSET;
130
+ fs->regs.reg[12].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_r12 - new_cfa;
131
+ fs->regs.reg[13].how = REG_SAVED_OFFSET;
132
+ fs->regs.reg[13].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_r13 - new_cfa;
133
+ fs->regs.reg[14].how = REG_SAVED_OFFSET;
134
+ fs->regs.reg[14].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_r14 - new_cfa;
135
+ fs->regs.reg[15].how = REG_SAVED_OFFSET;
136
+ fs->regs.reg[15].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_r15 - new_cfa;
137
+ fs->regs.reg[16].how = REG_SAVED_OFFSET;
138
+ fs->regs.reg[16].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_rip - new_cfa;
139
+ fs->retaddr_column = 16;
140
+ fs->signal_frame = 1;
141
+ return _URC_NO_REASON;
144
+#else /* ifdef __x86_64__ */
146
+#define MD_FALLBACK_FRAME_STATE_FOR x86_fb_fallback_frame_state
148
+static _Unwind_Reason_Code
149
+x86_fb_fallback_frame_state (struct _Unwind_Context *context,
150
+ _Unwind_FrameState *fs)
152
+ unsigned int *pc = context->ra;
153
+ struct sigframe *sf;
156
+/* sys/amd64/ia32/ia32_sigtramp.S
158
+ 8d 44 24 20 lea 0x20(%esp),%eax
160
+ b8 a1 01 00 00 mov $0x1a1,%eax
166
+/* sys/i386/i386/locore.s: sigcode()
168
+ 8d 44 24 20 lea 0x20(%esp),%eax
170
+ f7 40 54 00 00 02 00 testl $0x20000,0x54(%eax)
172
+ 8e 68 14 mov 0x14(%eax),%gs
173
+ b8 a1 01 00 00 mov $0x1a1,%eax
179
+ if ((pc[0] == 0x2024448dU)
181
+ (pc[1] == 0x01a1b850U)
182
+ && (pc[2] == 0xcd500000U)
183
+ && ((pc[3] & 0xFF) == 0x80)
187
+ (pc[4] == 0x01a1b814U)
188
+ && (pc[5] == 0xcd500000U)
189
+ && ((pc[6] & 0xFF) == 0x80)
192
+ sf = (struct sigframe *) context->cfa;
195
+ return _URC_END_OF_STACK;
197
+ new_cfa = sf->sf_uc.uc_mcontext.mc_esp;
198
+ fs->regs.cfa_how = CFA_REG_OFFSET;
199
+ fs->regs.cfa_reg = 4;
200
+ fs->regs.cfa_offset = new_cfa - (long) context->cfa;
202
+ /* The SVR4 register numbering macros aren't usable in libgcc. */
203
+ fs->regs.reg[0].how = REG_SAVED_OFFSET;
204
+ fs->regs.reg[0].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_eax - new_cfa;
205
+ fs->regs.reg[3].how = REG_SAVED_OFFSET;
206
+ fs->regs.reg[3].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_ebx - new_cfa;
207
+ fs->regs.reg[1].how = REG_SAVED_OFFSET;
208
+ fs->regs.reg[1].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_ecx - new_cfa;
209
+ fs->regs.reg[2].how = REG_SAVED_OFFSET;
210
+ fs->regs.reg[2].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_edx - new_cfa;
211
+ fs->regs.reg[6].how = REG_SAVED_OFFSET;
212
+ fs->regs.reg[6].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_esi - new_cfa;
213
+ fs->regs.reg[7].how = REG_SAVED_OFFSET;
214
+ fs->regs.reg[7].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_edi - new_cfa;
215
+ fs->regs.reg[5].how = REG_SAVED_OFFSET;
216
+ fs->regs.reg[5].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_ebp - new_cfa;
217
+ fs->regs.reg[8].how = REG_SAVED_OFFSET;
218
+ fs->regs.reg[8].loc.offset = (long)&sf->sf_uc.uc_mcontext.mc_eip - new_cfa;
219
+ fs->retaddr_column = 8;
220
+ fs->signal_frame = 1;
221
+ return _URC_NO_REASON;
224
+#endif /* ifdef __x86_64__ */
225
+#endif /* ifdef inhibit_libc */