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); }
static Dwarf_Off die_attr_ref(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name) { Dwarf_Off off; if (dwarf_attrval_unsigned(die, name, &off, &dw->dw_err) != DWARF_E_NONE) { terminate("die %llu: failed to get ref: %s\n", die_off(dw, die), dwarf_errmsg(&dw->dw_err)); } return (off); }
static Dwarf_Attribute die_attr(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, int req) { Dwarf_Attribute attr; int rc; if ((rc = dwarf_attr(die, name, &attr, &dw->dw_err)) == DW_DLV_OK) { return (attr); } else if (rc == DW_DLV_NO_ENTRY) { if (req) { terminate("die %llu: no attr 0x%x\n", die_off(dw, die), name); } else { return (NULL); } } terminate("die %llu: failed to get attribute for type: %s\n", die_off(dw, die), dwarf_errmsg(dw->dw_err)); /*NOTREACHED*/ return (NULL); }
static Dwarf_Half die_tag(dwarf_t *dw, Dwarf_Die die) { Dwarf_Half tag; if (dwarf_tag(die, &tag, &dw->dw_err) == DW_DLV_OK) return (tag); terminate("die %llu: failed to get tag for type: %s\n", die_off(dw, die), dwarf_errmsg(dw->dw_err)); /*NOTREACHED*/ return (0); }
static int die_bool(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Bool *valp, int req) { *valp = 0; if (dwarf_attrval_flag(die, name, valp, &dw->dw_err) != DWARF_E_NONE) { if (req) terminate("die %llu: failed to get flag: %s\n", die_off(dw, die), dwarf_errmsg(&dw->dw_err)); return (0); } return (1); }
static int die_mem_offset(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Unsigned *valp, int req __unused) { Dwarf_Locdesc *loc = NULL; Dwarf_Signed locnum = 0; if (dwarf_locdesc(die, name, &loc, &locnum, &dw->dw_err) != DW_DLV_OK) return (0); 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; if (loc != NULL) if (dwarf_locdesc_free(loc, &dw->dw_err) != DW_DLV_OK) terminate("die %llu: cannot free location descriptor: %s\n", die_off(dw, die), dwarf_errmsg(&dw->dw_err)); return (1); }
static Dwarf_Die die_child(dwarf_t *dw, Dwarf_Die die) { Dwarf_Die child; int rc; if ((rc = dwarf_child(die, &child, &dw->dw_err)) == DW_DLV_OK) return (child); else if (rc == DW_DLV_NO_ENTRY) return (NULL); terminate("die %llu: failed to find type child: %s\n", die_off(dw, die), dwarf_errmsg(dw->dw_err)); /*NOTREACHED*/ return (NULL); }
static Dwarf_Off die_attr_ref(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name) { Dwarf_Attribute attr; Dwarf_Off off; attr = die_attr(dw, die, name, DW_ATTR_REQ); if (dwarf_formref(attr, &off, &dw->dw_err) != DW_DLV_OK) { terminate("die %llu: failed to get ref (form 0x%x)\n", die_off(dw, die), die_attr_form(dw, attr)); } dwarf_dealloc(dw->dw_dw, attr, DW_DLA_ATTR); return (off); }
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 int die_string(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, char **strp, int req) { const char *str = NULL; if (dwarf_attrval_string(die, name, &str, &dw->dw_err) != DWARF_E_NONE || str == NULL) { if (req) terminate("die %llu: failed to get string: %s\n", die_off(dw, die), dwarf_errmsg(&dw->dw_err)); else *strp = NULL; return (0); } else *strp = xstrdup(str); return (1); }
static int die_string(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, char **strp, int req) { Dwarf_Attribute attr; char *str; if ((attr = die_attr(dw, die, name, req)) == NULL) return (0); /* die_attr will terminate for us if necessary */ if (dwarf_formstring(attr, &str, &dw->dw_err) != DW_DLV_OK) { terminate("die %llu: failed to get string (form 0x%x)\n", die_off(dw, die), die_attr_form(dw, attr)); } *strp = xstrdup(str); dwarf_dealloc(dw->dw_dw, str, DW_DLA_STRING); return (1); }
static int die_bool(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name, Dwarf_Bool *valp, int req) { Dwarf_Attribute attr; Dwarf_Bool val; if ((attr = die_attr(dw, die, name, req)) == NULL) return (0); /* die_attr will terminate for us if necessary */ if (dwarf_formflag(attr, &val, &dw->dw_err) != DW_DLV_OK) { terminate("die %llu: failed to get bool (form 0x%x)\n", die_off(dw, die), die_attr_form(dw, attr)); } dwarf_dealloc(dw->dw_dw, attr, DW_DLA_ATTR); *valp = val; return (1); }