xref: /openbmc/linux/tools/perf/util/dwarf-aux.h (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
11a59d1b8SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
2e0d153c6SMasami Hiramatsu #ifndef _DWARF_AUX_H
3e0d153c6SMasami Hiramatsu #define _DWARF_AUX_H
4e0d153c6SMasami Hiramatsu /*
5e0d153c6SMasami Hiramatsu  * dwarf-aux.h : libdw auxiliary interfaces
6e0d153c6SMasami Hiramatsu  */
7e0d153c6SMasami Hiramatsu 
8e0d153c6SMasami Hiramatsu #include <dwarf.h>
9e0d153c6SMasami Hiramatsu #include <elfutils/libdw.h>
10e0d153c6SMasami Hiramatsu #include <elfutils/libdwfl.h>
11e0d153c6SMasami Hiramatsu #include <elfutils/version.h>
12e0d153c6SMasami Hiramatsu 
138520a98dSArnaldo Carvalho de Melo struct strbuf;
148520a98dSArnaldo Carvalho de Melo 
15e0d153c6SMasami Hiramatsu /* Find the realpath of the target file */
163938bad4SArnaldo Carvalho de Melo const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname);
17e0d153c6SMasami Hiramatsu 
18e0d153c6SMasami Hiramatsu /* Get DW_AT_comp_dir (should be NULL with older gcc) */
193938bad4SArnaldo Carvalho de Melo const char *cu_get_comp_dir(Dwarf_Die *cu_die);
20e0d153c6SMasami Hiramatsu 
21e0d153c6SMasami Hiramatsu /* Get a line number and file name for given address */
2222a66551SYang Jihong int cu_find_lineinfo(Dwarf_Die *cudie, Dwarf_Addr addr,
23e0d153c6SMasami Hiramatsu 		     const char **fname, int *lineno);
24e0d153c6SMasami Hiramatsu 
254d39c89fSIngo Molnar /* Walk on functions at given address */
263938bad4SArnaldo Carvalho de Melo int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr,
27221d0611SMasami Hiramatsu 			 int (*callback)(Dwarf_Die *, void *), void *data);
28221d0611SMasami Hiramatsu 
29d5a00296SMasami Hiramatsu /* Get DW_AT_linkage_name (should be NULL for C binary) */
30d5a00296SMasami Hiramatsu const char *die_get_linkage_name(Dwarf_Die *dw_die);
31d5a00296SMasami Hiramatsu 
3291e2f539SMasami Hiramatsu /* Get the lowest PC in DIE (including range list) */
3391e2f539SMasami Hiramatsu int die_entrypc(Dwarf_Die *dw_die, Dwarf_Addr *addr);
3491e2f539SMasami Hiramatsu 
350dbb1cacSMasami Hiramatsu /* Ensure that this DIE is a subprogram and definition (not declaration) */
363938bad4SArnaldo Carvalho de Melo bool die_is_func_def(Dwarf_Die *dw_die);
370dbb1cacSMasami Hiramatsu 
38e1ecbbc3SMasami Hiramatsu /* Ensure that this DIE is an instance of a subprogram */
393938bad4SArnaldo Carvalho de Melo bool die_is_func_instance(Dwarf_Die *dw_die);
40e1ecbbc3SMasami Hiramatsu 
41e0d153c6SMasami Hiramatsu /* Compare diename and tname */
423938bad4SArnaldo Carvalho de Melo bool die_compare_name(Dwarf_Die *dw_die, const char *tname);
43e0d153c6SMasami Hiramatsu 
444c859351SMasami Hiramatsu /* Matching diename with glob pattern */
453938bad4SArnaldo Carvalho de Melo bool die_match_name(Dwarf_Die *dw_die, const char *glob);
464c859351SMasami Hiramatsu 
47e0d153c6SMasami Hiramatsu /* Get callsite line number of inline-function instance */
483938bad4SArnaldo Carvalho de Melo int die_get_call_lineno(Dwarf_Die *in_die);
49e0d153c6SMasami Hiramatsu 
50b0e9cb28SMasami Hiramatsu /* Get callsite file name of inlined function instance */
513938bad4SArnaldo Carvalho de Melo const char *die_get_call_file(Dwarf_Die *in_die);
52b0e9cb28SMasami Hiramatsu 
53*dc9a5d2cSMasami Hiramatsu (Google) /* Get declared file name of a DIE */
54*dc9a5d2cSMasami Hiramatsu (Google) const char *die_get_decl_file(Dwarf_Die *dw_die);
55*dc9a5d2cSMasami Hiramatsu (Google) 
56e0d153c6SMasami Hiramatsu /* Get type die */
573938bad4SArnaldo Carvalho de Melo Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem);
58e0d153c6SMasami Hiramatsu 
59e0d153c6SMasami Hiramatsu /* Get a type die, but skip qualifiers and typedef */
603938bad4SArnaldo Carvalho de Melo Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem);
61e0d153c6SMasami Hiramatsu 
62e0d153c6SMasami Hiramatsu /* Check whether the DIE is signed or not */
633938bad4SArnaldo Carvalho de Melo bool die_is_signed_type(Dwarf_Die *tp_die);
64e0d153c6SMasami Hiramatsu 
65e0d153c6SMasami Hiramatsu /* Get data_member_location offset */
663938bad4SArnaldo Carvalho de Melo int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs);
67e0d153c6SMasami Hiramatsu 
68e0d153c6SMasami Hiramatsu /* Return values for die_find_child() callbacks */
69e0d153c6SMasami Hiramatsu enum {
70e0d153c6SMasami Hiramatsu 	DIE_FIND_CB_END = 0,		/* End of Search */
71e0d153c6SMasami Hiramatsu 	DIE_FIND_CB_CHILD = 1,		/* Search only children */
72e0d153c6SMasami Hiramatsu 	DIE_FIND_CB_SIBLING = 2,	/* Search only siblings */
73e0d153c6SMasami Hiramatsu 	DIE_FIND_CB_CONTINUE = 3,	/* Search children and siblings */
74e0d153c6SMasami Hiramatsu };
75e0d153c6SMasami Hiramatsu 
76e0d153c6SMasami Hiramatsu /* Search child DIEs */
773938bad4SArnaldo Carvalho de Melo Dwarf_Die *die_find_child(Dwarf_Die *rt_die,
78e0d153c6SMasami Hiramatsu 			 int (*callback)(Dwarf_Die *, void *),
79e0d153c6SMasami Hiramatsu 			 void *data, Dwarf_Die *die_mem);
80e0d153c6SMasami Hiramatsu 
81e0d153c6SMasami Hiramatsu /* Search a non-inlined function including given address */
823938bad4SArnaldo Carvalho de Melo Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
83e0d153c6SMasami Hiramatsu 			     Dwarf_Die *die_mem);
84e0d153c6SMasami Hiramatsu 
85d4c537e6SNaveen N. Rao /* Search a non-inlined function with tail call at given address */
86d4c537e6SNaveen N. Rao Dwarf_Die *die_find_tailfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
87d4c537e6SNaveen N. Rao 				    Dwarf_Die *die_mem);
88d4c537e6SNaveen N. Rao 
89e08cfd4bSMasami Hiramatsu /* Search the top inlined function including given address */
903938bad4SArnaldo Carvalho de Melo Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
91e08cfd4bSMasami Hiramatsu 				   Dwarf_Die *die_mem);
92e08cfd4bSMasami Hiramatsu 
93e08cfd4bSMasami Hiramatsu /* Search the deepest inlined function including given address */
943938bad4SArnaldo Carvalho de Melo Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
95e0d153c6SMasami Hiramatsu 			       Dwarf_Die *die_mem);
96e0d153c6SMasami Hiramatsu 
97db0d2c64SMasami Hiramatsu /* Walk on the instances of given DIE */
983938bad4SArnaldo Carvalho de Melo int die_walk_instances(Dwarf_Die *in_die,
99db0d2c64SMasami Hiramatsu 		       int (*callback)(Dwarf_Die *, void *), void *data);
100db0d2c64SMasami Hiramatsu 
101e0d153c6SMasami Hiramatsu /* Walker on lines (Note: line number will not be sorted) */
102e0d153c6SMasami Hiramatsu typedef int (* line_walk_callback_t) (const char *fname, int lineno,
103e0d153c6SMasami Hiramatsu 				      Dwarf_Addr addr, void *data);
104e0d153c6SMasami Hiramatsu 
105e0d153c6SMasami Hiramatsu /*
106e0d153c6SMasami Hiramatsu  * Walk on lines inside given DIE. If the DIE is a subprogram, walk only on
107e0d153c6SMasami Hiramatsu  * the lines inside the subprogram, otherwise the DIE must be a CU DIE.
108e0d153c6SMasami Hiramatsu  */
1093938bad4SArnaldo Carvalho de Melo int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data);
110e0d153c6SMasami Hiramatsu 
111e0d153c6SMasami Hiramatsu /* Find a variable called 'name' at given address */
1123938bad4SArnaldo Carvalho de Melo Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name,
113e0d153c6SMasami Hiramatsu 				Dwarf_Addr addr, Dwarf_Die *die_mem);
114e0d153c6SMasami Hiramatsu 
115e0d153c6SMasami Hiramatsu /* Find a member called 'name' */
1163938bad4SArnaldo Carvalho de Melo Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name,
117e0d153c6SMasami Hiramatsu 			   Dwarf_Die *die_mem);
118e0d153c6SMasami Hiramatsu 
119e0d153c6SMasami Hiramatsu /* Get the name of given variable DIE */
1203938bad4SArnaldo Carvalho de Melo int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf);
121e0d153c6SMasami Hiramatsu 
122e0d153c6SMasami Hiramatsu /* Get the name and type of given variable DIE, stored as "type\tname" */
1233938bad4SArnaldo Carvalho de Melo int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf);
1243938bad4SArnaldo Carvalho de Melo int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, struct strbuf *buf);
1256243b9dcSRavi Bangoria 
1266243b9dcSRavi Bangoria /* Check if target program is compiled with optimization */
1276243b9dcSRavi Bangoria bool die_is_optimized_target(Dwarf_Die *cu_die);
1286243b9dcSRavi Bangoria 
1296243b9dcSRavi Bangoria /* Use next address after prologue as probe location */
1306243b9dcSRavi Bangoria void die_skip_prologue(Dwarf_Die *sp_die, Dwarf_Die *cu_die,
1316243b9dcSRavi Bangoria 		       Dwarf_Addr *entrypc);
1326243b9dcSRavi Bangoria 
133e0d153c6SMasami Hiramatsu #endif
134