static VALUE rd_die_source_files(VALUE self) { rd_die_t *die = GetDie(self); Dwarf_Signed cnt = 0; char **srcfiles = 0; Dwarf_Error err; VALUE files = Qnil; if (die->srcfiles != Qfalse) { return die->srcfiles; } if (chkerr2(dwarf_srcfiles(die->die, &srcfiles, &cnt, &err), &err)) { int i; files = rb_ary_new_capa(cnt); for (i = 0; i < cnt; i++) { VALUE file = rb_str_new_cstr(srcfiles[i]); OBJ_FREEZE(file); rb_ary_store(files, i, file); dwarf_dealloc(die->shared_data->dbg, srcfiles[i], DW_DLA_STRING); } dwarf_dealloc(die->shared_data->dbg, srcfiles, DW_DLA_LIST); } die->srcfiles = files; return files; }
static void print_comp_dir(Dwarf_Debug dbg,Dwarf_Die die,int level, struct srcfilesdata *sf) { int res; Dwarf_Error error = 0; Dwarf_Attribute *attrbuf = 0; Dwarf_Signed attrcount = 0; Dwarf_Unsigned i; res = dwarf_attrlist(die,&attrbuf,&attrcount,&error); if(res != DW_DLV_OK) { return; } sf->srcfilesres = dwarf_srcfiles(die,&sf->srcfiles,&sf->srcfilescount, &error); for(i = 0; i < attrcount ; ++i) { Dwarf_Half aform; res = dwarf_whatattr(attrbuf[i],&aform,&error); if(res == DW_DLV_OK) { if(aform == DW_AT_comp_dir) { char *name = 0; res = dwarf_formstring(attrbuf[i],&name,&error); if(res == DW_DLV_OK) { printf( "<%3d> compilation directory : \"%s\"\n", level,name); } } if(aform == DW_AT_stmt_list) { /* Offset of stmt list for this CU in .debug_line */ } } dwarf_dealloc(dbg,attrbuf[i],DW_DLA_ATTR); } dwarf_dealloc(dbg,attrbuf,DW_DLA_LIST); }
static int handle_debug_aranges(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func, int *errval) { int retval = DW_DLV_OK; Dwarf_Error err; Dwarf_Addr *aranges; Dwarf_Signed count; int indx; Dwarf_Off *offsets; retval = _dwarf_get_aranges_addr_offsets(dbg, &aranges, &offsets, &count, &err); if (retval == DW_DLV_OK) { if (count == 0) { retval = DW_DLV_NO_ENTRY; } else { for (indx = 0; indx < count; indx++) { cb_func(DW_SECTION_ARANGES, offsets[indx], aranges[indx]); } } dwarf_dealloc(dbg, aranges, DW_DLA_ADDR); dwarf_dealloc(dbg, offsets, DW_DLA_ADDR); } else if (retval == DW_DLV_NO_ENTRY) { ; /* do nothing */ } else { *errval = (int) dwarf_errno(err); retval = DW_DLV_ERROR; } return retval; }
static int handle_debug_line(Dwarf_Debug dbg, Dwarf_Die cu_die, Dwarf_addr_callback_func cb_func, int *errval) { int retval = DW_DLV_OK; int res; Dwarf_Error err; Dwarf_Addr *addrlist; Dwarf_Off *offsetlist; Dwarf_Unsigned count; Dwarf_Unsigned i; res = _dwarf_line_address_offsets(dbg, cu_die, &addrlist, &offsetlist, &count, &err); if (res == DW_DLV_OK) { for (i = 0; i < count; i++) { cb_func(DW_SECTION_LINE, offsetlist[i], addrlist[i]); } dwarf_dealloc(dbg, offsetlist, DW_DLA_ADDR); dwarf_dealloc(dbg, addrlist, DW_DLA_ADDR); } else if (res == DW_DLV_NO_ENTRY) { retval = res; } else { *errval = (int) dwarf_errno(err); retval = DW_DLV_ERROR; } return retval; }
/* To properly release all spaced used. Earlier approaches (before July 15, 2005) letting client do the dealloc directly left some data allocated. This is directly called by consumer code. */ void dwarf_fde_cie_list_dealloc(Dwarf_Debug dbg, Dwarf_Cie * cie_data, Dwarf_Signed cie_element_count, Dwarf_Fde * fde_data, Dwarf_Signed fde_element_count) { Dwarf_Signed i = 0; for (i = 0; i < cie_element_count; ++i) { Dwarf_Frame frame = cie_data[i]->ci_initial_table; if (frame) dwarf_dealloc(dbg, frame, DW_DLA_FRAME); dwarf_dealloc(dbg, cie_data[i], DW_DLA_CIE); } for (i = 0; i < fde_element_count; ++i) { dwarf_dealloc(dbg, fde_data[i], DW_DLA_FDE); } if (cie_data) dwarf_dealloc(dbg, cie_data, DW_DLA_LIST); if (fde_data) dwarf_dealloc(dbg, fde_data, DW_DLA_LIST); }
static void DC_get_location_attr_value(Dwarf_Attribute at, DC_location *dcl){ /* * It is assumed that at has a block form, and is a location list * so this won't fail. Caller is responsible for checking. */ Dwarf_Locdesc *locationList; Dwarf_Signed listLength; Dwarf_Error error; int frameRel = 0; long offset = 0; int i; int ret = dwarf_loclist( at, &locationList, &listLength, &error ); if( ret != DW_DLV_OK ){ return; } /*Get the location info*/ decode_location(locationList,listLength,&(dcl->offset),NULL,&(dcl->isFrameOffset)); /*Clean up*/ for( i = 0; i < listLength; ++i){ dwarf_dealloc(d,locationList[i].ld_s,DW_DLA_LOC_BLOCK); } dwarf_dealloc(d,locationList,DW_DLA_LOCDESC); }
static int die_mem_offset(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Unsigned *valp, int req) { Dwarf_Attribute attr; Dwarf_Locdesc *loc; Dwarf_Signed locnum; if ((attr = die_attr(dw, die, name, req)) == NULL) return (0); /* die_attr will terminate for us if necessary */ if (dwarf_loclist(attr, &loc, &locnum, &dw->dw_err) != DW_DLV_OK) { terminate("die %llu: failed to get mem offset location list\n", die_off(dw, die)); } dwarf_dealloc(dw->dw_dw, attr, DW_DLA_ATTR); if (locnum != 1 || loc->ld_s->lr_atom != DW_OP_plus_uconst) { terminate("die %llu: cannot parse member offset\n", die_off(dw, die)); } *valp = loc->ld_s->lr_number; dwarf_dealloc(dw->dw_dw, loc->ld_s, DW_DLA_LOC_BLOCK); dwarf_dealloc(dw->dw_dw, loc, DW_DLA_LOCDESC); return (1); }
DieHolder::~DieHolder(void) throw() { m_origin_holder.reset(); if(m_name != NULL) { dwarf_dealloc(m_dbg, m_name, DW_DLA_STRING); m_name = NULL; } for(MapAttrs::iterator iter = m_attrs.begin(); iter != m_attrs.end(); ++iter) { if(iter->second != NULL) { dwarf_dealloc(m_dbg, iter->second, DW_DLA_ATTR); iter->second = NULL; } } if(m_dealloc_die) { dwarf_dealloc(m_dbg, m_die, DW_DLA_DIE); } m_die = NULL; }
/* Recursively follow the DIE tree */ static int process_die_and_children(Dwarf_Debug dbg, Dwarf_Die in_die) { Dwarf_Die cur_die = in_die; Dwarf_Die child; Dwarf_Die sib_die; int is_function; int ret; ret = process_one_DIE(dbg, in_die, &is_function); if (ret != 0) return 1; while (1) { if (!is_function) /* Assume that there is no nested function, so we ignore the children of a function */ { ret = dwarf_child(cur_die, &child, NULL); if (ret == DW_DLV_ERROR) { fprintf(stderr, "SET dwarf: Error in dwarf_child()\n"); return 1; } /* Recursive call */ if (ret == DW_DLV_OK) { ret = process_die_and_children(dbg, child); dwarf_dealloc(dbg, child, DW_DLA_DIE); if (ret != 0) return 1; } } /* Current DIE has no children */ ret = dwarf_siblingof(dbg, cur_die, &sib_die, NULL); if (ret == DW_DLV_ERROR) { fprintf(stderr, "SET dwarf: Error in dwarf_siblingof()\n"); return 1; } if (cur_die != in_die) dwarf_dealloc(dbg, cur_die, DW_DLA_DIE); if (ret == DW_DLV_NO_ENTRY) { /* Done at this level */ break; } /* ret == DW_DLV_OK */ cur_die = sib_die; ret = process_one_DIE(dbg, cur_die, &is_function); if (ret != 0) return 1; } return 0; }
int _dwarf_get_string_from_tied(Dwarf_Debug dbg, Dwarf_Unsigned offset, char **return_str, Dwarf_Error*error) { Dwarf_Debug tieddbg = 0; Dwarf_Small *secend = 0; Dwarf_Small *secbegin = 0; Dwarf_Small *strbegin = 0; int res = DW_DLV_ERROR; Dwarf_Error localerror = 0; /* Attach errors to dbg, not tieddbg. */ tieddbg = dbg->de_tied_data.td_tied_object; if (!tieddbg) { _dwarf_error(dbg, error, DW_DLE_NO_TIED_FILE_AVAILABLE); return DW_DLV_ERROR; } /* The 'offset' into .debug_str is set. */ res = _dwarf_load_section(tieddbg, &tieddbg->de_debug_str,&localerror); if (res == DW_DLV_ERROR) { Dwarf_Unsigned lerrno = dwarf_errno(localerror); dwarf_dealloc(tieddbg,localerror,DW_DLA_ERROR); _dwarf_error(dbg,error,lerrno); return res; } else if (res == DW_DLV_NO_ENTRY) { return res; } if (offset >= tieddbg->de_debug_str.dss_size) { /* Badly damaged DWARF here. */ _dwarf_error(dbg, error, DW_DLE_NO_TIED_STRING_AVAILABLE); return (DW_DLV_ERROR); } secbegin = tieddbg->de_debug_str.dss_data; strbegin= tieddbg->de_debug_str.dss_data + offset; secend = tieddbg->de_debug_str.dss_data + tieddbg->de_debug_str.dss_size; /* Ensure the offset lies within the .debug_str */ if (offset >= tieddbg->de_debug_str.dss_size) { _dwarf_error(dbg, error, DW_DLE_NO_TIED_STRING_AVAILABLE); return (DW_DLV_ERROR); } res= _dwarf_check_string_valid(tieddbg,secbegin,strbegin, secend, &localerror); if (res == DW_DLV_ERROR) { Dwarf_Unsigned lerrno = dwarf_errno(localerror); dwarf_dealloc(tieddbg,localerror,DW_DLA_ERROR); _dwarf_error(dbg,error,lerrno); return res; } else if (res == DW_DLV_NO_ENTRY) { return res; } *return_str = (char *) (tieddbg->de_debug_str.dss_data + offset); return DW_DLV_OK; }
static struct dwarf_subprogram_t *read_from_cus(Dwarf_Debug dbg) { Dwarf_Unsigned cu_header_length, abbrev_offset, next_cu_header; Dwarf_Half version_stamp, address_size; Dwarf_Error err; Dwarf_Die no_die = 0, cu_die, child_die, next_die; int ret = DW_DLV_OK; int rc; struct dwarf_subprogram_t *subprograms = NULL; while (ret == DW_DLV_OK) { ret = dwarf_next_cu_header( dbg, &cu_header_length, &version_stamp, &abbrev_offset, &address_size, &next_cu_header, &err); DWARF_ASSERT(ret, err); if (ret == DW_DLV_NO_ENTRY) continue; /* TODO: If the CU can provide an address range then we can skip over * all the entire die if none of our addresses match */ /* Expect the CU to have a single sibling - a DIE */ ret = dwarf_siblingof(dbg, no_die, &cu_die, &err); if (ret == DW_DLV_ERROR) { continue; } DWARF_ASSERT(ret, err); /* Expect the CU DIE to have children */ ret = dwarf_child(cu_die, &child_die, &err); DWARF_ASSERT(ret, err); next_die = child_die; /* Now go over all children DIEs */ do { subprograms = read_cu_entry(subprograms, dbg, cu_die, child_die); rc = dwarf_siblingof(dbg, child_die, &next_die, &err); DWARF_ASSERT(rc, err); dwarf_dealloc(dbg, child_die, DW_DLA_DIE); child_die = next_die; } while (rc != DW_DLV_NO_ENTRY); dwarf_dealloc(dbg, cu_die, DW_DLA_DIE); } return subprograms; }
static struct dwarf_subprogram_t *read_from_cus(Dwarf_Debug dbg) { Dwarf_Unsigned cu_header_length, abbrev_offset, next_cu_header; Dwarf_Half version_stamp, address_size; Dwarf_Error err; Dwarf_Die no_die = 0, cu_die, child_die; int ret = DW_DLV_OK; struct dwarf_subprogram_t *subprograms = NULL; Dwarf_Unsigned language = 0; Dwarf_Attribute language_attr = 0; while (ret == DW_DLV_OK) { ret = dwarf_next_cu_header( dbg, &cu_header_length, &version_stamp, &abbrev_offset, &address_size, &next_cu_header, &err); DWARF_ASSERT(ret, err); if (ret == DW_DLV_NO_ENTRY) continue; /* TODO: If the CU can provide an address range then we can skip over * all the entire die if none of our addresses match */ /* Expect the CU to have a single sibling - a DIE */ ret = dwarf_siblingof(dbg, no_die, &cu_die, &err); if (ret == DW_DLV_ERROR) { continue; } DWARF_ASSERT(ret, err); /* Get compilation unit language attribute */ ret = dwarf_attr(cu_die, DW_AT_language, &language_attr, &err); DWARF_ASSERT(ret, err); if (ret != DW_DLV_NO_ENTRY) { /* Get language attribute data */ ret = dwarf_formudata(language_attr, &language, &err); DWARF_ASSERT(ret, err); dwarf_dealloc(dbg, language_attr, DW_DLA_ATTR); } /* Expect the CU DIE to have children */ ret = dwarf_child(cu_die, &child_die, &err); DWARF_ASSERT(ret, err); handle_die(&subprograms, dbg, cu_die, child_die, language); dwarf_dealloc(dbg, cu_die, DW_DLA_DIE); } return subprograms; }
/* When llbuf (see dwarf_loclist_n) is partially set up and an error is encountered, tear it down as it won't be used. */ static void _dwarf_cleanup_llbuf(Dwarf_Debug dbg, Dwarf_Locdesc ** llbuf, int count) { int i; for (i = 0; i < count; ++i) { dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK); dwarf_dealloc(dbg, llbuf[i], DW_DLA_LOCDESC); } dwarf_dealloc(dbg, llbuf, DW_DLA_LIST); }
int _dwarf_internal_get_die_comp_dir(Dwarf_Die die, const char **compdir_out, const char **compname_out, Dwarf_Error *error) { Dwarf_Attribute comp_dir_attr = 0; Dwarf_Attribute comp_name_attr = 0; int resattr = 0; Dwarf_Debug dbg = 0; dbg = die->di_cu_context->cc_dbg; resattr = dwarf_attr(die, DW_AT_name, &comp_name_attr, error); if (resattr == DW_DLV_ERROR) { return resattr; } if (resattr == DW_DLV_OK) { int cres = DW_DLV_ERROR; char *name = 0; cres = dwarf_formstring(comp_name_attr, &name, error); if (cres == DW_DLV_ERROR) { dwarf_dealloc(dbg, comp_name_attr, DW_DLA_ATTR); return cres; } else if (cres == DW_DLV_OK) { *compname_out = (const char *)name; } else { /* FALL thru */ } } if (resattr == DW_DLV_OK) { dwarf_dealloc(dbg, comp_name_attr, DW_DLA_ATTR); } resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error); if (resattr == DW_DLV_ERROR) { return resattr; } if (resattr == DW_DLV_OK) { int cres = DW_DLV_ERROR; char *cdir = 0; cres = dwarf_formstring(comp_dir_attr, &cdir, error); if (cres == DW_DLV_ERROR) { dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR); return cres; } else if (cres == DW_DLV_OK) { *compdir_out = (const char *) cdir; } else { /* FALL thru */ } } if (resattr == DW_DLV_OK) { dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR); } return resattr; }
static void print_subprog(Dwarf_Debug dbg,Dwarf_Die die, int level, struct srcfilesdata *sf) { int res; Dwarf_Error error = 0; Dwarf_Attribute *attrbuf = 0; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; Dwarf_Signed attrcount = 0; Dwarf_Unsigned i; Dwarf_Unsigned filenum = 0; Dwarf_Unsigned linenum = 0; char *filename = 0; res = dwarf_attrlist(die,&attrbuf,&attrcount,&error); if(res != DW_DLV_OK) { return; } for(i = 0; i < attrcount ; ++i) { Dwarf_Half aform; res = dwarf_whatattr(attrbuf[i],&aform,&error); if(res == DW_DLV_OK) { if(aform == DW_AT_decl_file) { get_number(attrbuf[i],&filenum); if((filenum > 0) && (sf->srcfilescount > (filenum-1))) { filename = sf->srcfiles[filenum-1]; } } if(aform == DW_AT_decl_line) { get_number(attrbuf[i],&linenum); } if(aform == DW_AT_low_pc) { get_addr(attrbuf[i],&lowpc); } if(aform == DW_AT_high_pc) { get_addr(attrbuf[i],&highpc); } } dwarf_dealloc(dbg,attrbuf[i],DW_DLA_ATTR); } if(filenum || linenum) { printf("<%3d> file: %" DW_PR_DUu " %s line %" DW_PR_DUu "\n",level,filenum,filename?filename:"",linenum); } if(lowpc) { printf("<%3d> low_pc : 0x%" DW_PR_DUx "\n", level, (Dwarf_Unsigned)lowpc); } if(highpc) { printf("<%3d> high_pc: 0x%" DW_PR_DUx "\n", level, (Dwarf_Unsigned)highpc); } dwarf_dealloc(dbg,attrbuf,DW_DLA_LIST); }
static int get_attributes(Dwarf_Debug dbg,Dwarf_Die die, int level, struct srcfilesdata *sf, struct attributes *attr) { int res; Dwarf_Error error = 0; Dwarf_Attribute *attrbuf = 0; Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; Dwarf_Signed attrcount = 0; Dwarf_Unsigned i; Dwarf_Unsigned filenum = 0; Dwarf_Unsigned linenum = 0; char *filename = 0; int ret = 1; res = dwarf_attrlist(die,&attrbuf,&attrcount,&error); if(res != DW_DLV_OK) { return ret; } for(i = 0; i < attrcount ; ++i) { Dwarf_Half aform; res = dwarf_whatattr(attrbuf[i],&aform,&error); if(res == DW_DLV_OK) { if(aform == DW_AT_decl_file) { get_number(attrbuf[i],&filenum); if((filenum > 0) && (sf->srcfilescount > (filenum-1))) { filename = sf->srcfiles[filenum-1]; attr->filename = filename; } } if(aform == DW_AT_declaration) { Dwarf_Unsigned size=0; get_number(attrbuf[i],&size); ret =0; } if(aform == DW_AT_byte_size) { attr->size=0; get_number(attrbuf[i],&attr->size); } if(aform == DW_AT_data_member_location) { attr->member_location=0; get_number(attrbuf[i],&attr->member_location); } if(aform == DW_AT_type) { attr->type_offset = 0; dwarf_global_formref(attrbuf[i],&(attr->type_offset),&error); } } dwarf_dealloc(dbg,attrbuf[i],DW_DLA_ATTR); } dwarf_dealloc(dbg,attrbuf,DW_DLA_LIST); return ret; }
static void resetsrcfiles(Dwarf_Debug dbg,struct srcfilesdata *sf) { Dwarf_Signed sri = 0; for (sri = 0; sri < sf->srcfilescount; ++sri) { dwarf_dealloc(dbg, sf->srcfiles[sri], DW_DLA_STRING); } dwarf_dealloc(dbg, sf->srcfiles, DW_DLA_LIST); sf->srcfilesres = DW_DLV_ERROR; sf->srcfiles = 0; sf->srcfilescount = 0; }
static void freecontextlist(Dwarf_Debug dbg, Dwarf_Debug_InfoTypes dis) { Dwarf_CU_Context context = 0; Dwarf_CU_Context nextcontext = 0; for (context = dis->de_cu_context_list; context; context = nextcontext) { Dwarf_Hash_Table hash_table = context->cc_abbrev_hash_table; _dwarf_free_abbrev_hash_table_contents(dbg,hash_table); nextcontext = context->cc_next; dwarf_dealloc(dbg, hash_table, DW_DLA_HASH_TABLE); dwarf_dealloc(dbg, context, DW_DLA_CU_CONTEXT); } }
void dwarf_ranges_dealloc(Dwarf_Debug dbg, Dwarf_Ranges * rangesbuf, Dwarf_Signed rangecount) { dwarf_dealloc(dbg,rangesbuf, DW_DLA_RANGES); }
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 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); } }
/* Often errs and errt point to the same Dwarf_Error, So exercise care. All the arguments MUST be non-null.*/ void _dwarf_error_mv_s_to_t(Dwarf_Debug dbgs,Dwarf_Error *errs, Dwarf_Debug dbgt,Dwarf_Error *errt) { if (!errt || !errs) { return; } if (!dbgs || !dbgt) { return; } if(dbgs == dbgt) { if(errs != errt) { Dwarf_Error ers = *errs; *errs = 0; *errt = ers; } } else { /* Do not stomp on the system errno variable if there is one! */ int mydw_errno = dwarf_errno(*errs); dwarf_dealloc(dbgs,*errs, DW_DLA_ERROR); *errs = 0; _dwarf_error(dbgt,errt, mydw_errno); } }
static int _dwarf_macro_stack_push_index(Dwarf_Debug dbg, Dwarf_Signed indx, struct macro_stack_s *ms) { Dwarf_Signed *newbase; if (ms->next_to_use >= ms->max) { long new_size; if (ms->max == 0) { ms->max = STARTERMAX; } new_size = ms->max * 2; newbase = (Dwarf_Signed *)_dwarf_get_alloc(dbg, DW_DLA_STRING, new_size * sizeof(Dwarf_Signed)); if (newbase == 0) { /* just leave the old array in place */ ms->was_fault = 1; return DW_DLV_ERROR; } if (ms->st_base) { memcpy(newbase, ms->st_base, ms->next_to_use * sizeof(Dwarf_Signed)); dwarf_dealloc(dbg, ms->st_base, DW_DLA_STRING); } ms->st_base = newbase; ms->max = new_size; } ms->st_base[ms->next_to_use] = indx; ++ms->next_to_use; return DW_DLV_OK; }
QVector< Dwarf_Half > DwarfDie::attributes() const { Dwarf_Attribute* attrList; Dwarf_Signed attrCount; auto res = dwarf_attrlist(m_die, &attrList, &attrCount, nullptr); if (res != DW_DLV_OK) return {}; QVector<Dwarf_Half> attrs; attrs.reserve(attrCount); for (int i = 0; i < attrCount; ++i) { Dwarf_Half attrType; res = dwarf_whatattr(attrList[i], &attrType, nullptr); if (res != DW_DLV_OK) continue; attrs.push_back(attrType); } dwarf_dealloc(dwarfHandle(), attrList, DW_DLA_LIST); if (const auto die = inheritedFrom()) { auto inheritedAttrs = die->attributes(); // remove attributes that must not be inherited inheritedAttrs.erase( std::remove_if(inheritedAttrs.begin(), inheritedAttrs.end(), [](Dwarf_Half at) { return at == DW_AT_declaration || at == DW_AT_sibling; }), inheritedAttrs.end()); attrs += inheritedAttrs; std::sort(attrs.begin(), attrs.end()); attrs.erase(std::unique(attrs.begin(), attrs.end()), attrs.end()); } return attrs; }
static void handle_die( struct dwarf_subprogram_t **subprograms, Dwarf_Debug dbg, Dwarf_Die cu_die, Dwarf_Die the_die, Dwarf_Unsigned language) { int rc; Dwarf_Error err; Dwarf_Die current_die = the_die; Dwarf_Die child_die = NULL; Dwarf_Die next_die; do { *subprograms = read_cu_entry(*subprograms, dbg, cu_die, current_die, language); /* Recursive call handle_die with child, to continue searching within child dies */ rc = dwarf_child(current_die, &child_die, &err); DWARF_ASSERT(rc, err); if (rc == DW_DLV_OK && child_die) handle_die(subprograms, dbg, cu_die, child_die, language); rc = dwarf_siblingof(dbg, current_die, &next_die, &err); DWARF_ASSERT(rc, err); dwarf_dealloc(dbg, current_die, DW_DLA_DIE); current_die = next_die; } while (rc != DW_DLV_NO_ENTRY); }
void CUsHolder::clean(void) throw() { Dwarf_Error err = NULL; int ret = 0; for(size_t idx = 0; idx < size(); ++idx) { dwarf_dealloc(m_dbg, (*this)[idx], DW_DLA_DIE); (*this)[idx] = NULL; } ret = dwarf_finish(m_dbg, &err); if(ret != DW_DLV_OK) { MSG("libdwarf cleanup failed: %s\n", dwarf_errmsg(err)); } clear(); m_dbg = NULL; if(m_fd != -1) { close(m_fd), m_fd = -1; } }
/* process each compilation unit(CU) in .debug_info */ static int process_CUs(Dwarf_Debug dbg) { Dwarf_Unsigned next_cu_header; int ret; while ((ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, &next_cu_header, NULL)) == DW_DLV_OK) { /* process a single compilation unit in .debug_info. */ Dwarf_Die cu_die; ret = dwarf_siblingof(dbg, NULL, &cu_die, NULL); if (ret != DW_DLV_OK) { fprintf(stderr, "SET dwarf: Error in dwarf_siblingof()\n"); return 1; } ret = process_die_and_children(dbg, cu_die); dwarf_dealloc(dbg, cu_die, DW_DLA_DIE); if (ret != 0) return 1; } if (ret == DW_DLV_ERROR) { fprintf(stderr, "SET dwarf: Error in dwarf_next_cu_header()\n"); return 1; } else return 0; }
/* Get the size (in words) */ static int get_size(Dwarf_Debug dbg, Dwarf_Die die) { Dwarf_Attribute attr; Dwarf_Unsigned size; int ret; ret = dwarf_attr(die, DW_AT_byte_size, &attr, NULL); if (ret != DW_DLV_OK) { fprintf(stderr, "SET dwarf: Error in dwarf_attr()\n"); return 1; } ret = dwarf_formudata(attr, &size, NULL); dwarf_dealloc(dbg, attr, DW_DLA_ATTR); if (ret != DW_DLV_OK) { fprintf(stderr, "SET dwarf: Error in dwarf_formudata()\n"); return 1; } /* Increment the parameter number of the function */ func_dwarf[local_func_idx].param_size += (size + 3) >> 2; return 0; }
/* Return DW_DLV_OK or, if error, DW_DLV_ERROR. Thru pointers, return 2 arrays and a count for rqs. */ int _dwarf_line_address_offsets(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr ** addrs, Dwarf_Off ** offs, Dwarf_Unsigned * returncount, Dwarf_Error * err) { Dwarf_Addr *laddrs; Dwarf_Off *loffsets; Dwarf_Signed lcount; Dwarf_Signed i; int res; Dwarf_Line *linebuf; res = _dwarf_internal_srclines(die, &linebuf, &lcount, /* addrlist= */ true, /* linelist= */ false, err); if (res != DW_DLV_OK) { return res; } laddrs = (Dwarf_Addr *) _dwarf_get_alloc(dbg, DW_DLA_ADDR, lcount); if (laddrs == NULL) { _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } loffsets = (Dwarf_Off *) _dwarf_get_alloc(dbg, DW_DLA_ADDR, lcount); if (loffsets == NULL) { _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); return (DW_DLV_ERROR); } for (i = 0; i < lcount; i++) { laddrs[i] = linebuf[i]->li_address; loffsets[i] = linebuf[i]->li_addr_line.li_offset; dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE); } dwarf_dealloc(dbg, linebuf, DW_DLA_LIST); *returncount = lcount; *offs = loffsets; *addrs = laddrs; return DW_DLV_OK; }
void dwarf_loc_head_c_dealloc(Dwarf_Loc_Head_c loclist_head) { Dwarf_Debug dbg = loclist_head->ll_dbg; Dwarf_Locdesc_c desc = loclist_head->ll_locdesc; if( desc) { Dwarf_Unsigned listlen = loclist_head->ll_locdesc_count; Dwarf_Unsigned i = 0; for ( ; i < listlen; ++i) { Dwarf_Loc_c loc = desc[i].ld_s; if(loc) { dwarf_dealloc(dbg,loc,DW_DLA_LOC_BLOCK_C); } } dwarf_dealloc(dbg,desc,DW_DLA_LOCDESC_C); } dwarf_dealloc(dbg,loclist_head,DW_DLA_LOC_HEAD_C); }