/* Convert subprogram DIE to trace point */ static int convert_to_trace_point(Dwarf_Die *sp_die, Dwarf_Addr paddr, bool retprobe, struct probe_trace_point *tp) { Dwarf_Addr eaddr; const char *name; /* Copy the name of probe point */ name = dwarf_diename(sp_die); if (name) { if (dwarf_entrypc(sp_die, &eaddr) != 0) { pr_warning("Failed to get entry address of %s\n", dwarf_diename(sp_die)); return -ENOENT; } tp->symbol = strdup(name); if (tp->symbol == NULL) return -ENOMEM; tp->offset = (unsigned long)(paddr - eaddr); } else /* This function has no name. */ tp->offset = (unsigned long)paddr; /* Return probe must be on the head of a subprogram */ if (retprobe) { if (eaddr != paddr) { pr_warning("Return probe must be on the head of" " a real function.\n"); return -EINVAL; } tp->retprobe = true; } return 0; }
bool supported_language(Dwarf_Die *cu) { int ret; Dwarf_Word lang; Dwarf_Attribute at; if (dwarf_attr(cu, DW_AT_language, &at) == NULL) { warn("CU %s: unknown language", dwarf_diename(cu)); return false; } ret = dwarf_formudata(&at, &lang); fail_if(ret == -1, "dwarf_formudata"); switch (lang) { case DW_LANG_C89: case DW_LANG_C: case DW_LANG_C99: /* good! */ break; case DW_LANG_C_plus_plus: warn("CU %s: C++ not supported", dwarf_diename(cu)); return false; break; default: debug("CU %s: unsupported language: 0x%lx", dwarf_diename(cu), (unsigned long)lang); return false; break; } return true; }
static int get_member_offset(Dwarf_Die *memdie, Dwarf_Word *off_out) { Dwarf_Attribute loc_attr; Dwarf_Block block; if (dwarf_attr_integrate(memdie, DW_AT_data_member_location, &loc_attr) == NULL) dwarf_err(EX_DATAERR, "dwarf_attr_integrate(%s/loc)", dwarf_diename(memdie)); switch (dwarf_whatform(&loc_attr)) { case DW_FORM_block: case DW_FORM_block1: case DW_FORM_block2: case DW_FORM_block4: if (dwarf_formblock(&loc_attr, &block)) dwarf_err(EX_DATAERR, "dwarf_formblock(%s)", dwarf_diename(memdie)); assert(block.data[0] == DW_OP_plus_uconst || block.data[0] == DW_OP_constu); get_uleb128(off_out, &block.data[1]); return (0); default: printf("ZZZ!\n"); return (-1); } }
/* Convert subprogram DIE to trace point */ static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod, Dwarf_Addr paddr, bool retprobe, struct probe_trace_point *tp) { Dwarf_Addr eaddr, highaddr; GElf_Sym sym; const char *symbol; /* Verify the address is correct */ if (dwarf_entrypc(sp_die, &eaddr) != 0) { pr_warning("Failed to get entry address of %s\n", dwarf_diename(sp_die)); return -ENOENT; } if (dwarf_highpc(sp_die, &highaddr) != 0) { pr_warning("Failed to get end address of %s\n", dwarf_diename(sp_die)); return -ENOENT; } if (paddr > highaddr) { pr_warning("Offset specified is greater than size of %s\n", dwarf_diename(sp_die)); return -EINVAL; } symbol = dwarf_diename(sp_die); if (!symbol) { /* Try to get the symbol name from symtab */ symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL); if (!symbol) { pr_warning("Failed to find symbol at 0x%lx\n", (unsigned long)paddr); return -ENOENT; } eaddr = sym.st_value; } tp->offset = (unsigned long)(paddr - eaddr); tp->address = (unsigned long)paddr; tp->symbol = strdup(symbol); if (!tp->symbol) return -ENOMEM; /* Return probe must be on the head of a subprogram */ if (retprobe) { if (eaddr != paddr) { pr_warning("Return probe must be on the head of" " a real function.\n"); return -EINVAL; } tp->retprobe = true; } return 0; }
static void get_dwarf_attr(Dwarf_Die *parent, int attr, Dwarf_Attribute *attr_out, Dwarf_Die *die_out) { if (dwarf_attr_integrate(parent, attr, attr_out) == NULL) dwarf_err(EX_DATAERR, "dwarf_attr_integrate(%s/%d)", dwarf_diename(parent), attr); if (dwarf_formref_die(attr_out, die_out) == NULL) dwarf_err(EX_DATAERR, "dwarf_formref_die(%s)", dwarf_diename(parent)); }
/** * die_match_name - Match diename and glob * @dw_die: a DIE * @glob: a string of target glob pattern * * Glob matching the name of @dw_die and @glob. Return false if matching fail. */ bool die_match_name(Dwarf_Die *dw_die, const char *glob) { const char *name; name = dwarf_diename(dw_die); return name ? strglobmatch(name, glob) : false; }
/** * die_compare_name - Compare diename and tname * @dw_die: a DIE * @tname: a string of target name * * Compare the name of @dw_die and @tname. Return false if @dw_die has no name. */ bool die_compare_name(Dwarf_Die *dw_die, const char *tname) { const char *name; name = dwarf_diename(dw_die); return name ? (strcmp(tname, name) == 0) : false; }
static int probe_point_inline_cb(Dwarf_Die *in_die, void *data) { struct probe_finder *pf = data; struct perf_probe_point *pp = &pf->pev->point; Dwarf_Addr addr; int ret; if (pp->lazy_line) ret = find_probe_point_lazy(in_die, pf); else { if (dwarf_entrypc(in_die, &addr) != 0) { pr_warning("Failed to get entry address of %s.\n", dwarf_diename(in_die)); return -ENOENT; } pf->addr = addr; pf->addr += pp->offset; pr_debug("found inline addr: 0x%jx\n", (uintmax_t)pf->addr); ret = call_probe_finder(in_die, pf); } return ret; }
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); } }
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; }
/* 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)); }
static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf) { Dwarf_Die die_mem; int ret; pr_debug("Converting variable %s into trace event.\n", dwarf_diename(vr_die)); ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops, pf->tvar); if (ret == -ENOENT) pr_err("Failed to find the location of %s at this address.\n" " Perhaps, it has been optimized out.\n", pf->pvar->var); else if (ret == -ENOTSUP) pr_err("Sorry, we don't support this variable location yet.\n"); else if (pf->pvar->field) { ret = convert_variable_fields(vr_die, pf->pvar->var, pf->pvar->field, &pf->tvar->ref, &die_mem); vr_die = &die_mem; } if (ret == 0) ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type); return ret; }
static void HandleFunctionDIE (Dwarf_Debug dwHandle, Dwarf_Die currChildDIE) { char *funcName = NULL; Dwarf_Addr lowAddress = 0; Dwarf_Addr highAddress = 0; int dwDieNameRet = dwarf_diename (currChildDIE, &funcName, NULL); int dwDieLowAddrRet = dwarf_lowpc (currChildDIE, &lowAddress, NULL); int dwDieHighAddrRet = dwarf_highpc (currChildDIE, &highAddress, NULL); if ((dwDieNameRet == DW_DLV_OK) && (dwDieLowAddrRet == DW_DLV_OK) && (dwDieHighAddrRet == DW_DLV_OK)) { FunctionMap_Add (funcName, lowAddress, highAddress); } if ((dwDieNameRet == DW_DLV_OK) && (funcName != NULL)) { dwarf_dealloc (dwHandle, funcName, DW_DLA_STRING); } }
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 int probe_point_inline_cb(Dwarf_Die *in_die, void *data) { struct dwarf_callback_param *param = data; struct probe_finder *pf = param->data; struct perf_probe_point *pp = &pf->pev->point; Dwarf_Addr addr; if (pp->lazy_line) param->retval = find_probe_point_lazy(in_die, pf); else { /* Get probe address */ if (dwarf_entrypc(in_die, &addr) != 0) { pr_warning("Failed to get entry pc of %s.\n", dwarf_diename(in_die)); param->retval = -ENOENT; return DWARF_CB_ABORT; } pf->addr = addr; pf->addr += pp->offset; pr_debug("found inline addr: 0x%jx\n", (uintmax_t)pf->addr); param->retval = convert_probe_point(in_die, pf); if (param->retval < 0) return DWARF_CB_ABORT; } return DWARF_CB_OK; }
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 int convert_to_trace_point(Dwarf_Die *sp_die, Dwarf_Addr paddr, bool retprobe, struct probe_trace_point *tp) { Dwarf_Addr eaddr, highaddr; const char *name; name = dwarf_diename(sp_die); if (name) { if (dwarf_entrypc(sp_die, &eaddr) != 0) { pr_warning("Failed to get entry address of %s\n", dwarf_diename(sp_die)); return -ENOENT; } if (dwarf_highpc(sp_die, &highaddr) != 0) { pr_warning("Failed to get end address of %s\n", dwarf_diename(sp_die)); return -ENOENT; } if (paddr > highaddr) { pr_warning("Offset specified is greater than size of %s\n", dwarf_diename(sp_die)); return -EINVAL; } tp->symbol = strdup(name); if (tp->symbol == NULL) return -ENOMEM; tp->offset = (unsigned long)(paddr - eaddr); } else tp->offset = (unsigned long)paddr; if (retprobe) { if (eaddr != paddr) { pr_warning("Return probe must be on the head of" " a real function.\n"); return -EINVAL; } tp->retprobe = true; } return 0; }
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; }
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 handle_function (Dwarf_Die *func, void *arg) { struct args *a = arg; const char *name = dwarf_diename (func); char **argv = a->argv; if (argv[0] != NULL) { bool match; do match = fnmatch (*argv, name, 0) == 0; while (!match && *++argv); if (!match) return 0; } if (dwarf_func_inline (func)) return 0; Dwarf_Addr entrypc; if (dwarf_entrypc (func, &entrypc) != 0) error (EXIT_FAILURE, 0, "dwarf_entrypc: %s: %s", dwarf_diename (func), dwarf_errmsg (-1)); entrypc += a->dwbias; printf ("%-16s %#.16" PRIx64, dwarf_diename (func), entrypc); Dwarf_Addr *bkpts = NULL; int result = dwarf_entry_breakpoints (func, &bkpts); if (result <= 0) printf ("\t%s\n", dwarf_errmsg (-1)); else { for (int i = 0; i < result; ++i) printf (" %#.16" PRIx64 "%s", bkpts[i] + a->dwbias, i == result - 1 ? "\n" : ""); free (bkpts); } return 0; }
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 VALUE rd_die_name(VALUE self) { rd_die_t *die = GetDie(self); char *name; Dwarf_Error err; if (chkerr2(dwarf_diename(die->die, &name, &err), &err)) { return rb_enc_str_new_cstr(name, rb_usascii_encoding()); } else { return Qnil; } }
/* 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 void print_vars (unsigned int indent, Dwarf_Die *die) { Dwarf_Die child; if (dwarf_child (die, &child) == 0) do switch (dwarf_tag (&child)) { case DW_TAG_variable: case DW_TAG_formal_parameter: printf ("%*s%-30s[%6" PRIx64 "]\n", indent, "", dwarf_diename (&child), (uint64_t) dwarf_dieoffset (&child)); break; default: break; } while (dwarf_siblingof (&child, &child) == 0); Dwarf_Attribute attr_mem; Dwarf_Die origin; if (dwarf_hasattr (die, DW_AT_abstract_origin) && dwarf_formref_die (dwarf_attr (die, DW_AT_abstract_origin, &attr_mem), &origin) != NULL && dwarf_child (&origin, &child) == 0) do switch (dwarf_tag (&child)) { case DW_TAG_variable: case DW_TAG_formal_parameter: printf ("%*s%s (abstract)\n", indent, "", dwarf_diename (&child)); break; default: break; } while (dwarf_siblingof (&child, &child) == 0); }
static int convert_variable_type(Dwarf_Die *vr_die, struct kprobe_trace_arg *targ) { Dwarf_Die type; char buf[16]; int ret; if (die_get_real_type(vr_die, &type) == NULL) { pr_warning("Failed to get a type information of %s.\n", dwarf_diename(vr_die)); return -ENOENT; } ret = die_get_byte_size(&type) * 8; if (ret) { /* Check the bitwidth */ if (ret > MAX_BASIC_TYPE_BITS) { pr_info("%s exceeds max-bitwidth." " Cut down to %d bits.\n", dwarf_diename(&type), MAX_BASIC_TYPE_BITS); ret = MAX_BASIC_TYPE_BITS; } ret = snprintf(buf, 16, "%c%d", die_is_signed_type(&type) ? 's' : 'u', ret); if (ret < 0 || ret >= 16) { if (ret >= 16) ret = -E2BIG; pr_warning("Failed to convert variable type: %s\n", strerror(-ret)); return ret; } targ->type = strdup(buf); if (targ->type == NULL) return -ENOMEM; } return 0; }
static int runtime_update_die_cb(pt_pstate *pstate, Dwarf_Die die, void *arg) { struct runtime_update_cb_arg_t *bounds = arg; Dwarf_Die type_die; Dwarf_Half tag; Dwarf_Error err; int res; char *name; res = dwarf_diename(die, &name, &err); if (res == DW_DLV_ERROR) { ERROR_MSG("runtime_update_die_cb(): dwarf_diename() fail.\n"); return 0; } if (res == DW_DLV_NO_ENTRY) { name = "<no DW_AT_name attr>"; } res = dwarf_tag(die, &tag, &err) ; if (res != DW_DLV_OK) { ERROR_MSG("runtime_update_die_cb(): dwarf_tag() fail.\n"); return 0; } if (tag != DW_TAG_variable) return 1; if (dwarfif_get_type_die(pstate->dbg, die, &type_die)) { task_register_cons *trc = pstate->trc; void *p = dwarfif_find_static_var_address(trc, die); u_int32_t address = (u_int32_t)p; DEBUG_MSG("Found variable @ 0x%x, we have lower_bound = 0x%x and upper_bound = 0x%x\n", address, bounds->lower_bound, bounds->upper_bound); if (p != NULL && address >= bounds->lower_bound && address < bounds->upper_bound) { const char *s; if (dwarf_get_TAG_name(tag, &s) != DW_DLV_OK) { ERROR_MSG("%s: Could not get tag name.\n", __func__); return 0; } DEBUG_MSG("Found static variable \"%s\" @ 0x%x, with type %s.\n", name, (u_int32_t)p, s); INFO_MSG("Found type for variable %s\n", name); if (!pt_trace_pointer(pstate, type_die, p)) { DEBUG_MSG("Pointer tracing failed.\n"); } else { DEBUG_MSG("Pointer tracing succeeded.\n"); } } } else { INFO_MSG("Could not get type die for variable, ignoring.\n"); } return 1; }
//print_cmd helper funcs error_t ip_in_func(Dwarf_Die the_die, size_t rip, bool* res){ char* die_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) return E_FATAL; else if (rc == DW_DLV_NO_ENTRY) return E_NONE; if (dwarf_tag(the_die, &tag, &err) != DW_DLV_OK) return E_FATAL; /* Only interested in subprogram DIEs here */ if (tag != DW_TAG_subprogram) return E_NONE; /* Grab the DIEs attributes for display */ if (dwarf_attrlist(the_die, &attrs, &attrcount, &err) != DW_DLV_OK) return E_FATAL; for (i = 0; i < attrcount; ++i) { Dwarf_Half attrcode; if (dwarf_whatattr(attrs[i], &attrcode, &err) != DW_DLV_OK) return E_FATAL; /* 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); } if( rip >= lowpc && rip <= highpc){ *res = true; return E_NONE; } return E_NONE; }
/* Get the name and type of given variable DIE, stored as "type\tname" */ static int die_get_varname(Dwarf_Die *vr_die, char *buf, int len) { int ret, ret2; ret = die_get_typename(vr_die, buf, len); if (ret < 0) { pr_debug("Failed to get type, make it unknown.\n"); ret = snprintf(buf, len, "(unknown_type)"); } if (ret > 0) { ret2 = snprintf(buf + ret, len - ret, "\t%s", dwarf_diename(vr_die)); ret = (ret2 >= len - ret) ? -E2BIG : ret2 + ret; } return ret; }
static VALUE rd_die_inspect(VALUE self) { rd_die_t *die = GetDie(self); char *name; Dwarf_Off dieoff = 0; Dwarf_Error err; dwarf_dieoffset(die->die, &dieoff, &err); switch (dwarf_diename(die->die, &name, &err)) { case DW_DLV_OK: return rb_sprintf("#<%s:(%llu) '%s'>", rb_obj_classname(self), dieoff, name); default: return rb_sprintf("#<%s:(%llu)>", rb_obj_classname(self), dieoff); } }
QByteArray DwarfDie::name() const { Q_ASSERT(m_die); char* dwarfStr; const auto res = dwarf_diename(m_die, &dwarfStr, nullptr); if (res != DW_DLV_OK) { const auto ref = inheritedFrom(); if (ref) return ref->name(); return {}; } const QByteArray s(dwarfStr); dwarf_dealloc(dwarfHandle(), dwarfStr, DW_DLA_STRING); return s; }