char *get_type_str(Dwarf_Die *die) { static char buf[256] = ""; char *ptr = NULL; Dwarf_Die tdie; Dwarf_Attribute attr; if (!dwarf_attr(die, DW_AT_type, &attr)) return "void"; dwarf_formref_die(&attr, &tdie); if (dwarf_tag(&tdie) == DW_TAG_array_type) ptr = "[]"; else if (dwarf_tag(&tdie) == DW_TAG_pointer_type) ptr = "*"; else goto end_ok; dwarf_attr(&tdie, DW_AT_type, &attr); dwarf_formref_die(&attr, &tdie); end_ok: sprintf(buf, "%s%s", dwarf_diename(&tdie), (ptr) ? ptr : ""); return buf; }
struct refl_object * refl_deref (struct refl *refl, struct refl_object *obj) { struct refl_type *type = refl_object_type (obj); Dwarf_Die die = type->die; if (__refl_die_strip_cvq (&die, &die) == NULL) return NULL; /* Cannot dereference non-pointer type. */ if (dwarf_tag (&die) != DW_TAG_pointer_type) { __refl_seterr_2 (REFL_E_REFL, REFL_ME_MISMATCH); return NULL; } if (__refl_die_type (&die, &die) == NULL) return NULL; /* Cannot dereference function pointer. */ if (dwarf_tag (&die) == DW_TAG_subroutine_type) { __refl_seterr_2 (REFL_E_REFL, REFL_ME_MISMATCH); return NULL; } struct refl_type *ntype = __refl_type_begin (&die); if (ntype == NULL) return NULL; void *ndata = *(void **)refl_object_cdata (obj); return __refl_object_begin (ntype, ndata); }
/** \brief Finds the number of elements in a DW_TAG_subrange_type or DW_TAG_enumeration_type DIE * * \param die the DIE * \param unit DIE of the compilation unit * \return number of elements in the range * */ static uint64_t MC_dwarf_subrange_element_count(Dwarf_Die * die, Dwarf_Die * unit) { xbt_assert(dwarf_tag(die) == DW_TAG_enumeration_type || dwarf_tag(die) == DW_TAG_subrange_type, "MC_dwarf_subrange_element_count called with DIE of type %s", simgrid::dwarf::tagname(die)); // Use DW_TAG_count if present: if (dwarf_hasattr_integrate(die, DW_AT_count)) return MC_dwarf_attr_integrate_uint(die, DW_AT_count, 0); // Otherwise compute DW_TAG_upper_bound-DW_TAG_lower_bound + 1: if (not dwarf_hasattr_integrate(die, DW_AT_upper_bound)) // This is not really 0, but the code expects this (we do not know): return 0; uint64_t upper_bound = MC_dwarf_attr_integrate_uint(die, DW_AT_upper_bound, static_cast<uint64_t>(-1)); uint64_t lower_bound = 0; if (dwarf_hasattr_integrate(die, DW_AT_lower_bound)) lower_bound = MC_dwarf_attr_integrate_uint(die, DW_AT_lower_bound, static_cast<uint64_t>(-1)); else lower_bound = MC_dwarf_default_lower_bound(dwarf_srclang(unit)); return upper_bound - lower_bound + 1; }
static int line_range_search_cb(Dwarf_Die *sp_die, void *data) { struct dwarf_callback_param *param = data; struct line_finder *lf = param->data; struct line_range *lr = lf->lr; if (lr->file && strtailcmp(lr->file, dwarf_decl_file(sp_die))) return DWARF_CB_OK; if (dwarf_tag(sp_die) == DW_TAG_subprogram && die_compare_name(sp_die, lr->function)) { lf->fname = dwarf_decl_file(sp_die); dwarf_decl_line(sp_die, &lr->offset); pr_debug("fname: %s, lineno:%d\n", lf->fname, lr->offset); lf->lno_s = lr->offset + lr->start; if (lf->lno_s < 0) lf->lno_s = INT_MAX; lf->lno_e = lr->offset + lr->end; if (lf->lno_e < 0) lf->lno_e = INT_MAX; pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e); lr->start = lf->lno_s; lr->end = lf->lno_e; if (dwarf_func_inline(sp_die)) param->retval = die_walk_instances(sp_die, line_range_inline_cb, lf); else param->retval = find_line_range_by_line(sp_die, lf); return DWARF_CB_ABORT; } return DWARF_CB_OK; }
struct variable* child_variables(Dwarf_Die *parent, Dwarf_Files *files, struct expr_context *ctx, bool params) { int ret; Dwarf_Die die; struct variable *var, *head = NULL, *tail = NULL; int desired_tag = params ? DW_TAG_formal_parameter : DW_TAG_variable; ret = dwarf_child(parent, &die); if (ret != 0) return NULL; do { if (dwarf_tag(&die) == desired_tag) { var = analyze_variable(&die, files, ctx); if (!var) continue; list_append(head, tail, var); } } while (dwarf_siblingof(&die, &die) == 0); return head; }
static void MC_dwarf_handle_die(simgrid::mc::ObjectInformation* info, Dwarf_Die * die, Dwarf_Die * unit, simgrid::mc::Frame* frame, const char *ns) { int tag = dwarf_tag(die); simgrid::dwarf::TagClass klass = simgrid::dwarf::classify_tag(tag); switch (klass) { // Type: case simgrid::dwarf::TagClass::Type: MC_dwarf_handle_type_die(info, die, unit, frame, ns); break; // Subprogram or scope: case simgrid::dwarf::TagClass::Subprogram: case simgrid::dwarf::TagClass::Scope: MC_dwarf_handle_scope_die(info, die, unit, frame, ns); return; // Variable: case simgrid::dwarf::TagClass::Variable: MC_dwarf_handle_variable_die(info, die, unit, frame, ns); break; case simgrid::dwarf::TagClass::Namespace: mc_dwarf_handle_namespace_die(info, die, unit, frame, ns); break; default: break; } }
/* recursively follow the die tree */ extern void print_die_and_children(Dwarf_Debug dbg, Dwarf_Die in_die_in, char **srcfiles, Dwarf_Signed cnt) { Dwarf_Die child; Dwarf_Die sibling; Dwarf_Error err; int tres; int cdres; Dwarf_Die in_die = in_die_in; for (;;) { PUSH_DIE_STACK(in_die); if (check_tag_tree) { tag_tree_result.checks++; if (indent_level == 0) { Dwarf_Half tag; tres = dwarf_tag(in_die, &tag, &err); if (tres != DW_DLV_OK) { tag_tree_result.errors++; DWARF_CHECK_ERROR ("Tag-tree root is not DW_TAG_compile_unit") } else if (tag == DW_TAG_compile_unit) { /* OK */ } else { tag_tree_result.errors++; DWARF_CHECK_ERROR ("tag-tree root is not DW_TAG_compile_unit") } } else {
static VALUE rd_die_new(rd_shared_data_t *sd, VALUE top, VALUE cu, Dwarf_Die die) { rd_die_t *rd_die; Dwarf_Off off; Dwarf_Half tag; Dwarf_Error err; VALUE obj; VALUE klass; chkerr1(dwarf_dieoffset(die, &off, &err), &err, Qnil); obj = rb_hash_aref(sd->off2die, LL2NUM(off)); if (!NIL_P(obj)) { return obj; } chkerr1(dwarf_tag(die, &tag, &err), &err, Qnil); klass = rb_hash_aref(rdwarf_tag2class, INT2FIX(tag)); if (NIL_P(klass)) { rb_raise(rb_eRuntimeError, "unknown tag %d\n", tag); } obj = rd_die_s_alloc(klass); rd_die = GetDie(obj); rd_die->shared_data = rd_shared_data_ref(sd); rd_die->die = die; rb_ivar_set(obj, id_at_top, top); rb_ivar_set(obj, id_at_cu, NIL_P(cu) ? obj : cu); rb_hash_aset(sd->off2die, LL2NUM(off), obj); return obj; }
/* BASE must be a base type DIE referenced by a typed DWARF expression op. */ static void print_base_type (Dwarf_Die *base) { assert (dwarf_tag (base) == DW_TAG_base_type); Dwarf_Attribute encoding; Dwarf_Word enctype; if (dwarf_attr (base, DW_AT_encoding, &encoding) == NULL || dwarf_formudata (&encoding, &enctype) != 0) error (EXIT_FAILURE, 0, "base type without encoding"); Dwarf_Attribute bsize; Dwarf_Word bits; if (dwarf_attr (base, DW_AT_byte_size, &bsize) != NULL && dwarf_formudata (&bsize, &bits) == 0) bits *= 8; else if (dwarf_attr (base, DW_AT_bit_size, &bsize) == NULL || dwarf_formudata (&bsize, &bits) != 0) error (EXIT_FAILURE, 0, "base type without byte or bit size"); printf ("{%s,%s,%" PRIu64 "@[%" PRIx64 "]}", dwarf_diename (base), dwarf_encoding_string (enctype), bits, dwarf_dieoffset (base)); }
/** * die_is_func_def - Ensure that this DIE is a subprogram and definition * @dw_die: a DIE * * Ensure that this DIE is a subprogram and NOT a declaration. This * returns true if @dw_die is a function definition. **/ bool die_is_func_def(Dwarf_Die *dw_die) { Dwarf_Attribute attr; return (dwarf_tag(dw_die) == DW_TAG_subprogram && dwarf_attr(dw_die, DW_AT_declaration, &attr) == NULL); }
int dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, size_t *nfiles) { if (unlikely (cudie == NULL || dwarf_tag (cudie) != DW_TAG_compile_unit)) return -1; int res = -1; /* Get the information if it is not already known. */ struct Dwarf_CU *const cu = cudie->cu; if (cu->lines == NULL) { Dwarf_Lines *lines; size_t nlines; /* Let the more generic function do the work. It'll create more data but that will be needed in an real program anyway. */ res = dwarf_getsrclines (cudie, &lines, &nlines); } else if (cu->files != (void *) -1l) /* We already have the information. */ res = 0; if (likely (res == 0)) { assert (cu->files != NULL && cu->files != (void *) -1l); *files = cu->files; if (nfiles != NULL) *nfiles = cu->files->nfiles; } // XXX Eventually: unlocking here. return res; }
static void print_die_data(Dwarf_Debug dbg, Dwarf_Die print_me,int level) { char *name = 0; Dwarf_Error error = 0; Dwarf_Half tag = 0; const char *tagname = 0; int res = dwarf_diename(print_me,&name,&error); if(res == DW_DLV_ERROR) { printf("Error in dwarf_diename , level %d \n",level); exit(1); } if(res == DW_DLV_NO_ENTRY) { return; } res = dwarf_tag(print_me,&tag,&error); if(res != DW_DLV_OK) { printf("Error in dwarf_tag , level %d \n",level); exit(1); } res = dwarf_get_TAG_name(tag,&tagname); if(res != DW_DLV_OK) { printf("Error in dwarf_get_TAG_name , level %d \n",level); exit(1); } printf("<%d> tag: %d %s name: %s\n",level,tag,tagname,name); dwarf_dealloc(dbg,name,DW_DLA_STRING); }
static void DC_resolve_type(Dwarf_Die v, DC_type *t){ /*TODO: Error Handling*/ Dwarf_Error error; Dwarf_Attribute type; Dwarf_Off off; Dwarf_Die typeDie; Dwarf_Half tag = 0; /* * Start with the variable, not its type. The loop * unwraps all the types. */ dwarf_attr(v, DW_AT_type, &type, &error); dwarf_formref(type, &off, &error); DC_get_die_from_CU_relative_offset(v, off, &typeDie); int points = 0; int arrs = 0; while( 1 ){ Dwarf_Bool has; dwarf_hasattr(typeDie,DW_AT_type,&has,&error); if(!has){ /*We've reached a base or structure type*/ dwarf_diename(typeDie,&(t->name),&error); Dwarf_Attribute bsize; dwarf_attr(typeDie,DW_AT_byte_size,&bsize,&error); dwarf_formudata(bsize,(Dwarf_Unsigned*)(&t->byteSize),&error); t->indirectionLevel = points; t->arrayLevel = arrs; return; /*Note: I am assuming this must happen eventually. can there * be mutually referencing types?*/ } /*Otherwise: this type has a type, so it is a pointer or a typedef * or an array type. For now, we're only going to correctly * handle pointer types.(TODO:) */ dwarf_tag(typeDie,&tag,&error); if(tag == DW_TAG_pointer_type){ points++; } if(tag == DW_TAG_array_type){ arrs++; } dwarf_attr(typeDie, DW_AT_type, &type, &error); dwarf_formref(type, &off, &error); /*Note, the next line uses v, because it can use anything in the CU*/ DC_get_die_from_CU_relative_offset(v, off, &typeDie); } }
static int __die_walk_instances_cb(Dwarf_Die *inst, void *data) { struct __instance_walk_param *iwp = data; Dwarf_Attribute attr_mem; Dwarf_Die origin_mem; Dwarf_Attribute *attr; Dwarf_Die *origin; int tmp; attr = dwarf_attr(inst, DW_AT_abstract_origin, &attr_mem); if (attr == NULL) return DIE_FIND_CB_CONTINUE; origin = dwarf_formref_die(attr, &origin_mem); if (origin == NULL || origin->addr != iwp->addr) return DIE_FIND_CB_CONTINUE; /* Ignore redundant instances */ if (dwarf_tag(inst) == DW_TAG_inlined_subroutine) { dwarf_decl_line(origin, &tmp); if (die_get_call_lineno(inst) == tmp) { tmp = die_get_decl_fileno(origin); if (die_get_call_fileno(inst) == tmp) return DIE_FIND_CB_CONTINUE; } } iwp->retval = iwp->callback(inst, iwp->data); return (iwp->retval) ? DIE_FIND_CB_END : DIE_FIND_CB_CONTINUE; }
/** * die_get_real_type - Get a type die, but skip qualifiers and typedef * @vr_die: a DIE of a variable * @die_mem: where to store a type DIE * * Get a DIE of the type of given variable (@vr_die), and store * it to die_mem. Return NULL if fails to get a type DIE. * If the type is qualifiers (e.g. const) or typedef, this skips it * and tries to find real type (structure or basic types, e.g. int). */ Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem) { do { vr_die = __die_get_real_type(vr_die, die_mem); } while (vr_die && dwarf_tag(vr_die) == DW_TAG_typedef); return vr_die; }
Dwarf_Half DwarfDie::tag() const { Dwarf_Half tagType; const auto res = dwarf_tag(m_die, &tagType, nullptr); if (res != DW_DLV_OK) return {}; return tagType; }
static void DC_show_info_for_containing_pc_ranges(Dwarf_Die die, int enclosing, unsigned long iaddr){ /*This function visits the children of a die in sequence, *applying the action() function to each*/ Dwarf_Attribute highattr; Dwarf_Attribute lowattr; Dwarf_Addr loval,hival; Dwarf_Bool has; Dwarf_Error error; Dwarf_Half tag; loval = hival = 0x0; int enc = 0; dwarf_tag(die,&tag,&error); if( tag == DW_TAG_variable || tag == DW_TAG_formal_parameter ){ if(enclosing){ char *name; dwarf_diename(die,&name,&error); fprintf(stderr,"%s, ",name); //show_all_attrs(die,0,NULL); } } if( tag == DW_TAG_lexical_block || tag == DW_TAG_subprogram ){ if( dwarf_lowpc(die,&loval,&error) == DW_DLV_OK && dwarf_highpc(die,&hival,&error) == DW_DLV_OK && iaddr >=loval && iaddr <= hival ){ enc = 1; fprintf(stderr,"\n=================================\n"); show_all_attrs(die,0,NULL); fprintf(stderr,"=================================\n"); } } Dwarf_Die kid; if( dwarf_child(die,&kid,&error) == DW_DLV_NO_ENTRY ){ return; } DC_show_info_for_containing_pc_ranges(kid, enc, iaddr); //visit_die(kid,level+1,action,adata); int chret; while( (chret = dwarf_siblingof(d,kid,&kid,&error)) != DW_DLV_NO_ENTRY && chret != DW_DLV_ERROR){ DC_show_info_for_containing_pc_ranges(kid, enc, iaddr); //visit_die(kid,level+1,action,adata); } return; }
static VALUE rd_die_tag_name(VALUE self) { rd_die_t *die = GetDie(self); Dwarf_Half tag = 0; Dwarf_Error err; chkerr1(dwarf_tag(die->die, &tag, &err), &err, self); return rb_hash_aref(rdwarf_tag2name, INT2FIX(tag)); }
/** \brief Finds the number of elements in a array type (DW_TAG_array_type) * * The compilation unit might be needed because the default lower * bound depends on the language of the compilation unit. * * \param die the DIE of the DW_TAG_array_type * \param unit the DIE of the compilation unit * \return number of elements in this array type * */ static uint64_t MC_dwarf_array_element_count(Dwarf_Die * die, Dwarf_Die * unit) { xbt_assert(dwarf_tag(die) == DW_TAG_array_type, "MC_dwarf_array_element_count called with DIE of type %s", simgrid::dwarf::tagname(die)); int result = 1; Dwarf_Die child; int res; for (res = dwarf_child(die, &child); res == 0; res = dwarf_siblingof(&child, &child)) { int child_tag = dwarf_tag(&child); if (child_tag == DW_TAG_subrange_type || child_tag == DW_TAG_enumeration_type) result *= MC_dwarf_subrange_element_count(&child, unit); } return result; }
static int frame_callback(Dwfl_Frame *frame, void *userdata) { struct stack_context *c = userdata; Dwarf_Addr pc, pc_adjusted, bias = 0; _cleanup_free_ Dwarf_Die *scopes = NULL; const char *fname = NULL, *symbol = NULL; Dwfl_Module *module; bool is_activation; assert(frame); assert(c); if (c->n_frame >= FRAMES_MAX) return DWARF_CB_ABORT; if (!dwfl_frame_pc(frame, &pc, &is_activation)) return DWARF_CB_ABORT; pc_adjusted = pc - (is_activation ? 0 : 1); module = dwfl_addrmodule(c->dwfl, pc_adjusted); if (module) { Dwarf_Die *s, *cudie; int n; cudie = dwfl_module_addrdie(module, pc_adjusted, &bias); if (cudie) { n = dwarf_getscopes(cudie, pc_adjusted - bias, &scopes); for (s = scopes; s < scopes + n; s++) { if (IN_SET(dwarf_tag(s), DW_TAG_subprogram, DW_TAG_inlined_subroutine, DW_TAG_entry_point)) { Dwarf_Attribute *a, space; a = dwarf_attr_integrate(s, DW_AT_MIPS_linkage_name, &space); if (!a) a = dwarf_attr_integrate(s, DW_AT_linkage_name, &space); if (a) symbol = dwarf_formstring(a); if (!symbol) symbol = dwarf_diename(s); if (symbol) break; } } } if (!symbol) symbol = dwfl_module_addrname(module, pc_adjusted); fname = dwfl_module_info(module, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } fprintf(c->f, "#%-2u 0x%016" PRIx64 " %s (%s)\n", c->n_frame, (uint64_t) pc, strna(symbol), strna(fname)); c->n_frame ++; return DWARF_CB_OK; }
Dwarf_Half DieHolder::get_tag(void) { Dwarf_Half tag = 0; Dwarf_Error err = NULL; CHECK_DWERR(dwarf_tag(m_die, &tag, &err), err, "cannot get DIE tag"); return tag; }
static int __die_find_member_cb(Dwarf_Die *die_mem, void *data) { const char *name = data; if ((dwarf_tag(die_mem) == DW_TAG_member) && (die_compare_name(die_mem, name) == 0)) return DIE_FIND_CB_FOUND; return DIE_FIND_CB_SIBLING; }
/* die_find callback for inline function search */ static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data) { Dwarf_Addr *addr = data; if (dwarf_tag(die_mem) == DW_TAG_inlined_subroutine && dwarf_haspc(die_mem, *addr)) return DIE_FIND_CB_END; return DIE_FIND_CB_CONTINUE; }
static void DC_get_info_for_scoped_variable(Dwarf_Die die, int enclosing, unsigned long iaddr, const char *varname, Dwarf_Die *retDie){ /*This function visits the children of a die in sequence, *applying the action() function to each*/ Dwarf_Attribute highattr; Dwarf_Attribute lowattr; Dwarf_Addr loval,hival; Dwarf_Bool has; Dwarf_Error error; Dwarf_Half tag; loval = hival = 0x0; int enc = 0; dwarf_tag(die,&tag,&error); if( tag == DW_TAG_variable || tag == DW_TAG_formal_parameter ){ if(enclosing){ char *name; dwarf_diename(die,&name,&error); if(!strncmp(name,varname,strlen(name))){ *retDie = die; return; } } } if( tag == DW_TAG_lexical_block || tag == DW_TAG_subprogram ){ if( dwarf_lowpc(die,&loval,&error) == DW_DLV_OK && dwarf_highpc(die,&hival,&error) == DW_DLV_OK && iaddr >=loval && iaddr <= hival ){ enc = 1; } } Dwarf_Die kid; if( dwarf_child(die,&kid,&error) == DW_DLV_NO_ENTRY ){ return; } DC_get_info_for_scoped_variable(kid, enc, iaddr,varname,retDie); int chret; while( (chret = dwarf_siblingof(d,kid,&kid,&error)) != DW_DLV_NO_ENTRY && chret != DW_DLV_ERROR){ DC_get_info_for_scoped_variable(kid, enc, iaddr,varname,retDie); } return; }
static int __die_search_func_cb(Dwarf_Die *fn_die, void *data) { struct __addr_die_search_param *ad = data; if (dwarf_tag(fn_die) == DW_TAG_subprogram && dwarf_haspc(fn_die, ad->addr)) { memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die)); return DWARF_CB_ABORT; } return DWARF_CB_OK; }
static void print_die_data(Dwarf_Debug dbg, Dwarf_Die print_me,int level, struct srcfilesdata *sf) { char *name = 0; Dwarf_Error error = 0; Dwarf_Half tag = 0; const char *tagname = 0; int localname = 0; int res = dwarf_diename(print_me,&name,&error); if(res == DW_DLV_ERROR) { printf("Error in dwarf_diename , level %d \n",level); exit(1); } if(res == DW_DLV_NO_ENTRY) { name = "<no DW_AT_name attr>"; localname = 1; } res = dwarf_tag(print_me,&tag,&error); if(res != DW_DLV_OK) { printf("Error in dwarf_tag , level %d \n",level); exit(1); } res = dwarf_get_TAG_name(tag,&tagname); if(res != DW_DLV_OK) { printf("Error in dwarf_get_TAG_name , level %d \n",level); exit(1); } if(namesoptionon) { if( tag == DW_TAG_subprogram) { printf( "<%3d> subprogram : \"%s\"\n",level,name); print_subprog(dbg,print_me,level,sf); } else if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit || tag == DW_TAG_type_unit) { resetsrcfiles(dbg,sf); printf( "<%3d> source file : \"%s\"\n",level,name); print_comp_dir(dbg,print_me,level,sf); } } else { /*edit by liupo*/ if(1 == level && 0 == strcmp(tagname, "DW_TAG_variable")) printf("display ::%s\n", name); /*edit end*/ //printf("<%d> tag: %d %s name: \"%s\"\n",level,tag,tagname,name); } if(!localname) { dwarf_dealloc(dbg,name,DW_DLA_STRING); } }
static int get_member_size(Dwarf_Die *type_die, Dwarf_Word *msize_out) { if (dwarf_aggregate_size(type_die, msize_out) != -1) return (0); if (dwarf_tag(type_die) == DW_TAG_pointer_type) return (pointer_size); dwarf_err(EX_DATAERR, "dwarf_aggregate_size"); return (-1); }
/* List a function if it's in the given DIE. */ void list_func_in_die(Dwarf_Debug dgb, Dwarf_Die the_die, FILE *fp) { char* die_name = 0; const char* tag_name = 0; Dwarf_Error err; Dwarf_Half tag; Dwarf_Attribute* attrs; Dwarf_Addr lowpc, highpc; Dwarf_Signed attrcount, i; int rc = dwarf_diename(the_die, &die_name, &err); if (rc == DW_DLV_ERROR) die("Error in dwarf_diename\n"); else if (rc == DW_DLV_NO_ENTRY) return; if (dwarf_tag(the_die, &tag, &err) != DW_DLV_OK) die("Error in dwarf_tag\n"); /* Only interested in subprogram DIEs here */ if (tag != DW_TAG_subprogram) return; if (dwarf_get_TAG_name(tag, &tag_name) != DW_DLV_OK) die("Error in dwarf_get_TAG_name\n"); //printf("DW_TAG_subprogram: '%s'\n", die_name); fprintf(fp, "%s\t", die_name); /* Grab the DIEs attributes for display */ if (dwarf_attrlist(the_die, &attrs, &attrcount, &err) != DW_DLV_OK) die("Error in dwarf_attlist\n"); for (i = 0; i < attrcount; ++i) { Dwarf_Half attrcode; if (dwarf_whatattr(attrs[i], &attrcode, &err) != DW_DLV_OK) die("Error in dwarf_whatattr\n"); /* We only take some of the attributes for display here. ** More can be picked with appropriate tag constants. */ if (attrcode == DW_AT_low_pc) dwarf_formaddr(attrs[i], &lowpc, 0); else if (attrcode == DW_AT_high_pc) dwarf_formaddr(attrs[i], &highpc, 0); } fprintf(fp, "%08llx\n", lowpc); // printf("low pc : 0x%08llx\n", lowpc); // printf("high pc : 0x%08llx\n", highpc); }
static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data) { const char *name = data; int tag; tag = dwarf_tag(die_mem); if ((tag == DW_TAG_formal_parameter || tag == DW_TAG_variable) && (die_compare_name(die_mem, name) == 0)) return DIE_FIND_CB_FOUND; return DIE_FIND_CB_CONTINUE; }
static Dwarf_Half die_tag(dwarf_t *dw, Dwarf_Die die) { Dwarf_Half tag; if (dwarf_tag(die, &tag, &dw->dw_err) == DW_DLV_OK) return (tag); terminate("die %llu: failed to get tag for type: %s\n", die_off(dw, die), dwarf_errmsg(dw->dw_err)); /*NOTREACHED*/ return (0); }