int dwarf_attrval_string(Dwarf_Die die, Dwarf_Half attr, const char **strp, Dwarf_Error *err) { Dwarf_Attribute at; Dwarf_Debug dbg; dbg = die != NULL ? die->die_dbg : NULL; if (die == NULL || strp == NULL) { DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } *strp = NULL; if ((at = _dwarf_attr_find(die, attr)) == NULL) { DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } switch (at->at_form) { case DW_FORM_strp: *strp = at->u[1].s; break; case DW_FORM_string: *strp = at->u[0].s; break; default: DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD); return (DW_DLV_ERROR); } return (DW_DLV_OK); }
int dwarf_highpc_b(Dwarf_Die die, Dwarf_Addr *ret_highpc, Dwarf_Half *ret_form, enum Dwarf_Form_Class *ret_class, Dwarf_Error *error) { Dwarf_Attribute at; Dwarf_Debug dbg; Dwarf_CU cu; dbg = die != NULL ? die->die_dbg : NULL; if (die == NULL || ret_highpc == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } if ((at = _dwarf_attr_find(die, DW_AT_high_pc)) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } *ret_highpc = at->u[0].u64; if (ret_form != NULL) { *ret_form = at->at_form; } if (ret_class != NULL) { cu = die->die_cu; *ret_class = dwarf_get_form_class(cu->cu_version, DW_AT_high_pc, cu->cu_length_size == 4 ? 4 : 8, at->at_form); } return (DW_DLV_OK); }
int dwarf_attrval_flag(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *valp, Dwarf_Error *err) { Dwarf_Attribute at; Dwarf_Debug dbg; dbg = die != NULL ? die->die_dbg : NULL; if (die == NULL || valp == NULL) { DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } *valp = 0; if ((at = _dwarf_attr_find(die, attr)) == NULL) { DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } switch (at->at_form) { case DW_FORM_flag: *valp = (Dwarf_Bool) (!!at->u[0].u64); break; default: DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD); return (DW_DLV_ERROR); } return (DW_DLV_OK); }
int dwarf_hasattr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *ret_bool, Dwarf_Error *error) { Dwarf_Debug dbg; dbg = die != NULL ? die->die_dbg : NULL; if (die == NULL || ret_bool == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } *ret_bool = (_dwarf_attr_find(die, attr) != NULL); return (DW_DLV_OK); }
int dwarf_attrval_signed(Dwarf_Die die, Dwarf_Half attr, Dwarf_Signed *valp, Dwarf_Error *err) { Dwarf_Attribute at; Dwarf_Debug dbg; dbg = die != NULL ? die->die_dbg : NULL; if (die == NULL || valp == NULL) { DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } *valp = 0; if ((at = _dwarf_attr_find(die, attr)) == NULL) { DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } switch (at->at_form) { case DW_FORM_data1: *valp = (int8_t) at->u[0].s64; break; case DW_FORM_data2: *valp = (int16_t) at->u[0].s64; break; case DW_FORM_data4: *valp = (int32_t) at->u[0].s64; break; case DW_FORM_data8: case DW_FORM_sdata: *valp = at->u[0].s64; break; default: DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD); return (DW_DLV_ERROR); } return (DW_DLV_OK); }
int dwarf_arrayorder(Dwarf_Die die, Dwarf_Unsigned *ret_order, Dwarf_Error *error) { Dwarf_Attribute at; Dwarf_Debug dbg; dbg = die != NULL ? die->die_dbg : NULL; if (die == NULL || ret_order == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } if ((at = _dwarf_attr_find(die, DW_AT_ordering)) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } *ret_order = at->u[0].u64; return (DW_DLV_OK); }
int dwarf_lowpc(Dwarf_Die die, Dwarf_Addr *ret_lowpc, Dwarf_Error *error) { Dwarf_Attribute at; Dwarf_Debug dbg; dbg = die != NULL ? die->die_dbg : NULL; if (die == NULL || ret_lowpc == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } if ((at = _dwarf_attr_find(die, DW_AT_low_pc)) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } *ret_lowpc = at->u[0].u64; return (DW_DLV_OK); }
int dwarf_attr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Attribute *atp, Dwarf_Error *error) { Dwarf_Debug dbg; Dwarf_Attribute at; dbg = die != NULL ? die->die_dbg : NULL; if (die == NULL || atp == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } if ((at = _dwarf_attr_find(die, attr)) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } *atp = at; return (DW_DLV_OK); }
int dwarf_attrval_unsigned(Dwarf_Die die, Dwarf_Half attr, Dwarf_Unsigned *valp, Dwarf_Error *err) { Dwarf_Attribute at; Dwarf_Die die1; Dwarf_Unsigned val; Dwarf_Debug dbg; dbg = die != NULL ? die->die_dbg : NULL; if (die == NULL || valp == NULL) { DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } *valp = 0; if ((at = _dwarf_attr_find(die, attr)) == NULL && attr != DW_AT_type) { DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } die1 = NULL; if (at == NULL && (at = _dwarf_attr_find(die, DW_AT_abstract_origin)) != NULL) { switch (at->at_form) { case DW_FORM_ref1: case DW_FORM_ref2: case DW_FORM_ref4: case DW_FORM_ref8: case DW_FORM_ref_udata: val = at->u[0].u64; if ((die1 = _dwarf_die_find(die, val)) == NULL || (at = _dwarf_attr_find(die1, attr)) == NULL) { if (die1 != NULL) dwarf_dealloc(dbg, die1, DW_DLA_DIE); DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } break; default: DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD); return (DW_DLV_ERROR); } } switch (at->at_form) { case DW_FORM_addr: case DW_FORM_data1: case DW_FORM_data2: case DW_FORM_data4: case DW_FORM_data8: case DW_FORM_udata: case DW_FORM_ref1: case DW_FORM_ref2: case DW_FORM_ref4: case DW_FORM_ref8: case DW_FORM_ref_udata: *valp = at->u[0].u64; break; default: if (die1 != NULL) dwarf_dealloc(dbg, die1, DW_DLA_DIE); DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD); return (DW_DLV_ERROR); } if (die1 != NULL) dwarf_dealloc(dbg, die1, DW_DLA_DIE); return (DW_DLV_OK); }
int dwarf_srcfiles(Dwarf_Die die, char ***srcfiles, Dwarf_Signed *srccount, Dwarf_Error *error) { Dwarf_LineInfo li; Dwarf_LineFile lf; Dwarf_Debug dbg; Dwarf_CU cu; Dwarf_Attribute at; int i; dbg = die != NULL ? die->die_dbg : NULL; if (die == NULL || srcfiles == NULL || srccount == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } if ((at = _dwarf_attr_find(die, DW_AT_stmt_list)) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } cu = die->die_cu; if (cu->cu_lineinfo == NULL) { if (_dwarf_lineno_init(die, at->u[0].u64, error) != DW_DLE_NONE) return (DW_DLV_ERROR); } if (cu->cu_lineinfo == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } li = cu->cu_lineinfo; *srccount = (Dwarf_Signed) li->li_lflen; if (*srccount == 0) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } if (li->li_lfnarray != NULL) { *srcfiles = li->li_lfnarray; return (DW_DLV_OK); } if ((li->li_lfnarray = malloc(*srccount * sizeof(char *))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLV_ERROR); } for (i = 0, lf = STAILQ_FIRST(&li->li_lflist); i < *srccount && lf != NULL; i++, lf = STAILQ_NEXT(lf, lf_next)) { if (lf->lf_fullpath) li->li_lfnarray[i] = lf->lf_fullpath; else li->li_lfnarray[i] = lf->lf_fname; } *srcfiles = li->li_lfnarray; return (DW_DLV_OK); }
int dwarf_srclines(Dwarf_Die die, Dwarf_Line **linebuf, Dwarf_Signed *linecount, Dwarf_Error *error) { Dwarf_LineInfo li; Dwarf_Debug dbg; Dwarf_Line ln; Dwarf_CU cu; Dwarf_Attribute at; int i; dbg = die != NULL ? die->die_dbg : NULL; if (die == NULL || linebuf == NULL || linecount == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } if ((at = _dwarf_attr_find(die, DW_AT_stmt_list)) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } cu = die->die_cu; if (cu->cu_lineinfo == NULL) { if (_dwarf_lineno_init(die, at->u[0].u64, error) != DW_DLE_NONE) return (DW_DLV_ERROR); } if (cu->cu_lineinfo == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } li = cu->cu_lineinfo; *linecount = (Dwarf_Signed) li->li_lnlen; if (*linecount == 0) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } if (li->li_lnarray != NULL) { *linebuf = li->li_lnarray; return (DW_DLV_OK); } if ((li->li_lnarray = malloc(*linecount * sizeof(Dwarf_Line))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLV_ERROR); } for (i = 0, ln = STAILQ_FIRST(&li->li_lnlist); i < *linecount && ln != NULL; i++, ln = STAILQ_NEXT(ln, ln_next)) li->li_lnarray[i] = ln; *linebuf = li->li_lnarray; return (DW_DLV_OK); }
int list_func_die(struct Ripdebuginfo *info, Dwarf_Die *die, uint64_t addr) { _Dwarf_Line ln; Dwarf_Attribute *low; Dwarf_Attribute *high; Dwarf_CU *cu = die->cu_header; Dwarf_Die *cudie = die->cu_die; Dwarf_Die ret, sib=*die; Dwarf_Attribute *attr; uint64_t offset; uint64_t ret_val=8; if(die->die_tag != DW_TAG_subprogram) return 0; memset(&ln, 0, sizeof(_Dwarf_Line)); low = _dwarf_attr_find(die, DW_AT_low_pc); high = _dwarf_attr_find(die, DW_AT_high_pc); if((low && (low->u[0].u64 < addr)) && (high && (high->u[0].u64 > addr))) { info->rip_file = die->cu_die->die_name; info->rip_fn_name = die->die_name; info->rip_fn_namelen = strlen(die->die_name); info->rip_fn_addr = (uintptr_t)low->u[0].u64; assert(die->cu_die); dwarf_srclines(die->cu_die, &ln, addr, NULL); info->rip_line = ln.ln_lineno; info->rip_fn_narg = 0; Dwarf_Attribute* attr; if(dwarf_child(dbg, cu, &sib, &ret) != DW_DLE_NO_ENTRY) { if(ret.die_tag != DW_TAG_formal_parameter) goto last; attr = _dwarf_attr_find(&ret, DW_AT_type); try_again: if(attr != NULL) { offset = (uint64_t)cu->cu_offset + attr->u[0].u64; dwarf_offdie(dbg, offset, &sib, *cu); attr = _dwarf_attr_find(&sib, DW_AT_byte_size); if(attr != NULL) { ret_val = attr->u[0].u64; } else { attr = _dwarf_attr_find(&sib, DW_AT_type); goto try_again; } } info->size_fn_arg[info->rip_fn_narg] = ret_val; info->rip_fn_narg++; sib = ret; while(dwarf_siblingof(dbg, &sib, &ret, cu) == DW_DLV_OK) { if(ret.die_tag != DW_TAG_formal_parameter) break; attr = _dwarf_attr_find(&ret, DW_AT_type); if(attr != NULL) { offset = (uint64_t)cu->cu_offset + attr->u[0].u64; dwarf_offdie(dbg, offset, &sib, *cu); attr = _dwarf_attr_find(&sib, DW_AT_byte_size); if(attr != NULL) { ret_val = attr->u[0].u64; } } info->size_fn_arg[info->rip_fn_narg]=ret_val;// _get_arg_size(ret); info->rip_fn_narg++; sib = ret; } } last: return 1; } return 0; }