summaryrefslogtreecommitdiff
path: root/lang/gcc49/patches/patch-libgcc_config_i386_dragonfly-unwind.h
blob: 8d712d87488e76fc1d8a70439608b5d0f0d43a7a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
$NetBSD: patch-libgcc_config_i386_dragonfly-unwind.h,v 1.1 2014/09/04 18:43:11 jperkin Exp $

Support DragonFly.

--- libgcc/config/i386/dragonfly-unwind.h.orig	2014-09-04 10:04:27.455838710 +0000
+++ libgcc/config/i386/dragonfly-unwind.h
@@ -0,0 +1,158 @@
+/* DWARF2 EH unwinding support for DragonFly BSD: AMD x86-64 and x86.
+   Copyright (C) 2010 John Marino <draco@marino.st> */
+
+/* Do code reading to identify a signal frame, and set the frame
+   state data appropriately.  See unwind-dw2.c for the structs. */
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <signal.h>
+#include <sys/ucontext.h>
+#include <machine/sigframe.h>
+
+
+#define REG_NAME(reg)	sf_uc.uc_mcontext.mc_## reg
+
+#ifdef __x86_64__
+#define MD_FALLBACK_FRAME_STATE_FOR x86_64_dragonfly_fallback_frame_state
+
+
+static void
+x86_64_sigtramp_range (unsigned char **start, unsigned char **end)
+{
+  unsigned long ps_strings;
+  int mib[2];
+  size_t len;
+
+  mib[0] = CTL_KERN;
+  mib[1] = KERN_PS_STRINGS;
+  len = sizeof (ps_strings);
+  sysctl (mib, 2, &ps_strings, &len, NULL, 0);
+
+  *start = (unsigned char *)ps_strings - 32;
+  *end   = (unsigned char *)ps_strings;
+}
+
+
+static _Unwind_Reason_Code
+x86_64_dragonfly_fallback_frame_state
+(struct _Unwind_Context *context, _Unwind_FrameState *fs)
+{
+  unsigned char *pc = context->ra;
+  unsigned char *sigtramp_start, *sigtramp_end;
+  struct sigframe *sf;
+  long new_cfa;
+
+  x86_64_sigtramp_range(&sigtramp_start, &sigtramp_end);
+  if (pc >= sigtramp_end || pc < sigtramp_start)
+    return _URC_END_OF_STACK;
+
+  sf = (struct sigframe *) context->cfa;
+  new_cfa = sf->REG_NAME(rsp);
+  fs->regs.cfa_how = CFA_REG_OFFSET;
+  /* Register 7 is rsp  */
+  fs->regs.cfa_reg = 7;
+  fs->regs.cfa_offset = new_cfa - (long) context->cfa;
+
+  /* The SVR4 register numbering macros aren't usable in libgcc.  */
+  fs->regs.reg[0].how = REG_SAVED_OFFSET;
+  fs->regs.reg[0].loc.offset = (long)&sf->REG_NAME(rax) - new_cfa;
+  fs->regs.reg[1].how = REG_SAVED_OFFSET;
+  fs->regs.reg[1].loc.offset = (long)&sf->REG_NAME(rdx) - new_cfa;
+  fs->regs.reg[2].how = REG_SAVED_OFFSET;
+  fs->regs.reg[2].loc.offset = (long)&sf->REG_NAME(rcx) - new_cfa;
+  fs->regs.reg[3].how = REG_SAVED_OFFSET;
+  fs->regs.reg[3].loc.offset = (long)&sf->REG_NAME(rbx) - new_cfa;
+  fs->regs.reg[4].how = REG_SAVED_OFFSET;
+  fs->regs.reg[4].loc.offset = (long)&sf->REG_NAME(rsi) - new_cfa;
+  fs->regs.reg[5].how = REG_SAVED_OFFSET;
+  fs->regs.reg[5].loc.offset = (long)&sf->REG_NAME(rdi) - new_cfa;
+  fs->regs.reg[6].how = REG_SAVED_OFFSET;
+  fs->regs.reg[6].loc.offset = (long)&sf->REG_NAME(rbp) - new_cfa;
+  fs->regs.reg[8].how = REG_SAVED_OFFSET;
+  fs->regs.reg[8].loc.offset = (long)&sf->REG_NAME(r8) - new_cfa;
+  fs->regs.reg[9].how = REG_SAVED_OFFSET;
+  fs->regs.reg[9].loc.offset = (long)&sf->REG_NAME(r9) - new_cfa;
+  fs->regs.reg[10].how = REG_SAVED_OFFSET;
+  fs->regs.reg[10].loc.offset = (long)&sf->REG_NAME(r10) - new_cfa;
+  fs->regs.reg[11].how = REG_SAVED_OFFSET;
+  fs->regs.reg[11].loc.offset = (long)&sf->REG_NAME(r11) - new_cfa;
+  fs->regs.reg[12].how = REG_SAVED_OFFSET;
+  fs->regs.reg[12].loc.offset = (long)&sf->REG_NAME(r12) - new_cfa;
+  fs->regs.reg[13].how = REG_SAVED_OFFSET;
+  fs->regs.reg[13].loc.offset = (long)&sf->REG_NAME(r13) - new_cfa;
+  fs->regs.reg[14].how = REG_SAVED_OFFSET;
+  fs->regs.reg[14].loc.offset = (long)&sf->REG_NAME(r14) - new_cfa;
+  fs->regs.reg[15].how = REG_SAVED_OFFSET;
+  fs->regs.reg[15].loc.offset = (long)&sf->REG_NAME(r15) - new_cfa;
+  fs->regs.reg[16].how = REG_SAVED_OFFSET;
+  fs->regs.reg[16].loc.offset = (long)&sf->REG_NAME(rip) - new_cfa;
+  fs->retaddr_column = 16;
+  fs->signal_frame = 1;
+  return _URC_NO_REASON;
+}
+
+#else /* Next section is for i386  */
+
+#define MD_FALLBACK_FRAME_STATE_FOR x86_dragonfly_fallback_frame_state
+
+
+static void
+x86_sigtramp_range (unsigned char **start, unsigned char **end)
+{
+  unsigned long ps_strings;
+  int mib[2];
+  size_t len;
+
+  mib[0] = CTL_KERN;
+  mib[1] = KERN_PS_STRINGS;
+  len = sizeof (ps_strings);
+  sysctl (mib, 2, &ps_strings, &len, NULL, 0);
+
+  *start = (unsigned char *)ps_strings - 128;
+  *end   = (unsigned char *)ps_strings;
+}
+
+
+static _Unwind_Reason_Code
+x86_dragonfly_fallback_frame_state
+(struct _Unwind_Context *context, _Unwind_FrameState *fs)
+{
+  unsigned char *pc = context->ra;
+  unsigned char *sigtramp_start, *sigtramp_end;
+  struct sigframe *sf;
+  long new_cfa;
+
+  x86_sigtramp_range(&sigtramp_start, &sigtramp_end);
+
+  if (pc >= sigtramp_end || pc < sigtramp_start)
+    return _URC_END_OF_STACK;
+
+  sf = (struct sigframe *) context->cfa;
+  new_cfa = sf->REG_NAME(esp);
+  fs->regs.cfa_how = CFA_REG_OFFSET;
+  fs->regs.cfa_reg = 4;
+  fs->regs.cfa_offset = new_cfa - (long) context->cfa;
+
+  /* The SVR4 register numbering macros aren't usable in libgcc.  */
+  fs->regs.reg[0].how = REG_SAVED_OFFSET;
+  fs->regs.reg[0].loc.offset = (long)&sf->REG_NAME(eax) - new_cfa;
+  fs->regs.reg[3].how = REG_SAVED_OFFSET;
+  fs->regs.reg[3].loc.offset = (long)&sf->REG_NAME(ebx) - new_cfa;
+  fs->regs.reg[1].how = REG_SAVED_OFFSET;
+  fs->regs.reg[1].loc.offset = (long)&sf->REG_NAME(ecx) - new_cfa;
+  fs->regs.reg[2].how = REG_SAVED_OFFSET;
+  fs->regs.reg[2].loc.offset = (long)&sf->REG_NAME(edx) - new_cfa;
+  fs->regs.reg[6].how = REG_SAVED_OFFSET;
+  fs->regs.reg[6].loc.offset = (long)&sf->REG_NAME(esi) - new_cfa;
+  fs->regs.reg[7].how = REG_SAVED_OFFSET;
+  fs->regs.reg[7].loc.offset = (long)&sf->REG_NAME(edi) - new_cfa;
+  fs->regs.reg[5].how = REG_SAVED_OFFSET;
+  fs->regs.reg[5].loc.offset = (long)&sf->REG_NAME(ebp) - new_cfa;
+  fs->regs.reg[8].how = REG_SAVED_OFFSET;
+  fs->regs.reg[8].loc.offset = (long)&sf->REG_NAME(eip) - new_cfa;
+  fs->retaddr_column = 8;
+  fs->signal_frame = 1;
+  return _URC_NO_REASON;
+}
+#endif /* ifdef __x86_64__  */