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