int dwarf_linesrc(Dwarf_Line ln, char **ret_linesrc, Dwarf_Error *error) { Dwarf_LineInfo li; Dwarf_LineFile lf; int i; if (ln == NULL || ret_linesrc == NULL) { DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } li = ln->ln_li; assert(li != NULL); for (i = 1, lf = STAILQ_FIRST(&li->li_lflist); (Dwarf_Unsigned) i < ln->ln_fileno && lf != NULL; i++, lf = STAILQ_NEXT(lf, lf_next)) ; if (lf == NULL) { DWARF_SET_ERROR(NULL, error, DW_DLE_LINE_FILE_NUM_BAD); return (DW_DLV_ERROR); } if (lf->lf_fullpath) { *ret_linesrc = (char *) lf->lf_fullpath; return (DW_DLV_OK); } *ret_linesrc = lf->lf_fname; return (DW_DLV_OK); }
int dwarf_get_str(Dwarf_Debug dbg, Dwarf_Off offset, char **string, Dwarf_Signed *ret_strlen, Dwarf_Error *error) { Dwarf_Section *ds; if (dbg == NULL || offset < 0 || string == NULL || ret_strlen == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } ds = _dwarf_find_section(dbg, ".debug_str"); if (ds == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } if ((Dwarf_Unsigned) offset > ds->ds_size) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } if ((Dwarf_Unsigned) offset == ds->ds_size) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } *string = (char *) ds->ds_data + offset; *ret_strlen = strlen(*string); return (DW_DLV_OK); }
int dwarf_attr_add(Dwarf_Abbrev a, uint64_t attr, uint64_t form, Dwarf_Attribute *atp, Dwarf_Error *error) { Dwarf_Attribute at; int ret = DWARF_E_NONE; if (error == NULL) return DWARF_E_ERROR; if (a == NULL) { DWARF_SET_ERROR(error, DWARF_E_ARGUMENT); return DWARF_E_ARGUMENT; } if ((at = malloc(sizeof(struct _Dwarf_Attribute))) == NULL) { DWARF_SET_ERROR(error, DWARF_E_MEMORY); return DWARF_E_MEMORY; } /* Initialise the attribute structure. */ at->at_attrib = attr; at->at_form = form; /* Add the attribute to the list in the abbrev. */ STAILQ_INSERT_TAIL(&a->a_attrib, at, at_next); if (atp != NULL) *atp = at; return ret; }
int dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev, Dwarf_Signed ndx, Dwarf_Half *attr_num, Dwarf_Signed *form, Dwarf_Off *offset, Dwarf_Error *error) { Dwarf_AttrDef ad; int i; if (abbrev == NULL || attr_num == NULL || form == NULL || offset == NULL) { DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } if (ndx < 0 || (uint64_t) ndx >= abbrev->ab_atnum) { DWARF_SET_ERROR(NULL, error, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } ad = STAILQ_FIRST(&abbrev->ab_attrdef); for (i = 0; i < ndx && ad != NULL; i++) ad = STAILQ_NEXT(ad, ad_next); assert(ad != NULL); *attr_num = ad->ad_attrib; *form = ad->ad_form; *offset = ad->ad_offset; return (DW_DLV_OK); }
int dwarf_get_pubtypes(Dwarf_Debug dbg, Dwarf_Type **pubtypes, Dwarf_Signed *ret_count, Dwarf_Error *error) { Dwarf_Section *ds; int ret; if (dbg == NULL || pubtypes == NULL || ret_count == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } if (dbg->dbg_pubtypes == NULL) { if ((ds = _dwarf_find_section(dbg, ".debug_pubtypes")) != NULL) { ret = _dwarf_nametbl_init(dbg, &dbg->dbg_pubtypes, ds, error); if (ret != DW_DLE_NONE) return (DW_DLV_ERROR); } if (dbg->dbg_pubtypes == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } } *pubtypes = dbg->dbg_pubtypes->ns_array; *ret_count = dbg->dbg_pubtypes->ns_len; return (DW_DLV_OK); }
int dwarf_attr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Attribute *atp, Dwarf_Error *err) { Dwarf_Attribute at; Dwarf_Abbrev a; int ret = DWARF_E_NONE; if (err == NULL) return DWARF_E_ERROR; if (die == NULL || atp == NULL || (a = die->die_a) == NULL) { DWARF_SET_ERROR(err, DWARF_E_ARGUMENT); return DWARF_E_ARGUMENT; } STAILQ_FOREACH(at, &a->a_attrib, at_next) if (at->at_attrib == attr) break; *atp = at; if (at == NULL) { DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY); ret = DWARF_E_NO_ENTRY; } return ret; }
int _dwarf_loc_fill_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *llbuf, uint8_t *in, uint64_t in_len, uint8_t pointer_size, uint8_t offset_size, uint8_t version, Dwarf_Error *error) { int num; assert(llbuf != NULL); assert(in != NULL); assert(in_len > 0); /* Compute the number of locations. */ if ((num = _dwarf_loc_fill_loc(dbg, NULL, pointer_size, offset_size, version, in, in_len)) < 0) { DWARF_SET_ERROR(dbg, error, DW_DLE_LOC_EXPR_BAD); return (DW_DLE_LOC_EXPR_BAD); } llbuf->ld_cents = num; if (num <= 0) return (DW_DLE_NONE); if ((llbuf->ld_s = calloc(num, sizeof(Dwarf_Loc))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } (void) _dwarf_loc_fill_loc(dbg, llbuf, pointer_size, offset_size, version, in, in_len); return (DW_DLE_NONE); }
int dwarf_get_abbrev(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Abbrev *return_abbrev, Dwarf_Unsigned *length, Dwarf_Unsigned *attr_count, Dwarf_Error *error) { Dwarf_Abbrev ab; int ret; if (dbg == NULL || return_abbrev == NULL || length == NULL || attr_count == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } ret = _dwarf_abbrev_parse(dbg, NULL, &offset, &ab, error); if (ret != DW_DLE_NONE) { if (ret == DW_DLE_NO_ENTRY) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } else return (DW_DLV_ERROR); } *return_abbrev = ab; *length = ab->ab_length; *attr_count = ab->ab_atnum; return (DW_DLV_OK); }
Dwarf_P_Die dwarf_die_link(Dwarf_P_Die die, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling, Dwarf_Error *error) { Dwarf_Debug dbg; int count; if (die == NULL) { DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); return (DW_DLV_BADADDR); } dbg = die->die_dbg; count = _dwarf_die_count_links(parent, child, left_sibling, right_sibling); if (count > 1) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_BADADDR); } else if (count == 0) return (die); _dwarf_die_link(die, parent, child, left_sibling, right_sibling); return (die); }
int dwarf_loclist_from_expr_b(Dwarf_Debug dbg, Dwarf_Ptr bytes_in, Dwarf_Unsigned bytes_len, Dwarf_Half addr_size, Dwarf_Half offset_size, Dwarf_Small version, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen, Dwarf_Error *error) { Dwarf_Locdesc *ld; int ret; if (dbg == NULL || bytes_in == NULL || bytes_len == 0 || llbuf == NULL || listlen == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } if (addr_size != 4 && addr_size != 8) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } if (offset_size != 4 && offset_size != 8) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } ret = _dwarf_loc_fill_locexpr(dbg, &ld, bytes_in, bytes_len, addr_size, offset_size, version, error); if (ret != DW_DLE_NONE) return (DW_DLV_ERROR); *llbuf = ld; *listlen = 1; return (DW_DLV_OK); }
Dwarf_Unsigned dwarf_add_arange_b(Dwarf_P_Debug dbg, Dwarf_Addr start, Dwarf_Unsigned length, Dwarf_Unsigned symbol_index, Dwarf_Unsigned end_symbol_index, Dwarf_Addr offset_from_end_symbol, Dwarf_Error *error) { Dwarf_ArangeSet as; Dwarf_Arange ar; if (dbg == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (0); } as = dbg->dbgp_as; if (end_symbol_index > 0 && (dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (0); } if ((ar = calloc(1, sizeof(struct _Dwarf_Arange))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (0); } ar->ar_as = as; ar->ar_address = start; ar->ar_range = length; ar->ar_symndx = symbol_index; ar->ar_esymndx = end_symbol_index; ar->ar_eoff = offset_from_end_symbol; STAILQ_INSERT_TAIL(&as->as_arlist, ar, ar_next); return (1); }
int dwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length, Dwarf_Half *cu_version, Dwarf_Off *cu_abbrev_offset, Dwarf_Half *cu_pointer_size, Dwarf_Half *cu_offset_size, Dwarf_Half *cu_extension_size, Dwarf_Unsigned *cu_next_offset, Dwarf_Error *error) { Dwarf_CU cu; int ret; if (dbg == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } if (dbg->dbg_cu_current == NULL) ret = _dwarf_info_first_cu(dbg, error); else ret = _dwarf_info_next_cu(dbg, error); if (ret == DW_DLE_NO_ENTRY) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } else if (ret != DW_DLE_NONE) return (DW_DLV_ERROR); if (dbg->dbg_cu_current == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); return (DW_DLV_NO_ENTRY); } cu = dbg->dbg_cu_current; if (cu_length) *cu_length = cu->cu_length; if (cu_version) *cu_version = cu->cu_version; if (cu_abbrev_offset) *cu_abbrev_offset = (Dwarf_Off) cu->cu_abbrev_offset; if (cu_pointer_size) *cu_pointer_size = cu->cu_pointer_size; if (cu_offset_size) { if (cu->cu_length_size == 4) *cu_offset_size = 4; else *cu_offset_size = 8; } if (cu_extension_size) { if (cu->cu_length_size == 4) *cu_extension_size = 0; else *cu_extension_size = 4; } if (cu_next_offset) *cu_next_offset = dbg->dbg_cu_current->cu_next_offset; return (DW_DLV_OK); }
int dwarf_get_loclist_entry(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Addr *hipc, Dwarf_Addr *lopc, Dwarf_Ptr *data, Dwarf_Unsigned *entry_len, Dwarf_Unsigned *next_entry, Dwarf_Error *error) { Dwarf_Loclist ll, next_ll; Dwarf_Locdesc *ld; Dwarf_Section *ds; int i, ret; if (dbg == NULL || hipc == NULL || lopc == NULL || data == NULL || entry_len == NULL || next_entry == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } ret = _dwarf_loclist_find(dbg, STAILQ_FIRST(&dbg->dbg_cu), offset, &ll, error); if (ret == DW_DLE_NO_ENTRY) { DWARF_SET_ERROR(dbg, error, DW_DLV_NO_ENTRY); return (DW_DLV_NO_ENTRY); } else if (ret != DW_DLE_NONE) return (DW_DLV_ERROR); *hipc = *lopc = 0; for (i = 0; i < ll->ll_ldlen; i++) { ld = ll->ll_ldlist[i]; if (i == 0) { *hipc = ld->ld_hipc; *lopc = ld->ld_lopc; } else { if (ld->ld_lopc < *lopc) *lopc = ld->ld_lopc; if (ld->ld_hipc > *hipc) *hipc = ld->ld_hipc; } } ds = _dwarf_find_section(dbg, ".debug_loc"); assert(ds != NULL); *data = (uint8_t *) ds->ds_data + ll->ll_offset; *entry_len = ll->ll_length; next_ll = TAILQ_NEXT(ll, ll_next); if (next_ll != NULL) *next_entry = next_ll->ll_offset; else *next_entry = ds->ds_size; return (DW_DLV_OK); }
int dwarf_get_loclist_entry(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Addr *hipc, Dwarf_Addr *lopc, Dwarf_Ptr *data, Dwarf_Unsigned *entry_len, Dwarf_Unsigned *next_entry, Dwarf_Error *error) { Dwarf_Locdesc *ld, **llbuf; Dwarf_Section *ds; Dwarf_Signed listlen; int i, ret; /* * Note that this API sometimes will not work correctly because * it assumes that all units have the same pointer size and offset * size. */ if (dbg == NULL || hipc == NULL || lopc == NULL || data == NULL || entry_len == NULL || next_entry == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } ret = _dwarf_loclist_find(dbg, STAILQ_FIRST(&dbg->dbg_cu), offset, &llbuf, &listlen, entry_len, error); if (ret == DW_DLE_NO_ENTRY) { DWARF_SET_ERROR(dbg, error, DW_DLV_NO_ENTRY); return (DW_DLV_NO_ENTRY); } else if (ret != DW_DLE_NONE) return (DW_DLV_ERROR); *hipc = *lopc = 0; for (i = 0; i < listlen; i++) { ld = llbuf[i]; if (i == 0) { *hipc = ld->ld_hipc; *lopc = ld->ld_lopc; } else { if (ld->ld_lopc < *lopc) *lopc = ld->ld_lopc; if (ld->ld_hipc > *hipc) *hipc = ld->ld_hipc; } } ds = _dwarf_find_section(dbg, ".debug_loc"); assert(ds != NULL); *data = (uint8_t *) ds->ds_data + offset; *next_entry = offset + *entry_len; return (DW_DLV_OK); }
int dwarf_get_fde_info_for_reg(Dwarf_Fde fde, Dwarf_Half table_column, Dwarf_Addr pc_requested, Dwarf_Signed *offset_relevant, Dwarf_Signed *register_num, Dwarf_Signed *offset, Dwarf_Addr *row_pc, Dwarf_Error *error) { Dwarf_Regtable3 *rt; Dwarf_Debug dbg; Dwarf_Addr pc; int ret; dbg = fde != NULL ? fde->fde_dbg : NULL; if (fde == NULL || offset_relevant == NULL || register_num == NULL || offset == NULL || row_pc == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } if (pc_requested < fde->fde_initloc || pc_requested >= fde->fde_initloc + fde->fde_adrange) { DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); return (DW_DLV_ERROR); } ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc, error); if (ret != DW_DLE_NONE) return (DW_DLV_ERROR); if (table_column == dbg->dbg_frame_cfa_value) { /* Application ask for CFA. */ *offset_relevant = CFA.dw_offset_relevant; *register_num = CFA.dw_regnum; *offset = CFA.dw_offset_or_block_len; } else { /* Application ask for normal registers. */ if (table_column >= dbg->dbg_frame_rule_table_size || table_column >= DW_REG_TABLE_SIZE) { DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD); return (DW_DLV_ERROR); } *offset_relevant = RL.dw_offset_relevant; *register_num = RL.dw_regnum; *offset = RL.dw_offset_or_block_len; } *row_pc = pc; return (DW_DLV_OK); }
int dwarf_init(int fd, int mode, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug *ret_dbg, Dwarf_Error *error) { Dwarf_Debug dbg; Elf *elf; int ret; if (fd < 0 || ret_dbg == NULL) { DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } if (mode != DW_DLC_READ) { DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } if (elf_version(EV_CURRENT) == EV_NONE) { DWARF_SET_ELF_ERROR(NULL, error); return (DW_DLV_ERROR); } if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { DWARF_SET_ELF_ERROR(NULL, error); return (DW_DLV_ERROR); } if (_dwarf_alloc(&dbg, mode, error) != DW_DLE_NONE) return (DW_DLV_ERROR); if (_dwarf_elf_init(dbg, elf, error) != DW_DLE_NONE) { free(dbg); return (DW_DLV_ERROR); } if ((ret = _dwarf_init(dbg, 0, errhand, errarg, error)) != DW_DLE_NONE) { _dwarf_elf_deinit(dbg); free(dbg); if (ret == DW_DLE_DEBUG_INFO_NULL) return (DW_DLV_NO_ENTRY); else return (DW_DLV_ERROR); } *ret_dbg = dbg; return (DW_DLV_OK); }
Dwarf_Unsigned dwarf_add_frame_fde_b(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len, Dwarf_Unsigned symbol_index, Dwarf_Unsigned end_symbol_index, Dwarf_Addr offset_from_end_sym, Dwarf_Error *error) { Dwarf_P_Cie ciep; int i; /* * XXX SGI libdwarf need the DIE arg because later it will insert a * DW_AT_MIPS_fde attribute, which points to the offset the * correspoding FDE, into this DIE. Do we need this? */ (void) die; if (dbg == NULL || fde == NULL || fde->fde_dbg != dbg) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_NOCOUNT); } ciep = STAILQ_FIRST(&dbg->dbgp_cielist); for (i = 0; (Dwarf_Unsigned) i < cie; i++) { ciep = STAILQ_NEXT(ciep, cie_next); if (ciep == NULL) break; } if (ciep == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_NOCOUNT); } if (end_symbol_index > 0 && (dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_NOCOUNT); } fde->fde_cie = ciep; fde->fde_initloc = virt_addr; fde->fde_adrange = code_len; fde->fde_symndx = symbol_index; fde->fde_esymndx = end_symbol_index; fde->fde_eoff = offset_from_end_sym; STAILQ_INSERT_TAIL(&dbg->dbgp_fdelist, fde, fde_next); return (dbg->dbgp_fdelen++); }
int _dwarf_loc_fill_locexpr(Dwarf_Debug dbg, Dwarf_Locdesc **ret_llbuf, uint8_t *in, uint64_t in_len, uint8_t pointer_size, Dwarf_Error *error) { Dwarf_Locdesc *llbuf; int ret; if ((llbuf = malloc(sizeof(Dwarf_Locdesc))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } llbuf->ld_lopc = 0; llbuf->ld_hipc = ~0ULL; llbuf->ld_s = NULL; ret = _dwarf_loc_fill_locdesc(dbg, llbuf, in, in_len, pointer_size, error); if (ret != DW_DLE_NONE) { free(llbuf); return (ret); } *ret_llbuf = llbuf; return (ret); }
int dwarf_var_name_offsets(Dwarf_Var var, char **ret_name, Dwarf_Off *die_offset, Dwarf_Off *cu_offset, Dwarf_Error *error) { Dwarf_CU cu; Dwarf_Debug dbg; Dwarf_NameTbl nt; dbg = var != NULL ? var->np_nt->nt_cu->cu_dbg : NULL; if (var == NULL || ret_name == NULL || die_offset == NULL || cu_offset == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } nt = var->np_nt; assert(nt != NULL); cu = nt->nt_cu; assert(cu != NULL); *ret_name = var->np_name; *die_offset = nt->nt_cu_offset + var->np_offset; *cu_offset = cu->cu_1st_offset; return (DW_DLV_OK); }
int dwarf_object_init(Dwarf_Obj_Access_Interface *iface, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug *ret_dbg, Dwarf_Error *error) { Dwarf_Debug dbg; if (iface == NULL || ret_dbg == NULL) { DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } if (_dwarf_alloc(&dbg, DW_DLC_READ, error) != DW_DLE_NONE) return (DW_DLV_ERROR); dbg->dbg_iface = iface; if (_dwarf_init(dbg, 0, errhand, errarg, error) != DW_DLE_NONE) { free(dbg); return (DW_DLV_ERROR); } *ret_dbg = dbg; return (DW_DLV_OK); }
int dwarf_get_cie_info(Dwarf_Cie cie, Dwarf_Unsigned *bytes_in_cie, Dwarf_Small *version, char **augmenter, Dwarf_Unsigned *caf, Dwarf_Unsigned *daf, Dwarf_Half *ra, Dwarf_Ptr *initinst, Dwarf_Unsigned *inst_len, Dwarf_Error *error) { if (cie == NULL || bytes_in_cie == NULL || version == NULL || augmenter == NULL || caf == NULL || daf == NULL || ra == NULL || initinst == NULL || inst_len == NULL) { DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } *bytes_in_cie = cie->cie_length; *version = cie->cie_version; *augmenter = (char *) cie->cie_augment; *caf = cie->cie_caf; *daf = cie->cie_daf; *ra = cie->cie_ra; *initinst = cie->cie_initinst; *inst_len = cie->cie_instlen; return (DW_DLV_OK); }
int dwarf_get_fde_range(Dwarf_Fde fde, Dwarf_Addr *low_pc, Dwarf_Unsigned *func_len, Dwarf_Ptr *fde_bytes, Dwarf_Unsigned *fde_byte_len, Dwarf_Off *cie_offset, Dwarf_Signed *cie_index, Dwarf_Off *fde_offset, Dwarf_Error *error) { Dwarf_Debug dbg; dbg = fde != NULL ? fde->fde_dbg : NULL; if (fde == NULL || low_pc == NULL || func_len == NULL || fde_bytes == NULL || fde_byte_len == NULL || cie_offset == NULL || cie_index == NULL || fde_offset == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } *low_pc = fde->fde_initloc; *func_len = fde->fde_adrange; *fde_bytes = fde->fde_addr; *fde_byte_len = fde->fde_length; *cie_offset = fde->fde_cieoff; *cie_index = fde->fde_cie->cie_index; *fde_offset = fde->fde_offset; return (DW_DLV_OK); }
int _dwarf_strtab_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) { Dwarf_P_Section ds; int ret; assert(dbg != NULL); if ((ret = _dwarf_section_init(dbg, &ds, ".debug_str", 0, error)) != DW_DLE_NONE) return (ret); if (dbg->dbg_strtab_size > ds->ds_cap) { ds->ds_data = realloc(ds->ds_data, (size_t) dbg->dbg_strtab_size); if (ds->ds_data == NULL) { _dwarf_section_free(dbg, &ds); DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } ds->ds_cap = dbg->dbg_strtab_size; } memcpy(ds->ds_data, dbg->dbg_strtab, dbg->dbg_strtab_size); ds->ds_size = dbg->dbg_strtab_size; /* * Inform application the creation of .debug_str ELF section. * Note that .debug_str use a different format than usual ELF * string table, so it should not have SHT_STRTAB as its type. */ ret = _dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error); return (ret); }
int _dwarf_strtab_add(Dwarf_Debug dbg, char *string, uint64_t *off, Dwarf_Error *error) { size_t len; assert(dbg != NULL && string != NULL); len = strlen(string) + 1; while (dbg->dbg_strtab_size + len > dbg->dbg_strtab_cap) { dbg->dbg_strtab_cap *= 2; dbg->dbg_strtab = realloc(dbg->dbg_strtab, (size_t) dbg->dbg_strtab_cap); if (dbg->dbg_strtab == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } } if (off != NULL) *off = dbg->dbg_strtab_size; strncpy(&dbg->dbg_strtab[dbg->dbg_strtab_size], string, len - 1); dbg->dbg_strtab_size += len; dbg->dbg_strtab[dbg->dbg_strtab_size - 1] = '\0'; return (DW_DLE_NONE); }
int dwarf_pubtype_name_offsets(Dwarf_Type pubtype, char **ret_name, Dwarf_Off *die_offset, Dwarf_Off *cu_offset, Dwarf_Error *error) { Dwarf_CU cu; Dwarf_Debug dbg; Dwarf_NameTbl nt; dbg = pubtype != NULL ? pubtype->np_nt->nt_cu->cu_dbg : NULL; if (pubtype == NULL || ret_name == NULL || die_offset == NULL || cu_offset == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } nt = pubtype->np_nt; assert(nt != NULL); cu = nt->nt_cu; assert(cu != NULL); *ret_name = pubtype->np_name; *die_offset = nt->nt_cu_offset + pubtype->np_offset; *cu_offset = cu->cu_1st_offset; return (DW_DLV_OK); }
int dwarf_get_fde_info_for_reg3(Dwarf_Fde fde, Dwarf_Half table_column, Dwarf_Addr pc_requested, Dwarf_Small *value_type, Dwarf_Signed *offset_relevant, Dwarf_Signed *register_num, Dwarf_Signed *offset_or_block_len, Dwarf_Ptr *block_ptr, Dwarf_Addr *row_pc, Dwarf_Error *error) { Dwarf_Regtable3 *rt; Dwarf_Debug dbg; Dwarf_Addr pc; int ret; dbg = fde != NULL ? fde->fde_dbg : NULL; if (fde == NULL || value_type == NULL || offset_relevant == NULL || register_num == NULL || offset_or_block_len == NULL || block_ptr == NULL || row_pc == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_ERROR); } if (pc_requested < fde->fde_initloc || pc_requested >= fde->fde_initloc + fde->fde_adrange) { DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); return (DW_DLV_ERROR); } ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc, error); if (ret != DW_DLE_NONE) return (DW_DLV_ERROR); if (table_column >= dbg->dbg_frame_rule_table_size) { DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD); return (DW_DLV_ERROR); } *value_type = RL.dw_value_type; *offset_relevant = RL.dw_offset_relevant; *register_num = RL.dw_regnum; *offset_or_block_len = RL.dw_offset_or_block_len; *block_ptr = RL.dw_block_ptr; *row_pc = pc; return (DW_DLV_OK); }
int dwarf_die_add(Dwarf_CU cu, int level, uint64_t offset, uint64_t abnum, Dwarf_Abbrev a, Dwarf_Die *diep, Dwarf_Error *err) { Dwarf_Die die; uint64_t key; int ret = DWARF_E_NONE; if (err == NULL) return DWARF_E_ERROR; if (cu == NULL || a == NULL) { DWARF_SET_ERROR(err, DWARF_E_ARGUMENT); return DWARF_E_ARGUMENT; } if ((die = malloc(sizeof(struct _Dwarf_Die))) == NULL) { DWARF_SET_ERROR(err, DWARF_E_MEMORY); return DWARF_E_MEMORY; } /* Initialise the abbrev structure. */ die->die_level = level; die->die_offset = offset; die->die_abnum = abnum; die->die_a = a; die->die_cu = cu; die->die_name = anon_name; /* Initialise the list of attribute values. */ STAILQ_INIT(&die->die_attrval); /* Add the die to the list in the compilation unit. */ STAILQ_INSERT_TAIL(&cu->cu_die, die, die_next); /* Add the die to the hash table in the compilation unit. */ key = offset % DWARF_DIE_HASH_SIZE; STAILQ_INSERT_TAIL(&cu->cu_die_hash[key], die, die_hash); if (diep != NULL) *diep = die; return ret; }
Dwarf_Unsigned dwarf_add_frame_cie(Dwarf_P_Debug dbg, char *augmenter, Dwarf_Small caf, Dwarf_Small daf, Dwarf_Small ra, Dwarf_Ptr initinst, Dwarf_Unsigned inst_len, Dwarf_Error *error) { Dwarf_P_Cie cie; if (dbg == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_NOCOUNT); } if ((cie = calloc(1, sizeof(struct _Dwarf_Cie))) == NULL) { DWARF_SET_ERROR(dbg, error,DW_DLE_MEMORY); return (DW_DLV_NOCOUNT); } STAILQ_INSERT_TAIL(&dbg->dbgp_cielist, cie, cie_next); cie->cie_index = dbg->dbgp_cielen++; if (augmenter != NULL) { cie->cie_augment = (uint8_t *) strdup(augmenter); if (cie->cie_augment == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLV_NOCOUNT); } } cie->cie_caf = caf; cie->cie_daf = (int8_t) daf; /* daf is signed. */ cie->cie_ra = ra; if (initinst != NULL && inst_len > 0) { cie->cie_initinst = malloc((size_t) inst_len); if (cie->cie_initinst == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLV_NOCOUNT); } memcpy(cie->cie_initinst, initinst, inst_len); cie->cie_instlen = inst_len; } return (cie->cie_index); }
Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error *error) { Dwarf_P_Fde fde; if (dbg == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_BADADDR); } if ((fde = calloc(1, sizeof(struct _Dwarf_Fde))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLV_BADADDR); } fde->fde_dbg = dbg; return (fde); }
int _dwarf_strtab_init(Dwarf_Debug dbg, Dwarf_Error *error) { Dwarf_Section *ds; assert(dbg != NULL); if (dbg->dbg_mode == DW_DLC_READ || dbg->dbg_mode == DW_DLC_RDWR) { ds = _dwarf_find_section(dbg, ".debug_str"); if (ds == NULL) { dbg->dbg_strtab = NULL; dbg->dbg_strtab_cap = dbg->dbg_strtab_size = 0; return (DW_DLE_NONE); } dbg->dbg_strtab_cap = dbg->dbg_strtab_size = ds->ds_size; if (dbg->dbg_mode == DW_DLC_RDWR) { if ((dbg->dbg_strtab = malloc((size_t) ds->ds_size)) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } memcpy(dbg->dbg_strtab, ds->ds_data, ds->ds_size); } else dbg->dbg_strtab = (char *) ds->ds_data; } else { /* DW_DLC_WRITE */ dbg->dbg_strtab_cap = _INIT_DWARF_STRTAB_SIZE; dbg->dbg_strtab_size = 0; if ((dbg->dbg_strtab = malloc((size_t) dbg->dbg_strtab_cap)) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } dbg->dbg_strtab[0] = '\0'; } return (DW_DLE_NONE); }