annotate libgcc/unwind-dw2-fde.h @ 158:494b0b89df80 default tip

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