Commit | Line | Data |
---|---|---|
1a59d1b8 | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
e0d153c6 MH |
2 | #ifndef _DWARF_AUX_H |
3 | #define _DWARF_AUX_H | |
4 | /* | |
5 | * dwarf-aux.h : libdw auxiliary interfaces | |
e0d153c6 MH |
6 | */ |
7 | ||
8 | #include <dwarf.h> | |
9 | #include <elfutils/libdw.h> | |
10 | #include <elfutils/libdwfl.h> | |
11 | #include <elfutils/version.h> | |
12 | ||
8520a98d ACM |
13 | struct strbuf; |
14 | ||
e0d153c6 | 15 | /* Find the realpath of the target file */ |
3938bad4 | 16 | const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname); |
e0d153c6 MH |
17 | |
18 | /* Get DW_AT_comp_dir (should be NULL with older gcc) */ | |
3938bad4 | 19 | const char *cu_get_comp_dir(Dwarf_Die *cu_die); |
e0d153c6 MH |
20 | |
21 | /* Get a line number and file name for given address */ | |
22a66551 | 22 | int cu_find_lineinfo(Dwarf_Die *cudie, Dwarf_Addr addr, |
3938bad4 | 23 | const char **fname, int *lineno); |
e0d153c6 | 24 | |
4d39c89f | 25 | /* Walk on functions at given address */ |
3938bad4 ACM |
26 | int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr, |
27 | int (*callback)(Dwarf_Die *, void *), void *data); | |
221d0611 | 28 | |
d5a00296 MH |
29 | /* Get DW_AT_linkage_name (should be NULL for C binary) */ |
30 | const char *die_get_linkage_name(Dwarf_Die *dw_die); | |
31 | ||
91e2f539 MH |
32 | /* Get the lowest PC in DIE (including range list) */ |
33 | int die_entrypc(Dwarf_Die *dw_die, Dwarf_Addr *addr); | |
34 | ||
0dbb1cac | 35 | /* Ensure that this DIE is a subprogram and definition (not declaration) */ |
3938bad4 | 36 | bool die_is_func_def(Dwarf_Die *dw_die); |
0dbb1cac | 37 | |
e1ecbbc3 | 38 | /* Ensure that this DIE is an instance of a subprogram */ |
3938bad4 | 39 | bool die_is_func_instance(Dwarf_Die *dw_die); |
e1ecbbc3 | 40 | |
e0d153c6 | 41 | /* Compare diename and tname */ |
3938bad4 | 42 | bool die_compare_name(Dwarf_Die *dw_die, const char *tname); |
e0d153c6 | 43 | |
4c859351 | 44 | /* Matching diename with glob pattern */ |
3938bad4 | 45 | bool die_match_name(Dwarf_Die *dw_die, const char *glob); |
4c859351 | 46 | |
e0d153c6 | 47 | /* Get callsite line number of inline-function instance */ |
3938bad4 | 48 | int die_get_call_lineno(Dwarf_Die *in_die); |
e0d153c6 | 49 | |
b0e9cb28 | 50 | /* Get callsite file name of inlined function instance */ |
3938bad4 | 51 | const char *die_get_call_file(Dwarf_Die *in_die); |
b0e9cb28 | 52 | |
dc9a5d2c MHG |
53 | /* Get declared file name of a DIE */ |
54 | const char *die_get_decl_file(Dwarf_Die *dw_die); | |
55 | ||
e0d153c6 | 56 | /* Get type die */ |
3938bad4 | 57 | Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem); |
e0d153c6 MH |
58 | |
59 | /* Get a type die, but skip qualifiers and typedef */ | |
3938bad4 | 60 | Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem); |
e0d153c6 MH |
61 | |
62 | /* Check whether the DIE is signed or not */ | |
3938bad4 | 63 | bool die_is_signed_type(Dwarf_Die *tp_die); |
e0d153c6 MH |
64 | |
65 | /* Get data_member_location offset */ | |
3938bad4 | 66 | int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs); |
e0d153c6 MH |
67 | |
68 | /* Return values for die_find_child() callbacks */ | |
69 | enum { | |
70 | DIE_FIND_CB_END = 0, /* End of Search */ | |
71 | DIE_FIND_CB_CHILD = 1, /* Search only children */ | |
72 | DIE_FIND_CB_SIBLING = 2, /* Search only siblings */ | |
73 | DIE_FIND_CB_CONTINUE = 3, /* Search children and siblings */ | |
74 | }; | |
75 | ||
76 | /* Search child DIEs */ | |
3938bad4 ACM |
77 | Dwarf_Die *die_find_child(Dwarf_Die *rt_die, |
78 | int (*callback)(Dwarf_Die *, void *), | |
79 | void *data, Dwarf_Die *die_mem); | |
e0d153c6 MH |
80 | |
81 | /* Search a non-inlined function including given address */ | |
3938bad4 ACM |
82 | Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, |
83 | Dwarf_Die *die_mem); | |
e0d153c6 | 84 | |
d4c537e6 NR |
85 | /* Search a non-inlined function with tail call at given address */ |
86 | Dwarf_Die *die_find_tailfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, | |
87 | Dwarf_Die *die_mem); | |
88 | ||
e08cfd4b | 89 | /* Search the top inlined function including given address */ |
3938bad4 ACM |
90 | Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, |
91 | Dwarf_Die *die_mem); | |
e08cfd4b MH |
92 | |
93 | /* Search the deepest inlined function including given address */ | |
3938bad4 ACM |
94 | Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, |
95 | Dwarf_Die *die_mem); | |
e0d153c6 | 96 | |
db0d2c64 | 97 | /* Walk on the instances of given DIE */ |
3938bad4 ACM |
98 | int die_walk_instances(Dwarf_Die *in_die, |
99 | int (*callback)(Dwarf_Die *, void *), void *data); | |
db0d2c64 | 100 | |
e0d153c6 MH |
101 | /* Walker on lines (Note: line number will not be sorted) */ |
102 | typedef int (* line_walk_callback_t) (const char *fname, int lineno, | |
103 | Dwarf_Addr addr, void *data); | |
104 | ||
105 | /* | |
106 | * Walk on lines inside given DIE. If the DIE is a subprogram, walk only on | |
107 | * the lines inside the subprogram, otherwise the DIE must be a CU DIE. | |
108 | */ | |
3938bad4 | 109 | int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data); |
e0d153c6 MH |
110 | |
111 | /* Find a variable called 'name' at given address */ | |
3938bad4 ACM |
112 | Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name, |
113 | Dwarf_Addr addr, Dwarf_Die *die_mem); | |
e0d153c6 MH |
114 | |
115 | /* Find a member called 'name' */ | |
3938bad4 ACM |
116 | Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name, |
117 | Dwarf_Die *die_mem); | |
e0d153c6 | 118 | |
60cb19b4 NK |
119 | /* Get the name of given type DIE */ |
120 | int die_get_typename_from_type(Dwarf_Die *type_die, struct strbuf *buf); | |
121 | ||
e0d153c6 | 122 | /* Get the name of given variable DIE */ |
3938bad4 | 123 | int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf); |
e0d153c6 MH |
124 | |
125 | /* Get the name and type of given variable DIE, stored as "type\tname" */ | |
3938bad4 | 126 | int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf); |
6243b9dc RB |
127 | |
128 | /* Check if target program is compiled with optimization */ | |
129 | bool die_is_optimized_target(Dwarf_Die *cu_die); | |
130 | ||
131 | /* Use next address after prologue as probe location */ | |
132 | void die_skip_prologue(Dwarf_Die *sp_die, Dwarf_Die *cu_die, | |
133 | Dwarf_Addr *entrypc); | |
134 | ||
981620fd NK |
135 | /* Get the list of including scopes */ |
136 | int die_get_scopes(Dwarf_Die *cu_die, Dwarf_Addr pc, Dwarf_Die **scopes); | |
137 | ||
3796eba7 NK |
138 | #ifdef HAVE_DWARF_GETLOCATIONS_SUPPORT |
139 | ||
140 | /* Get byte offset range of given variable DIE */ | |
141 | int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, struct strbuf *buf); | |
142 | ||
3f5928e4 NK |
143 | /* Find a variable saved in the 'reg' at given address */ |
144 | Dwarf_Die *die_find_variable_by_reg(Dwarf_Die *sc_die, Dwarf_Addr pc, int reg, | |
bc10db8e | 145 | int *poffset, bool is_fbreg, |
3f5928e4 NK |
146 | Dwarf_Die *die_mem); |
147 | ||
d60469d7 NK |
148 | /* Find a (global) variable located in the 'addr' */ |
149 | Dwarf_Die *die_find_variable_by_addr(Dwarf_Die *sc_die, Dwarf_Addr pc, | |
150 | Dwarf_Addr addr, Dwarf_Die *die_mem, | |
151 | int *offset); | |
152 | ||
3796eba7 NK |
153 | #else /* HAVE_DWARF_GETLOCATIONS_SUPPORT */ |
154 | ||
155 | static inline int die_get_var_range(Dwarf_Die *sp_die __maybe_unused, | |
156 | Dwarf_Die *vr_die __maybe_unused, | |
157 | struct strbuf *buf __maybe_unused) | |
158 | { | |
159 | return -ENOTSUP; | |
160 | } | |
161 | ||
3f5928e4 NK |
162 | static inline Dwarf_Die *die_find_variable_by_reg(Dwarf_Die *sc_die __maybe_unused, |
163 | Dwarf_Addr pc __maybe_unused, | |
164 | int reg __maybe_unused, | |
bc10db8e NK |
165 | int *poffset __maybe_unused, |
166 | bool is_fbreg __maybe_unused, | |
3f5928e4 NK |
167 | Dwarf_Die *die_mem __maybe_unused) |
168 | { | |
169 | return NULL; | |
170 | } | |
171 | ||
d60469d7 NK |
172 | static inline Dwarf_Die *die_find_variable_by_addr(Dwarf_Die *sc_die __maybe_unused, |
173 | Dwarf_Addr pc __maybe_unused, | |
174 | Dwarf_Addr addr __maybe_unused, | |
175 | Dwarf_Die *die_mem __maybe_unused, | |
176 | int *offset __maybe_unused) | |
177 | { | |
178 | return NULL; | |
179 | } | |
180 | ||
3796eba7 NK |
181 | #endif /* HAVE_DWARF_GETLOCATIONS_SUPPORT */ |
182 | ||
6fed025f NK |
183 | #ifdef HAVE_DWARF_CFI_SUPPORT |
184 | ||
185 | /* Get the frame base information from CFA */ | |
186 | int die_get_cfa(Dwarf *dwarf, u64 pc, int *preg, int *poffset); | |
187 | ||
188 | #else /* HAVE_DWARF_CFI_SUPPORT */ | |
189 | ||
190 | static inline int die_get_cfa(Dwarf *dwarf __maybe_unused, u64 pc __maybe_unused, | |
191 | int *preg __maybe_unused, int *poffset __maybe_unused) | |
192 | { | |
193 | return -1; | |
194 | } | |
195 | ||
196 | #endif /* HAVE_DWARF_CFI_SUPPORT */ | |
197 | ||
3796eba7 | 198 | #endif /* _DWARF_AUX_H */ |