1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */ 2*4882a593Smuzhiyun #ifndef _DWARF_AUX_H 3*4882a593Smuzhiyun #define _DWARF_AUX_H 4*4882a593Smuzhiyun /* 5*4882a593Smuzhiyun * dwarf-aux.h : libdw auxiliary interfaces 6*4882a593Smuzhiyun */ 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun #include <dwarf.h> 9*4882a593Smuzhiyun #include <elfutils/libdw.h> 10*4882a593Smuzhiyun #include <elfutils/libdwfl.h> 11*4882a593Smuzhiyun #include <elfutils/version.h> 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun struct strbuf; 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun /* Find the realpath of the target file */ 16*4882a593Smuzhiyun const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname); 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun /* Get DW_AT_comp_dir (should be NULL with older gcc) */ 19*4882a593Smuzhiyun const char *cu_get_comp_dir(Dwarf_Die *cu_die); 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun /* Get a line number and file name for given address */ 22*4882a593Smuzhiyun int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr, 23*4882a593Smuzhiyun const char **fname, int *lineno); 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun /* Walk on funcitons at given address */ 26*4882a593Smuzhiyun int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr, 27*4882a593Smuzhiyun int (*callback)(Dwarf_Die *, void *), void *data); 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun /* Get DW_AT_linkage_name (should be NULL for C binary) */ 30*4882a593Smuzhiyun const char *die_get_linkage_name(Dwarf_Die *dw_die); 31*4882a593Smuzhiyun 32*4882a593Smuzhiyun /* Get the lowest PC in DIE (including range list) */ 33*4882a593Smuzhiyun int die_entrypc(Dwarf_Die *dw_die, Dwarf_Addr *addr); 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun /* Ensure that this DIE is a subprogram and definition (not declaration) */ 36*4882a593Smuzhiyun bool die_is_func_def(Dwarf_Die *dw_die); 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun /* Ensure that this DIE is an instance of a subprogram */ 39*4882a593Smuzhiyun bool die_is_func_instance(Dwarf_Die *dw_die); 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun /* Compare diename and tname */ 42*4882a593Smuzhiyun bool die_compare_name(Dwarf_Die *dw_die, const char *tname); 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun /* Matching diename with glob pattern */ 45*4882a593Smuzhiyun bool die_match_name(Dwarf_Die *dw_die, const char *glob); 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun /* Get callsite line number of inline-function instance */ 48*4882a593Smuzhiyun int die_get_call_lineno(Dwarf_Die *in_die); 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun /* Get callsite file name of inlined function instance */ 51*4882a593Smuzhiyun const char *die_get_call_file(Dwarf_Die *in_die); 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun /* Get type die */ 54*4882a593Smuzhiyun Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem); 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun /* Get a type die, but skip qualifiers and typedef */ 57*4882a593Smuzhiyun Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem); 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun /* Check whether the DIE is signed or not */ 60*4882a593Smuzhiyun bool die_is_signed_type(Dwarf_Die *tp_die); 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun /* Get data_member_location offset */ 63*4882a593Smuzhiyun int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs); 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun /* Return values for die_find_child() callbacks */ 66*4882a593Smuzhiyun enum { 67*4882a593Smuzhiyun DIE_FIND_CB_END = 0, /* End of Search */ 68*4882a593Smuzhiyun DIE_FIND_CB_CHILD = 1, /* Search only children */ 69*4882a593Smuzhiyun DIE_FIND_CB_SIBLING = 2, /* Search only siblings */ 70*4882a593Smuzhiyun DIE_FIND_CB_CONTINUE = 3, /* Search children and siblings */ 71*4882a593Smuzhiyun }; 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun /* Search child DIEs */ 74*4882a593Smuzhiyun Dwarf_Die *die_find_child(Dwarf_Die *rt_die, 75*4882a593Smuzhiyun int (*callback)(Dwarf_Die *, void *), 76*4882a593Smuzhiyun void *data, Dwarf_Die *die_mem); 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun /* Search a non-inlined function including given address */ 79*4882a593Smuzhiyun Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, 80*4882a593Smuzhiyun Dwarf_Die *die_mem); 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun /* Search a non-inlined function with tail call at given address */ 83*4882a593Smuzhiyun Dwarf_Die *die_find_tailfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, 84*4882a593Smuzhiyun Dwarf_Die *die_mem); 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun /* Search the top inlined function including given address */ 87*4882a593Smuzhiyun Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, 88*4882a593Smuzhiyun Dwarf_Die *die_mem); 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun /* Search the deepest inlined function including given address */ 91*4882a593Smuzhiyun Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, 92*4882a593Smuzhiyun Dwarf_Die *die_mem); 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun /* Walk on the instances of given DIE */ 95*4882a593Smuzhiyun int die_walk_instances(Dwarf_Die *in_die, 96*4882a593Smuzhiyun int (*callback)(Dwarf_Die *, void *), void *data); 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun /* Walker on lines (Note: line number will not be sorted) */ 99*4882a593Smuzhiyun typedef int (* line_walk_callback_t) (const char *fname, int lineno, 100*4882a593Smuzhiyun Dwarf_Addr addr, void *data); 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun /* 103*4882a593Smuzhiyun * Walk on lines inside given DIE. If the DIE is a subprogram, walk only on 104*4882a593Smuzhiyun * the lines inside the subprogram, otherwise the DIE must be a CU DIE. 105*4882a593Smuzhiyun */ 106*4882a593Smuzhiyun int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data); 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun /* Find a variable called 'name' at given address */ 109*4882a593Smuzhiyun Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name, 110*4882a593Smuzhiyun Dwarf_Addr addr, Dwarf_Die *die_mem); 111*4882a593Smuzhiyun 112*4882a593Smuzhiyun /* Find a member called 'name' */ 113*4882a593Smuzhiyun Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name, 114*4882a593Smuzhiyun Dwarf_Die *die_mem); 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun /* Get the name of given variable DIE */ 117*4882a593Smuzhiyun int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf); 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun /* Get the name and type of given variable DIE, stored as "type\tname" */ 120*4882a593Smuzhiyun int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf); 121*4882a593Smuzhiyun int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, struct strbuf *buf); 122*4882a593Smuzhiyun 123*4882a593Smuzhiyun /* Check if target program is compiled with optimization */ 124*4882a593Smuzhiyun bool die_is_optimized_target(Dwarf_Die *cu_die); 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun /* Use next address after prologue as probe location */ 127*4882a593Smuzhiyun void die_skip_prologue(Dwarf_Die *sp_die, Dwarf_Die *cu_die, 128*4882a593Smuzhiyun Dwarf_Addr *entrypc); 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun #endif 131