111
|
1 /* Subroutines needed for unwinding stack frames for exception handling. */
|
145
|
2 /* Copyright (C) 1997-2020 Free Software Foundation, Inc.
|
111
|
3 Contributed by Jason Merrill <jason@cygnus.com>.
|
|
4
|
|
5 This file is part of GCC.
|
|
6
|
|
7 GCC is free software; you can redistribute it and/or modify it under
|
|
8 the terms of the GNU General Public License as published by the Free
|
|
9 Software Foundation; either version 3, or (at your option) any later
|
|
10 version.
|
|
11
|
|
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
15 for more details.
|
|
16
|
|
17 Under Section 7 of GPL version 3, you are granted additional
|
|
18 permissions described in the GCC Runtime Library Exception, version
|
|
19 3.1, as published by the Free Software Foundation.
|
|
20
|
|
21 You should have received a copy of the GNU General Public License and
|
|
22 a copy of the GCC Runtime Library Exception along with this program;
|
|
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
24 <http://www.gnu.org/licenses/>. */
|
|
25
|
|
26 #ifndef GCC_UNWIND_DW2_FDE_H
|
|
27 #define GCC_UNWIND_DW2_FDE_H
|
|
28
|
|
29 #ifndef HIDE_EXPORTS
|
|
30 #pragma GCC visibility push(default)
|
|
31 #endif
|
|
32
|
|
33 struct fde_vector
|
|
34 {
|
|
35 const void *orig_data;
|
|
36 size_t count;
|
|
37 const struct dwarf_fde *array[];
|
|
38 };
|
|
39
|
|
40 struct object
|
|
41 {
|
|
42 void *pc_begin;
|
|
43 void *tbase;
|
|
44 void *dbase;
|
|
45 union {
|
|
46 const struct dwarf_fde *single;
|
|
47 struct dwarf_fde **array;
|
|
48 struct fde_vector *sort;
|
|
49 } u;
|
|
50
|
|
51 union {
|
|
52 struct {
|
|
53 unsigned long sorted : 1;
|
|
54 unsigned long from_array : 1;
|
|
55 unsigned long mixed_encoding : 1;
|
|
56 unsigned long encoding : 8;
|
|
57 /* ??? Wish there was an easy way to detect a 64-bit host here;
|
|
58 we've got 32 bits left to play with... */
|
|
59 unsigned long count : 21;
|
|
60 } b;
|
|
61 size_t i;
|
|
62 } s;
|
|
63
|
|
64 #ifdef DWARF2_OBJECT_END_PTR_EXTENSION
|
|
65 char *fde_end;
|
|
66 #endif
|
|
67
|
|
68 struct object *next;
|
|
69 };
|
|
70
|
|
71 /* This is the original definition of struct object. While the struct
|
|
72 itself was opaque to users, they did know how large it was, and
|
|
73 allocate one statically in crtbegin for each DSO. Keep this around
|
|
74 so that we're aware of the static size limitations for the new struct. */
|
|
75 struct old_object
|
|
76 {
|
|
77 void *pc_begin;
|
|
78 void *pc_end;
|
|
79 struct dwarf_fde *fde_begin;
|
|
80 struct dwarf_fde **fde_array;
|
|
81 size_t count;
|
|
82 struct old_object *next;
|
|
83 };
|
|
84
|
|
85 struct dwarf_eh_bases
|
|
86 {
|
|
87 void *tbase;
|
|
88 void *dbase;
|
|
89 void *func;
|
|
90 };
|
|
91
|
|
92
|
|
93 extern void __register_frame_info_bases (const void *, struct object *,
|
|
94 void *, void *);
|
|
95 extern void __register_frame_info (const void *, struct object *);
|
|
96 extern void __register_frame (void *);
|
|
97 extern void __register_frame_info_table_bases (void *, struct object *,
|
|
98 void *, void *);
|
|
99 extern void __register_frame_info_table (void *, struct object *);
|
|
100 extern void __register_frame_table (void *);
|
|
101 extern void *__deregister_frame_info (const void *);
|
|
102 extern void *__deregister_frame_info_bases (const void *);
|
|
103 extern void __deregister_frame (void *);
|
|
104
|
|
105
|
|
106 typedef int sword __attribute__ ((mode (SI)));
|
|
107 typedef unsigned int uword __attribute__ ((mode (SI)));
|
|
108 typedef unsigned int uaddr __attribute__ ((mode (pointer)));
|
|
109 typedef int saddr __attribute__ ((mode (pointer)));
|
|
110 typedef unsigned char ubyte;
|
|
111
|
|
112 /* Terminology:
|
|
113 CIE - Common Information Element
|
|
114 FDE - Frame Descriptor Element
|
|
115
|
|
116 There is one per function, and it describes where the function code
|
|
117 is located, and what the register lifetimes and stack layout are
|
|
118 within the function.
|
|
119
|
|
120 The data structures are defined in the DWARF specification, although
|
|
121 not in a very readable way (see LITERATURE).
|
|
122
|
|
123 Every time an exception is thrown, the code needs to locate the FDE
|
|
124 for the current function, and starts to look for exception regions
|
|
125 from that FDE. This works in a two-level search:
|
|
126 a) in a linear search, find the shared image (i.e. DLL) containing
|
|
127 the PC
|
|
128 b) using the FDE table for that shared object, locate the FDE using
|
|
129 binary search (which requires the sorting). */
|
|
130
|
|
131 /* The first few fields of a CIE. The CIE_id field is 0 for a CIE,
|
|
132 to distinguish it from a valid FDE. FDEs are aligned to an addressing
|
|
133 unit boundary, but the fields within are unaligned. */
|
|
134 struct dwarf_cie
|
|
135 {
|
|
136 uword length;
|
|
137 sword CIE_id;
|
|
138 ubyte version;
|
|
139 unsigned char augmentation[];
|
|
140 } __attribute__ ((packed, aligned (__alignof__ (void *))));
|
|
141
|
|
142 /* The first few fields of an FDE. */
|
|
143 struct dwarf_fde
|
|
144 {
|
|
145 uword length;
|
|
146 sword CIE_delta;
|
|
147 unsigned char pc_begin[];
|
|
148 } __attribute__ ((packed, aligned (__alignof__ (void *))));
|
|
149
|
|
150 typedef struct dwarf_fde fde;
|
|
151
|
|
152 /* Locate the CIE for a given FDE. */
|
|
153
|
|
154 static inline const struct dwarf_cie *
|
|
155 get_cie (const struct dwarf_fde *f)
|
|
156 {
|
|
157 return (const void *)&f->CIE_delta - f->CIE_delta;
|
|
158 }
|
|
159
|
|
160 static inline const fde *
|
|
161 next_fde (const fde *f)
|
|
162 {
|
|
163 return (const fde *) ((const char *) f + f->length + sizeof (f->length));
|
|
164 }
|
|
165
|
|
166 extern const fde * _Unwind_Find_FDE (void *, struct dwarf_eh_bases *);
|
|
167
|
|
168 static inline int
|
|
169 last_fde (struct object *obj __attribute__ ((__unused__)), const fde *f)
|
|
170 {
|
|
171 #ifdef DWARF2_OBJECT_END_PTR_EXTENSION
|
|
172 return f == (const fde *) obj->fde_end || f->length == 0;
|
|
173 #else
|
|
174 return f->length == 0;
|
|
175 #endif
|
|
176 }
|
|
177
|
|
178 #ifndef HIDE_EXPORTS
|
|
179 #pragma GCC visibility pop
|
|
180 #endif
|
|
181
|
|
182 #endif /* unwind-dw2-fde.h */
|