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 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 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; }
/* 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 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 void HandleFunctionDIE (Dwarf_Debug dwHandle, Dwarf_Die currChildDIE) { char *funcName = NULL; Dwarf_Addr lowAddress = 0; Dwarf_Addr highAddress = 0; int dwDieNameRet, dwDieLowAddrRet, dwDieHighAddrRet; dwDieNameRet = dwarf_diename (currChildDIE, &funcName, &dw_err); if (dwDieNameRet != DW_DLV_OK) mpiPi_msg_debug("Failed to get DIE name : %s\n", dwarf_errmsg(dw_err)); dwDieLowAddrRet = dwarf_lowpc (currChildDIE, &lowAddress, &dw_err); if (dwDieLowAddrRet != DW_DLV_OK) mpiPi_msg_debug("Failed to get low PC : %s\n", dwarf_errmsg(dw_err)); dwDieHighAddrRet = dwarf_highpc (currChildDIE, &highAddress, &dw_err); if (dwDieHighAddrRet != DW_DLV_OK) mpiPi_msg_debug("Failed to get high PC : %s\n", dwarf_errmsg(dw_err)); 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); } }
/* Iterate over all the CUs in the module to find the CU containing the given * PC. */ static Dwarf_Die find_cu_die_via_iter(Dwarf_Debug dbg, Dwarf_Addr pc) { Dwarf_Die die = NULL; Dwarf_Unsigned cu_offset = 0; Dwarf_Error de = {0}; Dwarf_Die cu_die = NULL; while (dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, &cu_offset, &de) == DW_DLV_OK) { /* Scan forward in the tag soup for a CU DIE. */ die = next_die_matching_tag(dbg, DW_TAG_compile_unit); /* We found a CU die, now check if it's the one we wanted. */ if (die != NULL) { Dwarf_Addr lo_pc, hi_pc; if (dwarf_lowpc(die, &lo_pc, &de) != DW_DLV_OK || dwarf_highpc(die, &hi_pc, &de) != DW_DLV_OK) { NOTIFY_DWARF(de); break; } if (lo_pc <= pc && pc < hi_pc) { cu_die = die; break; } } } while (dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, &cu_offset, &de) == DW_DLV_OK) { /* Reset the internal CU header state. */ } return cu_die; }
/* List a function if it's in the given DIE. */ static struct dwarf_subprogram_t *read_cu_entry( struct dwarf_subprogram_t *subprograms, Dwarf_Debug dbg, Dwarf_Die cu_die, Dwarf_Die the_die) { char* die_name = 0; Dwarf_Error err; Dwarf_Half tag; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; char *filename; struct dwarf_subprogram_t *subprogram = NULL; int rc; Dwarf_Attribute attrib = 0; rc = dwarf_tag(the_die, &tag, &err); if (rc != DW_DLV_OK) fatal("unable to parse dwarf tag"); /* Only interested in subprogram DIEs here */ if (tag != DW_TAG_subprogram) return subprograms; rc = dwarf_diename(the_die, &die_name, &err); if (rc == DW_DLV_ERROR) fatal("unable to parse dwarf diename"); if (rc == DW_DLV_NO_ENTRY) return subprograms; rc = dwarf_attr(cu_die, DW_AT_name, &attrib, &err); DWARF_ASSERT(rc, err); if (rc != DW_DLV_NO_ENTRY) { rc = dwarf_formstring(attrib, &filename, &err); DWARF_ASSERT(rc, err); dwarf_dealloc(dbg, attrib, DW_DLA_ATTR); } rc = dwarf_lowpc(the_die, &lowpc, &err); DWARF_ASSERT(rc, err); rc = dwarf_highpc(the_die, &highpc, &err); DWARF_ASSERT(rc, err); /* TODO: when would these not be defined? */ if (lowpc && highpc) { subprogram = malloc(sizeof(*subprogram)); if (!subprogram) fatal("unable to allocate memory"); memset(subprogram, 0, sizeof(*subprogram)); subprogram->lowpc = lowpc; subprogram->highpc = highpc; subprogram->name = die_name; subprogram->next = subprograms; subprograms = subprogram; } return subprograms; }
/* simple but too slow */ struct dwarf_subprogram_t *read_from_globals(Dwarf_Debug dbg) { Dwarf_Global *globals = NULL; Dwarf_Signed nglobals; Dwarf_Off offset; Dwarf_Die die; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; Dwarf_Error err; Dwarf_Attribute attrib = 0; struct dwarf_subprogram_t *subprograms = NULL; struct dwarf_subprogram_t *subprogram = NULL; char *name; int i; int ret; ret = dwarf_get_globals(dbg, &globals, &nglobals, &err); DWARF_ASSERT(ret, err); if (ret != DW_DLV_OK) fatal("unable to get dwarf globals"); for (i = 0; i < nglobals; i++) { ret = dwarf_global_die_offset(globals[i], &offset, &err); DWARF_ASSERT(ret, err); /* TODO: this function does a linear search, making it pretty damn * slow.. see libdwarf/dwarf_die_deliv.c:_dwarf_find_CU_Context * for details */ ret = dwarf_offdie(dbg, offset, &die, &err); DWARF_ASSERT(ret, err); ret = dwarf_lowpc(die, &lowpc, &err); DWARF_ASSERT(ret, err); ret = dwarf_highpc(die, &highpc, &err); DWARF_ASSERT(ret, err); /* TODO: when would these not be defined? */ if (lowpc && highpc) { subprogram = malloc(sizeof(*subprogram)); if (!subprogram) fatal("unable to allocate memory for subprogram"); memset(subprogram, 0, sizeof(*subprogram)); ret = dwarf_attr(die, DW_AT_MIPS_linkage_name, &attrib, &err); if (ret == DW_DLV_OK) { ret = dwarf_formstring(attrib, &name, &err); DWARF_ASSERT(ret, err); dwarf_dealloc(dbg, attrib, DW_DLA_ATTR); } else { ret = dwarf_globname(globals[i], &name, &err); DWARF_ASSERT(ret, err); } subprogram->lowpc = lowpc; subprogram->highpc = highpc; subprogram->name = name; subprogram->next = subprograms; subprograms = subprogram; } dwarf_dealloc(dbg, die, DW_DLA_DIE); } return subprograms; }
/* * Convert a location into trace_arg. * If tvar == NULL, this just checks variable can be converted. * If fentry == true and vr_die is a parameter, do huristic search * for the location fuzzed by function entry mcount. */ static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr, Dwarf_Op *fb_ops, Dwarf_Die *sp_die, struct probe_trace_arg *tvar) { Dwarf_Attribute attr; Dwarf_Addr tmp = 0; Dwarf_Op *op; size_t nops; unsigned int regn; Dwarf_Word offs = 0; bool ref = false; const char *regs; int ret; if (dwarf_attr(vr_die, DW_AT_external, &attr) != NULL) goto static_var; /* TODO: handle more than 1 exprs */ if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL) return -EINVAL; /* Broken DIE ? */ if (dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0) { ret = dwarf_entrypc(sp_die, &tmp); if (ret || addr != tmp || dwarf_tag(vr_die) != DW_TAG_formal_parameter || dwarf_highpc(sp_die, &tmp)) return -ENOENT; /* * This is fuzzed by fentry mcount. We try to find the * parameter location at the earliest address. */ for (addr += 1; addr <= tmp; addr++) { if (dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) > 0) goto found; } return -ENOENT; } found: if (nops == 0) /* TODO: Support const_value */ return -ENOENT; if (op->atom == DW_OP_addr) { static_var: if (!tvar) return 0; /* Static variables on memory (not stack), make @varname */ ret = strlen(dwarf_diename(vr_die)); tvar->value = zalloc(ret + 2); if (tvar->value == NULL) return -ENOMEM; snprintf(tvar->value, ret + 2, "@%s", dwarf_diename(vr_die)); tvar->ref = alloc_trace_arg_ref((long)offs); if (tvar->ref == NULL) return -ENOMEM; return 0; } /* If this is based on frame buffer, set the offset */ if (op->atom == DW_OP_fbreg) { if (fb_ops == NULL) return -ENOTSUP; ref = true; offs = op->number; op = &fb_ops[0]; } if (op->atom >= DW_OP_breg0 && op->atom <= DW_OP_breg31) { regn = op->atom - DW_OP_breg0; offs += op->number; ref = true; } else if (op->atom >= DW_OP_reg0 && op->atom <= DW_OP_reg31) { regn = op->atom - DW_OP_reg0; } else if (op->atom == DW_OP_bregx) { regn = op->number; offs += op->number2; ref = true; } else if (op->atom == DW_OP_regx) { regn = op->number; } else { pr_debug("DW_OP %x is not supported.\n", op->atom); return -ENOTSUP; } if (!tvar) return 0; regs = get_arch_regstr(regn); if (!regs) { /* This should be a bug in DWARF or this tool */ pr_warning("Mapping for the register number %u " "missing on this architecture.\n", regn); return -ERANGE; } tvar->value = strdup(regs); if (tvar->value == NULL) return -ENOMEM; if (ref) { tvar->ref = alloc_trace_arg_ref((long)offs); if (tvar->ref == NULL) return -ENOMEM; } return 0; }
void handle (Dwarf *dbg, Dwarf_Die *die, int n) { Dwarf_Die child; unsigned int tag; const char *str; char buf[30]; const char *name; Dwarf_Off off; Dwarf_Off cuoff; size_t cnt; Dwarf_Addr addr; int i; tag = dwarf_tag (die); if (tag != DW_TAG_invalid) { if (tag < ntagnames) str = tagnames[tag]; else { snprintf (buf, sizeof buf, "%#x", tag); str = buf; } } else str = "* NO TAG *"; name = dwarf_diename (die); if (name == 0) name = "* NO NAME *"; off = dwarf_dieoffset (die); cuoff = dwarf_cuoffset (die); printf ("%*s%s\n", n * 5, "", str); printf ("%*s Name : %s\n", n * 5, "", name); printf ("%*s Offset : %lld\n", n * 5, "", (long long int) off); printf ("%*s CU offset : %lld\n", n * 5, "", (long long int) cuoff); printf ("%*s Attrs :", n * 5, ""); for (cnt = 0; cnt < nattrs; ++cnt) if (dwarf_hasattr (die, attrs[cnt].code)) printf (" %s", attrs[cnt].name); puts (""); if (dwarf_hasattr (die, DW_AT_low_pc) && dwarf_lowpc (die, &addr) == 0) { Dwarf_Attribute attr; Dwarf_Addr addr2; printf ("%*s low PC : %#llx\n", n * 5, "", (unsigned long long int) addr); if (dwarf_attr (die, DW_AT_low_pc, &attr) == NULL || dwarf_formaddr (&attr, &addr2) != 0 || addr != addr2) puts ("************* DW_AT_low_pc verify failed ************"); else if (! dwarf_hasform (&attr, DW_FORM_addr)) puts ("************* DW_AT_low_pc form failed ************"); else if (dwarf_whatform (&attr) != DW_FORM_addr) puts ("************* DW_AT_low_pc form (2) failed ************"); else if (dwarf_whatattr (&attr) != DW_AT_low_pc) puts ("************* DW_AT_low_pc attr failed ************"); } if (dwarf_hasattr (die, DW_AT_high_pc) && dwarf_highpc (die, &addr) == 0) { Dwarf_Attribute attr; Dwarf_Addr addr2; printf ("%*s high PC : %#llx\n", n * 5, "", (unsigned long long int) addr); if (dwarf_attr (die, DW_AT_high_pc, &attr) == NULL || dwarf_formaddr (&attr, &addr2) != 0 || addr != addr2) puts ("************* DW_AT_high_pc verify failed ************"); else if (! dwarf_hasform (&attr, DW_FORM_addr)) puts ("************* DW_AT_high_pc form failed ************"); else if (dwarf_whatform (&attr) != DW_FORM_addr) puts ("************* DW_AT_high_pc form (2) failed ************"); else if (dwarf_whatattr (&attr) != DW_AT_high_pc) puts ("************* DW_AT_high_pc attr failed ************"); } if (dwarf_hasattr (die, DW_AT_byte_size) && (i = dwarf_bytesize (die)) != -1) { Dwarf_Attribute attr; Dwarf_Word u2; unsigned int u; printf ("%*s byte size : %d\n", n * 5, "", i); if (dwarf_attr (die, DW_AT_byte_size, &attr) == NULL || dwarf_formudata (&attr, &u2) != 0 || i != (int) u2) puts ("************* DW_AT_byte_size verify failed ************"); else if (! dwarf_hasform (&attr, DW_FORM_data1) && ! dwarf_hasform (&attr, DW_FORM_data2) && ! dwarf_hasform (&attr, DW_FORM_data4) && ! dwarf_hasform (&attr, DW_FORM_data8) && ! dwarf_hasform (&attr, DW_FORM_sdata) && ! dwarf_hasform (&attr, DW_FORM_udata)) puts ("************* DW_AT_byte_size form failed ************"); else if ((u = dwarf_whatform (&attr)) == 0 || (u != DW_FORM_data1 && u != DW_FORM_data2 && u != DW_FORM_data4 && u != DW_FORM_data8 && u != DW_FORM_sdata && u != DW_FORM_udata)) puts ("************* DW_AT_byte_size form (2) failed ************"); else if (dwarf_whatattr (&attr) != DW_AT_byte_size) puts ("************* DW_AT_byte_size attr failed ************"); } if (dwarf_hasattr (die, DW_AT_bit_size) && (i = dwarf_bitsize (die)) != -1) { Dwarf_Attribute attr; Dwarf_Word u2; unsigned int u; printf ("%*s bit size : %d\n", n * 5, "", i); if (dwarf_attr (die, DW_AT_bit_size, &attr) == NULL || dwarf_formudata (&attr, &u2) != 0 || i != (int) u2) puts ("************* DW_AT_bit_size test failed ************"); else if (! dwarf_hasform (&attr, DW_FORM_data1) && ! dwarf_hasform (&attr, DW_FORM_data2) && ! dwarf_hasform (&attr, DW_FORM_data4) && ! dwarf_hasform (&attr, DW_FORM_data8) && ! dwarf_hasform (&attr, DW_FORM_sdata) && ! dwarf_hasform (&attr, DW_FORM_udata)) puts ("************* DW_AT_bit_size form failed ************"); else if ((u = dwarf_whatform (&attr)) == 0 || (u != DW_FORM_data1 && u != DW_FORM_data2 && u != DW_FORM_data4 && u != DW_FORM_data8 && u != DW_FORM_sdata && u != DW_FORM_udata)) puts ("************* DW_AT_bit_size form (2) failed ************"); else if (dwarf_whatattr (&attr) != DW_AT_bit_size) puts ("************* DW_AT_bit_size attr failed ************"); } if (dwarf_hasattr (die, DW_AT_bit_offset) && (i = dwarf_bitoffset (die)) != -1) { Dwarf_Attribute attr; Dwarf_Word u2; unsigned int u; printf ("%*s bit offset: %d\n", n * 5, "", i); if (dwarf_attr (die, DW_AT_bit_offset, &attr) == NULL || dwarf_formudata (&attr, &u2) != 0 || i != (int) u2) puts ("************* DW_AT_bit_offset test failed ************"); else if (! dwarf_hasform (&attr, DW_FORM_data1) && ! dwarf_hasform (&attr, DW_FORM_data2) && ! dwarf_hasform (&attr, DW_FORM_data4) && ! dwarf_hasform (&attr, DW_FORM_data8) && ! dwarf_hasform (&attr, DW_FORM_sdata) && ! dwarf_hasform (&attr, DW_FORM_udata)) puts ("************* DW_AT_bit_offset form failed ************"); else if ((u = dwarf_whatform (&attr)) == 0 || (u != DW_FORM_data1 && u != DW_FORM_data2 && u != DW_FORM_data4 && u != DW_FORM_data8 && u != DW_FORM_sdata && u != DW_FORM_udata)) puts ("************* DW_AT_bit_offset form (2) failed ************"); else if (dwarf_whatattr (&attr) != DW_AT_bit_offset) puts ("************* DW_AT_bit_offset attr failed ************"); } if (dwarf_hasattr (die, DW_AT_language) && (i = dwarf_srclang (die)) != -1) { Dwarf_Attribute attr; Dwarf_Word u2; unsigned int u; printf ("%*s language : %d\n", n * 5, "", i); if (dwarf_attr (die, DW_AT_language, &attr) == NULL || dwarf_formudata (&attr, &u2) != 0 || i != (int) u2) puts ("************* DW_AT_language test failed ************"); else if (! dwarf_hasform (&attr, DW_FORM_data1) && ! dwarf_hasform (&attr, DW_FORM_data2) && ! dwarf_hasform (&attr, DW_FORM_data4) && ! dwarf_hasform (&attr, DW_FORM_data8) && ! dwarf_hasform (&attr, DW_FORM_sdata) && ! dwarf_hasform (&attr, DW_FORM_udata)) puts ("************* DW_AT_language form failed ************"); else if ((u = dwarf_whatform (&attr)) == 0 || (u != DW_FORM_data1 && u != DW_FORM_data2 && u != DW_FORM_data4 && u != DW_FORM_data8 && u != DW_FORM_sdata && u != DW_FORM_udata)) puts ("************* DW_AT_language form (2) failed ************"); else if (dwarf_whatattr (&attr) != DW_AT_language) puts ("************* DW_AT_language attr failed ************"); } if (dwarf_hasattr (die, DW_AT_ordering) && (i = dwarf_arrayorder (die)) != -1) { Dwarf_Attribute attr; Dwarf_Word u2; unsigned int u; printf ("%*s ordering : %d\n", n * 5, "", i); if (dwarf_attr (die, DW_AT_ordering, &attr) == NULL || dwarf_formudata (&attr, &u2) != 0 || i != (int) u2) puts ("************* DW_AT_ordering test failed ************"); else if (! dwarf_hasform (&attr, DW_FORM_data1) && ! dwarf_hasform (&attr, DW_FORM_data2) && ! dwarf_hasform (&attr, DW_FORM_data4) && ! dwarf_hasform (&attr, DW_FORM_data8) && ! dwarf_hasform (&attr, DW_FORM_sdata) && ! dwarf_hasform (&attr, DW_FORM_udata)) puts ("************* DW_AT_ordering failed ************"); else if ((u = dwarf_whatform (&attr)) == 0 || (u != DW_FORM_data1 && u != DW_FORM_data2 && u != DW_FORM_data4 && u != DW_FORM_data8 && u != DW_FORM_sdata && u != DW_FORM_udata)) puts ("************* DW_AT_ordering form (2) failed ************"); else if (dwarf_whatattr (&attr) != DW_AT_ordering) puts ("************* DW_AT_ordering attr failed ************"); } if (dwarf_hasattr (die, DW_AT_comp_dir)) { Dwarf_Attribute attr; if (dwarf_attr (die, DW_AT_comp_dir, &attr) == NULL || (name = dwarf_formstring (&attr)) == NULL) puts ("************* DW_AT_comp_dir attr failed ************"); else printf ("%*s directory : %s\n", n * 5, "", name); } if (dwarf_hasattr (die, DW_AT_producer)) { Dwarf_Attribute attr; if (dwarf_attr (die, DW_AT_producer, &attr) == NULL || (name = dwarf_formstring (&attr)) == NULL) puts ("************* DW_AT_comp_dir attr failed ************"); else printf ("%*s producer : %s\n", n * 5, "", name); } if (dwarf_haschildren (die) != 0 && dwarf_child (die, &child) == 0) handle (dbg, &child, n + 1); if (dwarf_siblingof (die, die) == 0) handle (dbg, die, n); }
static void DC_show_vars_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); DC_type t; DC_resolve_type(die,&t); fprintf(stderr,"%s ",t.name); int i; for(i = 0; i < t.indirectionLevel; i++){ fprintf(stderr,"*"); } fprintf(stderr,"%s",name); for(i = 0; i < t.arrayLevel; i++){ fprintf(stderr,"[]"); } fprintf(stderr,","); } } 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_show_vars_for_containing_pc_ranges(kid, enc, iaddr); int chret; while( (chret = dwarf_siblingof(d,kid,&kid,&error)) != DW_DLV_NO_ENTRY && chret != DW_DLV_ERROR){ DC_show_vars_for_containing_pc_ranges(kid, enc, iaddr); } return; }