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 VALUE rdwarf_compile_units(VALUE self) { rdwarf_t *rd = GetRDwarf(self); Dwarf_Unsigned cu_header_length = 0; Dwarf_Unsigned abbrev_offset = 0; Dwarf_Half version_stamp = 0; Dwarf_Half address_size = 0; Dwarf_Unsigned next_cu_offset = 0; Dwarf_Error err; Dwarf_Die die; VALUE ary; if (rd->compile_units != Qfalse) { return rd->compile_units; } ary = rb_ary_new(); while (dwarf_next_cu_header(rd->shared_data->dbg, &cu_header_length, &version_stamp, &abbrev_offset, &address_size, &next_cu_offset, &err) == DW_DLV_OK) { if (!chkerr2(dwarf_siblingof(rd->shared_data->dbg, NULL, &die, &err), &err)) { continue; } rb_ary_push(ary, rd_die_new(rd->shared_data, self, Qnil, die)); } rd->compile_units = ary; return ary; }
/* 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; }
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); }
/** * die_find_child - Generic DIE search function in DIE tree * @rt_die: a root DIE * @callback: a callback function * @data: a user data passed to the callback function * @die_mem: a buffer for result DIE * * Trace DIE tree from @rt_die and call @callback for each child DIE. * If @callback returns DIE_FIND_CB_END, this stores the DIE into * @die_mem and returns it. If @callback returns DIE_FIND_CB_CONTINUE, * this continues to trace the tree. Optionally, @callback can return * DIE_FIND_CB_CHILD and DIE_FIND_CB_SIBLING, those means trace only * the children and trace only the siblings respectively. * Returns NULL if @callback can't find any appropriate DIE. */ Dwarf_Die *die_find_child(Dwarf_Die *rt_die, int (*callback)(Dwarf_Die *, void *), void *data, Dwarf_Die *die_mem) { Dwarf_Die child_die; int ret; ret = dwarf_child(rt_die, die_mem); if (ret != 0) return NULL; do { ret = callback(die_mem, data); if (ret == DIE_FIND_CB_END) return die_mem; if ((ret & DIE_FIND_CB_CHILD) && die_find_child(die_mem, callback, data, &child_die)) { memcpy(die_mem, &child_die, sizeof(Dwarf_Die)); return die_mem; } } while ((ret & DIE_FIND_CB_SIBLING) && dwarf_siblingof(die_mem, die_mem) == 0); return NULL; }
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; }
//file_cmd helper funcs //DBG init and exit functions error_t load_dbg(mygdb_info_t* gdb_info){ Dwarf_Error err; Dwarf_Die no_die = 0; Dwarf_Unsigned cu_header_length; Dwarf_Half version_stamp; Dwarf_Unsigned abbrev_offset; Dwarf_Half addr_size; Dwarf_Unsigned nxt_cu_hdr; gdb_info->dbg_fd = open(gdb_info->src_file, O_RDONLY); if( dwarf_init(gdb_info->dbg_fd,DW_DLC_READ,0,0, &gdb_info->dbg, &err) != DW_DLV_OK ) return E_FATAL; printf("Succesfully loaded symbol info\n"); int res; if( (res = dwarf_next_cu_header(gdb_info->dbg, &cu_header_length, &version_stamp, &abbrev_offset, &addr_size, &nxt_cu_hdr, &err)) == DW_DLV_ERROR ){ printf("failed to get next header\n"); return E_FATAL; } if( dwarf_siblingof(gdb_info->dbg, no_die, &gdb_info->cu_die, &err) == DW_DLV_ERROR){ printf("siblingof() failed\n"); return E_FATAL; } return E_NONE; }
/* 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; }
/* Return DW_DLV_OK, ERROR, or NO_ENTRY. */ static int handle_debug_info(Dwarf_Debug dbg, int *errval) { Dwarf_Unsigned nxtoff = 1; Dwarf_Unsigned hdr_length; Dwarf_Half version_stamp; Dwarf_Unsigned abbrev_offset; Dwarf_Half addr_size; Dwarf_Error err; int terminate_now = 0; int res = 0; Dwarf_Die sibdie; int sibres; int nres = DW_DLV_OK; for (nres = dwarf_next_cu_header(dbg, &hdr_length, &version_stamp, &abbrev_offset, &addr_size, &nxtoff, &err); terminate_now == 0 && nres == DW_DLV_OK; nres = dwarf_next_cu_header(dbg, &hdr_length, &version_stamp, &abbrev_offset, &addr_size, &nxtoff, &err) ) { Dwarf_Die curdie = 0; /* try to get the compilation unit die */ sibres = dwarf_siblingof(dbg, curdie, &sibdie, &err); if (sibres == DW_DLV_OK) { res = do_this_die_and_dealloc(dbg, sibdie, errval); switch (res) { case DW_DLV_OK: break; case DW_DLV_NO_ENTRY: break; default: case DW_DLV_ERROR: return DW_DLV_ERROR; } } else if (sibres == DW_DLV_ERROR) { *errval = (int) dwarf_errno(err); return DW_DLV_ERROR; } else { /* NO ENTRY! */ /* impossible? */ } } if (nres == DW_DLV_ERROR) { int localerr = (int) dwarf_errno(err); *errval = localerr; return DW_DLV_ERROR; } return DW_DLV_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 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; }
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 void read_cu_list(Dwarf_Debug dbg) { Dwarf_Unsigned cu_header_length = 0; Dwarf_Half version_stamp = 0; Dwarf_Unsigned abbrev_offset = 0; Dwarf_Half address_size = 0; Dwarf_Unsigned next_cu_header = 0; Dwarf_Error error; int cu_number = 0; for(;;++cu_number) { /*edit by liupo*/ //printf("\n--------------CU_NUMBER-%d-----------------\n", cu_number); /*end edit*/ struct srcfilesdata sf; sf.srcfilesres = DW_DLV_ERROR; sf.srcfiles = 0; sf.srcfilescount = 0; Dwarf_Die no_die = 0; Dwarf_Die cu_die = 0; int res = DW_DLV_ERROR; res = dwarf_next_cu_header(dbg,&cu_header_length, &version_stamp, &abbrev_offset, &address_size, &next_cu_header, &error); if(res == DW_DLV_ERROR) { printf("Error in dwarf_next_cu_header\n"); exit(1); } if(res == DW_DLV_NO_ENTRY) { /*edit by liupo*/ //printf("\n-------------CU_NUMBER--------------\n"); /*end edit*/ /* Done. */ return; } /* The CU will have a single sibling, a cu_die. */ res = dwarf_siblingof(dbg,no_die,&cu_die,&error); if(res == DW_DLV_ERROR) { printf("Error in dwarf_siblingof on CU die \n"); exit(1); } if(res == DW_DLV_NO_ENTRY) { /* Impossible case. */ printf("no entry! in dwarf_siblingof on CU die \n"); exit(1); } get_die_and_siblings(dbg,cu_die,0,&sf); dwarf_dealloc(dbg,cu_die,DW_DLA_DIE); resetsrcfiles(dbg,&sf); } }
static void MC_dwarf_handle_children(simgrid::mc::ObjectInformation* info, Dwarf_Die * die, Dwarf_Die * unit, simgrid::mc::Frame* frame, const char *ns) { // For each child DIE: Dwarf_Die child; int res; for (res = dwarf_child(die, &child); res == 0; res = dwarf_siblingof(&child, &child)) MC_dwarf_handle_die(info, &child, unit, frame, ns); }
Dwarf_Die DieHolder::get_sibling(void) { Dwarf_Die sibling_die = NULL; Dwarf_Error err = NULL; // there may be no sibling CHECK_DWERR2(dwarf_siblingof(m_dbg, m_die, &sibling_die, &err) == DW_DLV_ERROR, err, "error when asking for a DIE sibling"); return sibling_die; }
static void tp_dwarf_child_first(void) { Dwarf_Debug dbg; Dwarf_Error de; Dwarf_Die die, die0; Dwarf_Unsigned cu_next_offset; int r, fd, result, die_cnt; result = TET_UNRESOLVED; TS_DWARF_INIT(dbg, fd, de); tet_infoline("count the number of children of compilation unit DIE"); die_cnt = 0; TS_DWARF_CU_FOREACH(dbg, cu_next_offset, de) { r = dwarf_siblingof(dbg, NULL, &die, &de); if (r == DW_DLV_OK) { r = dwarf_child(die, &die0, &de); while (r == DW_DLV_OK) { if (die0 == NULL) { tet_infoline("dwarf_child or " "dwarf_siblingof return " "DW_DLV_OK while argument die0 " "is not filled in"); result = TET_FAIL; goto done; } die_cnt++; die = die0; r = dwarf_siblingof(dbg, die, &die0, &de); } } if (r == DW_DLV_ERROR) { tet_printf("dwarf_siblingof or dwarf_child failed:" " %s\n", dwarf_errmsg(de)); result = TET_FAIL; goto done; } }
static Dwarf_Die _get_next_function_helper(Dwarf_Die compilation_die, Dwarf_Debug dbg){ Dwarf_Die cur_die=compilation_die; Dwarf_Die sib_die = 0; Dwarf_Error error; Dwarf_Half tag = 0; int res = DW_DLV_ERROR; res = dwarf_siblingof(dbg,cur_die,&sib_die,&error); cur_die=sib_die; while(res==DW_DLV_OK){ dwarf_tag(cur_die,&tag,&error); if (tag == DW_TAG_subprogram){ //found the first function return cur_die; } res = dwarf_siblingof(dbg,cur_die,&sib_die,&error); cur_die=sib_die; } }
static struct dwarf_compilation_unit * read_cu_list(Dwarf_Debug dbg) { Dwarf_Unsigned cu_header_length = 0; Dwarf_Half version_stamp = 0; Dwarf_Unsigned abbrev_offset = 0; Dwarf_Half address_size = 0; Dwarf_Unsigned next_cu_header = 0; Dwarf_Error error; int cu_number = 0; struct dwarf_compilation_unit * cu = NULL; //for(;;++cu_number) { struct srcfilesdata sf; sf.srcfilesres = DW_DLV_ERROR; sf.srcfiles = 0; sf.srcfilescount = 0; Dwarf_Die no_die = 0; Dwarf_Die cu_die = 0; int res = DW_DLV_ERROR; res = dwarf_next_cu_header(dbg,&cu_header_length, &version_stamp, &abbrev_offset, &address_size, &next_cu_header, &error); if(res == DW_DLV_ERROR) { printf("Error in dwarf_next_cu_header\n"); exit(1); } if(res == DW_DLV_NO_ENTRY) { /* Done. */ return NULL; } /* The CU will have a single sibling, a cu_die. */ res = dwarf_siblingof(dbg,no_die,&cu_die,&error); if(res == DW_DLV_ERROR) { printf("Error in dwarf_siblingof on CU die \n"); exit(1); } if(res == DW_DLV_NO_ENTRY) { // Impossible case. printf("no entry! in dwarf_siblingof on CU die \n"); exit(1); } cu = malloc(sizeof(struct dwarf_compilation_unit)); cu->root_die = cu_die; return cu; /*get_die_and_siblings(dbg,cu_die,0,&sf); dwarf_dealloc(dbg,cu_die,DW_DLA_DIE); resetsrcfiles(dbg,&sf);*/ //} }
/* List all the functions from the file represented by the given descriptor. */ void list_funcs_in_file(Dwarf_Debug dbg, FILE *fp) { 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; /* Find compilation unit header */ if (dwarf_next_cu_header( dbg, &cu_header_length, &version_stamp, &abbrev_offset, &address_size, &next_cu_header, &err) == DW_DLV_ERROR) die("Error reading DWARF cu header\n"); /* Expect the CU to have a single sibling - a DIE */ if (dwarf_siblingof(dbg, no_die, &cu_die, &err) == DW_DLV_ERROR) die("Error getting sibling of CU\n"); /* Expect the CU DIE to have children */ if (dwarf_child(cu_die, &child_die, &err) == DW_DLV_ERROR) die("Error getting child of CU DIE\n"); /* Now go over all children DIEs */ while (1) { int rc; list_func_in_die(dbg, child_die, fp); rc = dwarf_siblingof(dbg, child_die, &child_die, &err); if (rc == DW_DLV_ERROR) die("Error getting sibling of DIE\n"); else if (rc == DW_DLV_NO_ENTRY) break; /* done */ } }
DwarfDie DwarfDie::GetSibling() const { Dwarf_Die new_die; Dwarf_Error derr; int error; error = dwarf_siblingof(dwarf, die, &new_die, &derr); if (error != DW_DLV_OK) return DwarfDie(dwarf, nullptr); else return DwarfDie(dwarf, new_die); }
DwarfDie DwarfDie::GetCuDie(Dwarf_Debug dwarf) { int error; Dwarf_Die die; Dwarf_Error derr; error = dwarf_siblingof(dwarf, NULL, &die, &derr); if (error != 0) return DwarfDie(); else return DwarfDie(dwarf, die); }
static void checked_siblingof (Dwarf_Die **diep, Dwarf_Die *die_memp) { switch (dwarf_siblingof (*diep, die_memp)) { case -1: __refl_seterr (REFL_E_DWARF); case 1: *diep = NULL; case 0: break; } }
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 void tp_dwarf_die_offset_sanity(void) { Dwarf_Debug dbg; Dwarf_Die die; Dwarf_Error de; Dwarf_Off rel_off, die_off, cu_off, cu_len; Dwarf_Unsigned cu_next_offset; int fd; result = TET_UNRESOLVED; TS_DWARF_INIT(dbg, fd, de); TS_DWARF_CU_FOREACH(dbg, cu_next_offset, de) { if (dwarf_siblingof(dbg, NULL, &die, &de) == DW_DLV_ERROR) { tet_printf("dwarf_siblingof failed: %s\n", dwarf_errmsg(de)); result = TET_FAIL; goto done; } if (dwarf_die_CU_offset(NULL, &rel_off, &de) != DW_DLV_ERROR) { tet_infoline("dwarf_die_CU_offset didn't return" " DW_DLV_ERROR when called with NULL arguments"); result = TET_FAIL; goto done; } if (dwarf_die_CU_offset_range(NULL, &cu_off, &cu_len, &de) != DW_DLV_ERROR) { tet_infoline("dwarf_die_CU_offset_range didn't return" " DW_DLV_ERROR when called with NULL arguments"); result = TET_FAIL; goto done; } if (dwarf_dieoffset(NULL, &die_off, &de) != DW_DLV_ERROR) { tet_infoline("dwarf_dieoffset didn't return DW_DLV_ERROR" " when called with NULL arguments"); result = TET_FAIL; goto done; } } if (result == TET_UNRESOLVED) result = TET_PASS; done: TS_DWARF_FINISH(dbg, de); TS_RESULT(result); }
static Dwarf_Die _get_next_variable(Dwarf_Die die, Dwarf_Die original_die, struct dwarf_compilation_unit * unit){ Dwarf_Die sib_die = 0; Dwarf_Die child = 0; Dwarf_Half tag = 0; Dwarf_Error error; int res; //first, see what type this is dwarf_tag(die,&tag,&error); if ((tag == DW_TAG_variable || tag == DW_TAG_formal_parameter) && die != original_die){ return die; } //go through each child res = dwarf_child(die,&child,&error); if(res == DW_DLV_OK) { Dwarf_Die result = _get_next_variable(child,original_die,unit); if (result > 0){ return result; } } //now do the siblings res = dwarf_siblingof(unit->dbg,die,&sib_die,&error); Dwarf_Die old_die = 0; while(res != DW_DLV_ERROR && (old_die != sib_die)){ old_die=sib_die; if(res == DW_DLV_OK) { dwarf_tag(sib_die,&tag,&error); if (tag == DW_TAG_variable || tag == DW_TAG_formal_parameter){ return sib_die; } res = dwarf_siblingof(unit->dbg,sib_die,&sib_die,&error); } } return NULL; }
static void tp_dwarf_siblingof_level1(void) { Dwarf_Debug dbg; Dwarf_Error de; Dwarf_Die die, die0; Dwarf_Unsigned cu_next_offset; int r, fd, result, die_cnt; result = TET_UNRESOLVED; TS_DWARF_INIT(dbg, fd, de); tet_infoline("count the number of level 1 DIEs"); die_cnt = 0; TS_DWARF_CU_FOREACH(dbg, cu_next_offset, de) { r = dwarf_siblingof(dbg, NULL, &die, &de); while (r == DW_DLV_OK) { if (die == NULL) { tet_infoline("dwarf_siblingof return DW_DLV_OK" " while argument die is not filled in"); result = TET_FAIL; goto done; } die_cnt++; die0 = die; r = dwarf_siblingof(dbg, die0, &die, &de); } if (r == DW_DLV_ERROR) { tet_printf("dwarf_siblingof failed: %s\n", dwarf_errmsg(de)); result = TET_FAIL; goto done; } }
static Dwarf_Die die_sibling(dwarf_t *dw, Dwarf_Die die) { Dwarf_Die sib; int rc; if ((rc = dwarf_siblingof(dw->dw_dw, die, &sib, &dw->dw_err)) == DW_DLV_OK) return (sib); else if (rc == DW_DLV_NO_ENTRY) return (NULL); terminate("die %llu: failed to find type sibling: %s\n", die_off(dw, die), dwarf_errmsg(dw->dw_err)); /*NOTREACHED*/ return (NULL); }
static Dwarf_Die get_cu_by_iaddr(unsigned long iaddr){ Dwarf_Unsigned cu_h_len; Dwarf_Half verstamp; Dwarf_Unsigned abbrev_offset; Dwarf_Half addrsize; Dwarf_Unsigned next_cu; Dwarf_Error error; while( dwarf_next_cu_header(d, &cu_h_len, &verstamp, &abbrev_offset, &addrsize, &next_cu, &error) == DW_DLV_OK ){ Dwarf_Die cu_die = NULL; int sibret; int dieno = 0; while((sibret = dwarf_siblingof(d,cu_die,&cu_die,&error)) != DW_DLV_NO_ENTRY && sibret != DW_DLV_ERROR){ Dwarf_Attribute lowattr; if( dwarf_attr(cu_die, DW_AT_low_pc, &lowattr, &error) != DW_DLV_OK ){ continue; } Dwarf_Attribute highattr; if( dwarf_attr(cu_die, DW_AT_high_pc, &highattr, &error) != DW_DLV_OK ){ continue; } Dwarf_Addr loval,hival; dwarf_formaddr(lowattr,&loval,&error); dwarf_formaddr(highattr,&hival,&error); if(iaddr >= loval && iaddr <= hival){ return cu_die; } } } return (Dwarf_Die)-1; }
static void get_die_and_siblings(Dwarf_Debug dbg, Dwarf_Die in_die,int in_level, struct srcfilesdata *sf) { int res = DW_DLV_ERROR; Dwarf_Die cur_die=in_die; Dwarf_Die child = 0; Dwarf_Error error; print_die_data(dbg,in_die,in_level,sf); for(;;) { /*edit by liupo*/ //printf("\n-----------SIB-%d----------------\n", in_level); /*end edit*/ Dwarf_Die sib_die = 0; res = dwarf_child(cur_die,&child,&error); if(res == DW_DLV_ERROR) { printf("Error in dwarf_child , level %d \n",in_level); exit(1); } if(res == DW_DLV_OK) { get_die_and_siblings(dbg,child,in_level+1,sf); } /* res == DW_DLV_NO_ENTRY */ res = dwarf_siblingof(dbg,cur_die,&sib_die,&error); if(res == DW_DLV_ERROR) { printf("Error in dwarf_siblingof , level %d \n",in_level); exit(1); } if(res == DW_DLV_NO_ENTRY) { /* Done at this level. */ break; } /* res == DW_DLV_OK */ if(cur_die != in_die) { dwarf_dealloc(dbg,cur_die,DW_DLA_DIE); } cur_die = sib_die; print_die_data(dbg,cur_die,in_level,sf); } return; }
/* Find the next DIE matching this tag. Uses the internal state of dbg to * determine where to start searching. */ static Dwarf_Die next_die_matching_tag(Dwarf_Debug dbg, Dwarf_Tag search_tag) { Dwarf_Half tag = 0; Dwarf_Die die = NULL; Dwarf_Error de = {0}; while (dwarf_siblingof(dbg, die, &die, &de) == DW_DLV_OK) { if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { NOTIFY_DWARF(de); die = NULL; break; } if (tag == search_tag) break; } return die; }