1 | /* dwarf2out.h - Various declarations for functions found in dwarf2out.cc |
2 | Copyright (C) 1998-2023 Free Software Foundation, Inc. |
3 | |
4 | This file is part of GCC. |
5 | |
6 | GCC is free software; you can redistribute it and/or modify it under |
7 | the terms of the GNU General Public License as published by the Free |
8 | Software Foundation; either version 3, or (at your option) any later |
9 | version. |
10 | |
11 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
12 | WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
14 | for more details. |
15 | |
16 | You should have received a copy of the GNU General Public License |
17 | along with GCC; see the file COPYING3. If not see |
18 | <http://www.gnu.org/licenses/>. */ |
19 | |
20 | #ifndef GCC_DWARF2OUT_H |
21 | #define GCC_DWARF2OUT_H 1 |
22 | |
23 | #include "dwarf2.h" /* ??? Remove this once only used by dwarf2foo.c. */ |
24 | |
25 | typedef struct die_struct *dw_die_ref; |
26 | typedef const struct die_struct *const_dw_die_ref; |
27 | |
28 | typedef struct dw_val_node *dw_val_ref; |
29 | typedef struct dw_cfi_node *dw_cfi_ref; |
30 | typedef struct dw_loc_descr_node *dw_loc_descr_ref; |
31 | typedef struct dw_loc_list_struct *dw_loc_list_ref; |
32 | typedef struct dw_discr_list_node *dw_discr_list_ref; |
33 | typedef struct dw_wide_int *dw_wide_int_ptr; |
34 | |
35 | |
36 | /* Call frames are described using a sequence of Call Frame |
37 | Information instructions. The register number, offset |
38 | and address fields are provided as possible operands; |
39 | their use is selected by the opcode field. */ |
40 | |
41 | enum dw_cfi_oprnd_type { |
42 | dw_cfi_oprnd_unused, |
43 | dw_cfi_oprnd_reg_num, |
44 | dw_cfi_oprnd_offset, |
45 | dw_cfi_oprnd_addr, |
46 | dw_cfi_oprnd_loc, |
47 | dw_cfi_oprnd_cfa_loc |
48 | }; |
49 | |
50 | typedef union GTY(()) { |
51 | unsigned int GTY ((tag ("dw_cfi_oprnd_reg_num" ))) dw_cfi_reg_num; |
52 | HOST_WIDE_INT GTY ((tag ("dw_cfi_oprnd_offset" ))) dw_cfi_offset; |
53 | const char * GTY ((tag ("dw_cfi_oprnd_addr" ))) dw_cfi_addr; |
54 | struct dw_loc_descr_node * GTY ((tag ("dw_cfi_oprnd_loc" ))) dw_cfi_loc; |
55 | struct dw_cfa_location * GTY ((tag ("dw_cfi_oprnd_cfa_loc" ))) |
56 | dw_cfi_cfa_loc; |
57 | } dw_cfi_oprnd; |
58 | |
59 | struct GTY(()) dw_cfi_node { |
60 | enum dwarf_call_frame_info dw_cfi_opc; |
61 | dw_cfi_oprnd GTY ((desc ("dw_cfi_oprnd1_desc (%1.dw_cfi_opc)" ))) |
62 | dw_cfi_oprnd1; |
63 | dw_cfi_oprnd GTY ((desc ("dw_cfi_oprnd2_desc (%1.dw_cfi_opc)" ))) |
64 | dw_cfi_oprnd2; |
65 | }; |
66 | |
67 | |
68 | typedef vec<dw_cfi_ref, va_gc> *cfi_vec; |
69 | |
70 | typedef struct dw_fde_node *dw_fde_ref; |
71 | |
72 | /* All call frame descriptions (FDE's) in the GCC generated DWARF |
73 | refer to a single Common Information Entry (CIE), defined at |
74 | the beginning of the .debug_frame section. This use of a single |
75 | CIE obviates the need to keep track of multiple CIE's |
76 | in the DWARF generation routines below. */ |
77 | |
78 | struct GTY(()) dw_fde_node { |
79 | tree decl; |
80 | const char *dw_fde_begin; |
81 | const char *dw_fde_current_label; |
82 | const char *dw_fde_end; |
83 | const char *dw_fde_vms_end_prologue; |
84 | const char *dw_fde_vms_begin_epilogue; |
85 | const char *dw_fde_second_begin; |
86 | const char *dw_fde_second_end; |
87 | cfi_vec dw_fde_cfi; |
88 | int dw_fde_switch_cfi_index; /* Last CFI before switching sections. */ |
89 | HOST_WIDE_INT stack_realignment; |
90 | |
91 | unsigned funcdef_number; |
92 | unsigned fde_index; |
93 | |
94 | /* Dynamic realign argument pointer register. */ |
95 | unsigned int drap_reg; |
96 | /* Virtual dynamic realign argument pointer register. */ |
97 | unsigned int vdrap_reg; |
98 | /* These 3 flags are copied from rtl_data in function.h. */ |
99 | unsigned all_throwers_are_sibcalls : 1; |
100 | unsigned uses_eh_lsda : 1; |
101 | unsigned nothrow : 1; |
102 | /* Whether we did stack realign in this call frame. */ |
103 | unsigned stack_realign : 1; |
104 | /* Whether dynamic realign argument pointer register has been saved. */ |
105 | unsigned drap_reg_saved: 1; |
106 | /* True iff dw_fde_begin label is in text_section or cold_text_section. */ |
107 | unsigned in_std_section : 1; |
108 | /* True iff dw_fde_second_begin label is in text_section or |
109 | cold_text_section. */ |
110 | unsigned second_in_std_section : 1; |
111 | /* True if Rule 18 described in dwarf2cfi.cc is in action, i.e. for dynamic |
112 | stack realignment in between pushing of hard frame pointer to stack |
113 | and setting hard frame pointer to stack pointer. The register save for |
114 | hard frame pointer register should be emitted only on the latter |
115 | instruction. */ |
116 | unsigned rule18 : 1; |
117 | /* True if this function is to be ignored by debugger. */ |
118 | unsigned ignored_debug : 1; |
119 | }; |
120 | |
121 | |
122 | /* This represents a register, in DWARF_FRAME_REGNUM space, for use in CFA |
123 | definitions and expressions. |
124 | Most architectures only need a single register number, but some (amdgcn) |
125 | have pointers that span multiple registers. DWARF permits arbitrary |
126 | register sets but existing use-cases only require contiguous register |
127 | sets, as represented here. */ |
128 | struct GTY(()) cfa_reg { |
129 | unsigned int reg; |
130 | unsigned short span; |
131 | unsigned short span_width; /* A.K.A. register mode size. */ |
132 | |
133 | cfa_reg& set_by_dwreg (unsigned int r) |
134 | { |
135 | reg = r; |
136 | span = 1; |
137 | span_width = 0; /* Unknown size (permitted when span == 1). */ |
138 | return *this; |
139 | } |
140 | |
141 | bool operator== (const cfa_reg &other) const |
142 | { |
143 | return (reg == other.reg && span == other.span |
144 | && (span_width == other.span_width |
145 | || (span == 1 |
146 | && (span_width == 0 || other.span_width == 0)))); |
147 | } |
148 | |
149 | bool operator!= (const cfa_reg &other) const |
150 | { |
151 | return !(*this == other); |
152 | } |
153 | }; |
154 | |
155 | /* This is how we define the location of the CFA. We use to handle it |
156 | as REG + OFFSET all the time, but now it can be more complex. |
157 | It can now be either REG + CFA_OFFSET or *(REG + BASE_OFFSET) + CFA_OFFSET. |
158 | Instead of passing around REG and OFFSET, we pass a copy |
159 | of this structure. */ |
160 | struct GTY(()) dw_cfa_location { |
161 | poly_int64 offset; |
162 | poly_int64 base_offset; |
163 | /* REG is in DWARF_FRAME_REGNUM space, *not* normal REGNO space. */ |
164 | struct cfa_reg reg; |
165 | BOOL_BITFIELD indirect : 1; /* 1 if CFA is accessed via a dereference. */ |
166 | BOOL_BITFIELD in_use : 1; /* 1 if a saved cfa is stored here. */ |
167 | }; |
168 | |
169 | |
170 | /* Each DIE may have a series of attribute/value pairs. Values |
171 | can take on several forms. The forms that are used in this |
172 | implementation are listed below. */ |
173 | |
174 | enum dw_val_class |
175 | { |
176 | dw_val_class_none, |
177 | dw_val_class_addr, |
178 | dw_val_class_offset, |
179 | dw_val_class_loc, |
180 | dw_val_class_loc_list, |
181 | dw_val_class_range_list, |
182 | dw_val_class_const, |
183 | dw_val_class_unsigned_const, |
184 | dw_val_class_const_double, |
185 | dw_val_class_wide_int, |
186 | dw_val_class_vec, |
187 | dw_val_class_flag, |
188 | dw_val_class_die_ref, |
189 | dw_val_class_fde_ref, |
190 | dw_val_class_lbl_id, |
191 | dw_val_class_lineptr, |
192 | dw_val_class_str, |
193 | dw_val_class_macptr, |
194 | dw_val_class_loclistsptr, |
195 | dw_val_class_file, |
196 | dw_val_class_data8, |
197 | dw_val_class_decl_ref, |
198 | dw_val_class_vms_delta, |
199 | dw_val_class_high_pc, |
200 | dw_val_class_discr_value, |
201 | dw_val_class_discr_list, |
202 | dw_val_class_const_implicit, |
203 | dw_val_class_unsigned_const_implicit, |
204 | dw_val_class_file_implicit, |
205 | dw_val_class_view_list, |
206 | dw_val_class_symview |
207 | }; |
208 | |
209 | /* Describe a floating point constant value, or a vector constant value. */ |
210 | |
211 | struct GTY(()) dw_vec_const { |
212 | void * GTY((atomic)) array; |
213 | unsigned length; |
214 | unsigned elt_size; |
215 | }; |
216 | |
217 | /* Describe a single value that a discriminant can match. |
218 | |
219 | Discriminants (in the "record variant part" meaning) are scalars. |
220 | dw_discr_list_ref and dw_discr_value are a mean to describe a set of |
221 | discriminant values that are matched by a particular variant. |
222 | |
223 | Discriminants can be signed or unsigned scalars, and can be discriminants |
224 | values. Both have to be consistent, though. */ |
225 | |
226 | struct GTY(()) dw_discr_value { |
227 | int pos; /* Whether the discriminant value is positive (unsigned). */ |
228 | union |
229 | { |
230 | HOST_WIDE_INT GTY ((tag ("0" ))) sval; |
231 | unsigned HOST_WIDE_INT GTY ((tag ("1" ))) uval; |
232 | } |
233 | GTY ((desc ("%1.pos" ))) v; |
234 | }; |
235 | |
236 | struct addr_table_entry; |
237 | |
238 | /* The dw_val_node describes an attribute's value, as it is |
239 | represented internally. */ |
240 | |
241 | struct GTY(()) dw_val_node { |
242 | enum dw_val_class val_class; |
243 | struct addr_table_entry * GTY(()) val_entry; |
244 | union dw_val_struct_union |
245 | { |
246 | rtx GTY ((tag ("dw_val_class_addr" ))) val_addr; |
247 | unsigned HOST_WIDE_INT GTY ((tag ("dw_val_class_offset" ))) val_offset; |
248 | dw_loc_list_ref GTY ((tag ("dw_val_class_loc_list" ))) val_loc_list; |
249 | dw_die_ref GTY ((tag ("dw_val_class_view_list" ))) val_view_list; |
250 | dw_loc_descr_ref GTY ((tag ("dw_val_class_loc" ))) val_loc; |
251 | HOST_WIDE_INT GTY ((default)) val_int; |
252 | unsigned HOST_WIDE_INT |
253 | GTY ((tag ("dw_val_class_unsigned_const" ))) val_unsigned; |
254 | double_int GTY ((tag ("dw_val_class_const_double" ))) val_double; |
255 | dw_wide_int_ptr GTY ((tag ("dw_val_class_wide_int" ))) val_wide; |
256 | dw_vec_const GTY ((tag ("dw_val_class_vec" ))) val_vec; |
257 | struct dw_val_die_union |
258 | { |
259 | dw_die_ref die; |
260 | int external; |
261 | } GTY ((tag ("dw_val_class_die_ref" ))) val_die_ref; |
262 | unsigned GTY ((tag ("dw_val_class_fde_ref" ))) val_fde_index; |
263 | struct indirect_string_node * GTY ((tag ("dw_val_class_str" ))) val_str; |
264 | char * GTY ((tag ("dw_val_class_lbl_id" ))) val_lbl_id; |
265 | unsigned char GTY ((tag ("dw_val_class_flag" ))) val_flag; |
266 | struct dwarf_file_data * GTY ((tag ("dw_val_class_file" ))) val_file; |
267 | struct dwarf_file_data * |
268 | GTY ((tag ("dw_val_class_file_implicit" ))) val_file_implicit; |
269 | unsigned char GTY ((tag ("dw_val_class_data8" ))) val_data8[8]; |
270 | tree GTY ((tag ("dw_val_class_decl_ref" ))) val_decl_ref; |
271 | struct dw_val_vms_delta_union |
272 | { |
273 | char * lbl1; |
274 | char * lbl2; |
275 | } GTY ((tag ("dw_val_class_vms_delta" ))) val_vms_delta; |
276 | dw_discr_value GTY ((tag ("dw_val_class_discr_value" ))) val_discr_value; |
277 | dw_discr_list_ref GTY ((tag ("dw_val_class_discr_list" ))) val_discr_list; |
278 | char * GTY ((tag ("dw_val_class_symview" ))) val_symbolic_view; |
279 | } |
280 | GTY ((desc ("%1.val_class" ))) v; |
281 | }; |
282 | |
283 | /* Locations in memory are described using a sequence of stack machine |
284 | operations. */ |
285 | |
286 | struct GTY((chain_next ("%h.dw_loc_next" ))) dw_loc_descr_node { |
287 | dw_loc_descr_ref dw_loc_next; |
288 | ENUM_BITFIELD (dwarf_location_atom) dw_loc_opc : 8; |
289 | /* Used to distinguish DW_OP_addr with a direct symbol relocation |
290 | from DW_OP_addr with a dtp-relative symbol relocation. */ |
291 | unsigned int dtprel : 1; |
292 | /* For DW_OP_pick, DW_OP_dup and DW_OP_over operations: true iff. |
293 | it targets a DWARF prodecure argument. In this case, it needs to be |
294 | relocated according to the current frame offset. */ |
295 | unsigned int frame_offset_rel : 1; |
296 | int dw_loc_addr; |
297 | dw_val_node dw_loc_oprnd1; |
298 | dw_val_node dw_loc_oprnd2; |
299 | }; |
300 | |
301 | /* A variant (inside a record variant part) is selected when the corresponding |
302 | discriminant matches its set of values (see the comment for dw_discr_value). |
303 | The following datastructure holds such matching information. */ |
304 | |
305 | struct GTY(()) dw_discr_list_node { |
306 | dw_discr_list_ref dw_discr_next; |
307 | |
308 | dw_discr_value dw_discr_lower_bound; |
309 | dw_discr_value dw_discr_upper_bound; |
310 | /* This node represents only the value in dw_discr_lower_bound when it's |
311 | zero. It represents the range between the two fields (bounds included) |
312 | otherwise. */ |
313 | int dw_discr_range; |
314 | }; |
315 | |
316 | struct GTY((variable_size)) dw_wide_int { |
317 | unsigned int precision; |
318 | unsigned int len; |
319 | HOST_WIDE_INT val[1]; |
320 | |
321 | unsigned int get_precision () const { return precision; } |
322 | unsigned int get_len () const { return len; } |
323 | const HOST_WIDE_INT *get_val () const { return val; } |
324 | inline HOST_WIDE_INT elt (unsigned int) const; |
325 | inline bool operator == (const dw_wide_int &) const; |
326 | }; |
327 | |
328 | inline HOST_WIDE_INT |
329 | dw_wide_int::elt (unsigned int i) const |
330 | { |
331 | if (i < len) |
332 | return val[i]; |
333 | wide_int_ref ref = wi::storage_ref (val, len, precision); |
334 | return wi::sign_mask (x: ref); |
335 | } |
336 | |
337 | inline bool |
338 | dw_wide_int::operator == (const dw_wide_int &o) const |
339 | { |
340 | wide_int_ref ref1 = wi::storage_ref (val, len, precision); |
341 | wide_int_ref ref2 = wi::storage_ref (o.val, o.len, o.precision); |
342 | return ref1 == ref2; |
343 | } |
344 | |
345 | /* Interface from dwarf2out.cc to dwarf2cfi.cc. */ |
346 | extern struct dw_loc_descr_node *build_cfa_loc |
347 | (dw_cfa_location *, poly_int64); |
348 | extern struct dw_loc_descr_node *build_cfa_aligned_loc |
349 | (dw_cfa_location *, poly_int64, HOST_WIDE_INT); |
350 | extern struct dw_loc_descr_node *build_span_loc (struct cfa_reg); |
351 | extern struct dw_loc_descr_node *mem_loc_descriptor |
352 | (rtx, machine_mode mode, machine_mode mem_mode, |
353 | enum var_init_status); |
354 | extern bool loc_descr_equal_p (dw_loc_descr_ref, dw_loc_descr_ref); |
355 | extern dw_fde_ref dwarf2out_alloc_current_fde (void); |
356 | |
357 | extern unsigned long size_of_locs (dw_loc_descr_ref); |
358 | extern void output_loc_sequence (dw_loc_descr_ref, int); |
359 | extern void output_loc_sequence_raw (dw_loc_descr_ref); |
360 | |
361 | /* Interface from dwarf2cfi.cc to dwarf2out.cc. */ |
362 | extern void lookup_cfa_1 (dw_cfi_ref cfi, dw_cfa_location *loc, |
363 | dw_cfa_location *remember); |
364 | extern bool cfa_equal_p (const dw_cfa_location *, const dw_cfa_location *); |
365 | |
366 | extern void output_cfi (dw_cfi_ref, dw_fde_ref, int); |
367 | |
368 | extern GTY(()) cfi_vec cie_cfi_vec; |
369 | |
370 | /* Interface from dwarf2*.c to the rest of the compiler. */ |
371 | extern enum dw_cfi_oprnd_type dw_cfi_oprnd1_desc |
372 | (enum dwarf_call_frame_info cfi); |
373 | extern enum dw_cfi_oprnd_type dw_cfi_oprnd2_desc |
374 | (enum dwarf_call_frame_info cfi); |
375 | |
376 | extern void output_cfi_directive (FILE *f, struct dw_cfi_node *cfi); |
377 | |
378 | extern void dwarf2out_emit_cfi (dw_cfi_ref cfi); |
379 | |
380 | extern void debug_dwarf (void); |
381 | struct die_struct; |
382 | extern void debug_dwarf_die (struct die_struct *); |
383 | extern void debug_dwarf_loc_descr (dw_loc_descr_ref); |
384 | extern void debug (die_struct &ref); |
385 | extern void debug (die_struct *ptr); |
386 | extern void dwarf2out_set_demangle_name_func (const char *(*) (const char *)); |
387 | #ifdef VMS_DEBUGGING_INFO |
388 | extern void dwarf2out_vms_debug_main_pointer (void); |
389 | #endif |
390 | |
391 | enum array_descr_ordering |
392 | { |
393 | array_descr_ordering_default, |
394 | array_descr_ordering_row_major, |
395 | array_descr_ordering_column_major |
396 | }; |
397 | |
398 | #define DWARF2OUT_ARRAY_DESCR_INFO_MAX_DIMEN 16 |
399 | |
400 | struct array_descr_info |
401 | { |
402 | int ndimensions; |
403 | enum array_descr_ordering ordering; |
404 | tree element_type; |
405 | tree base_decl; |
406 | tree data_location; |
407 | tree allocated; |
408 | tree associated; |
409 | tree stride; |
410 | tree rank; |
411 | bool stride_in_bits; |
412 | struct array_descr_dimen |
413 | { |
414 | /* GCC uses sizetype for array indices, so lower_bound and upper_bound |
415 | will likely be "sizetype" values. However, bounds may have another |
416 | type in the original source code. */ |
417 | tree bounds_type; |
418 | tree lower_bound; |
419 | tree upper_bound; |
420 | |
421 | /* Only Fortran uses more than one dimension for array types. For other |
422 | languages, the stride can be rather specified for the whole array. */ |
423 | tree stride; |
424 | } dimen[DWARF2OUT_ARRAY_DESCR_INFO_MAX_DIMEN]; |
425 | }; |
426 | |
427 | enum fixed_point_scale_factor |
428 | { |
429 | fixed_point_scale_factor_binary, |
430 | fixed_point_scale_factor_decimal, |
431 | fixed_point_scale_factor_arbitrary |
432 | }; |
433 | |
434 | struct fixed_point_type_info |
435 | { |
436 | /* The scale factor is the value one has to multiply the actual data with |
437 | to get the fixed point value. We support three ways to encode it. */ |
438 | enum fixed_point_scale_factor scale_factor_kind; |
439 | union |
440 | { |
441 | /* For a binary scale factor, the scale factor is 2 ** binary. */ |
442 | int binary; |
443 | /* For a decimal scale factor, the scale factor is 10 ** decimal. */ |
444 | int decimal; |
445 | /* For an arbitrary scale factor, the scale factor is the ratio |
446 | numerator / denominator. */ |
447 | struct { tree numerator; tree denominator; } arbitrary; |
448 | } scale_factor; |
449 | }; |
450 | |
451 | void dwarf2cfi_cc_finalize (void); |
452 | void dwarf2out_cc_finalize (void); |
453 | |
454 | /* Some DWARF internals are exposed for the needs of DWARF-based debug |
455 | formats. */ |
456 | |
457 | /* Each DIE attribute has a field specifying the attribute kind, |
458 | a link to the next attribute in the chain, and an attribute value. |
459 | Attributes are typically linked below the DIE they modify. */ |
460 | |
461 | typedef struct GTY(()) dw_attr_struct { |
462 | enum dwarf_attribute dw_attr; |
463 | dw_val_node dw_attr_val; |
464 | } |
465 | dw_attr_node; |
466 | |
467 | extern dw_attr_node *get_AT (dw_die_ref, enum dwarf_attribute); |
468 | extern HOST_WIDE_INT AT_int (dw_attr_node *); |
469 | extern unsigned HOST_WIDE_INT AT_unsigned (dw_attr_node *a); |
470 | extern dw_loc_descr_ref AT_loc (dw_attr_node *); |
471 | extern dw_die_ref get_AT_ref (dw_die_ref, enum dwarf_attribute); |
472 | extern const char *get_AT_string (dw_die_ref, enum dwarf_attribute); |
473 | extern enum dw_val_class AT_class (dw_attr_node *); |
474 | extern unsigned HOST_WIDE_INT AT_unsigned (dw_attr_node *); |
475 | extern unsigned get_AT_unsigned (dw_die_ref, enum dwarf_attribute); |
476 | extern int get_AT_flag (dw_die_ref, enum dwarf_attribute); |
477 | |
478 | extern void add_name_attribute (dw_die_ref, const char *); |
479 | |
480 | extern dw_die_ref new_die_raw (enum dwarf_tag); |
481 | extern dw_die_ref base_type_die (tree, bool); |
482 | |
483 | extern dw_die_ref lookup_decl_die (tree); |
484 | extern dw_die_ref lookup_type_die (tree); |
485 | |
486 | extern dw_die_ref dw_get_die_child (dw_die_ref); |
487 | extern dw_die_ref dw_get_die_sib (dw_die_ref); |
488 | extern enum dwarf_tag dw_get_die_tag (dw_die_ref); |
489 | |
490 | /* Data about a single source file. */ |
491 | struct GTY((for_user)) dwarf_file_data { |
492 | const char * key; |
493 | const char * filename; |
494 | int emitted_number; |
495 | }; |
496 | |
497 | extern struct dwarf_file_data *get_AT_file (dw_die_ref, |
498 | enum dwarf_attribute); |
499 | |
500 | #endif /* GCC_DWARF2OUT_H */ |
501 | |