📄 dt_parser.c
字号:
dnp->dn_kind = (uchar_t)kind; dnp->dn_flags = 0; dnp->dn_op = 0; dnp->dn_line = yylineno; dnp->dn_reg = -1; dnp->dn_attr = _dtrace_defattr; dnp->dn_list = NULL; dnp->dn_link = yypcb->pcb_list; yypcb->pcb_list = dnp; bzero(&dnp->dn_u, sizeof (dnp->dn_u)); return (dnp);}voiddt_node_free(dt_node_t *dnp){ uchar_t kind = dnp->dn_kind; dnp->dn_kind = DT_NODE_FREE; switch (kind) { case DT_NODE_STRING: case DT_NODE_IDENT: case DT_NODE_TYPE: free(dnp->dn_string); dnp->dn_string = NULL; break; case DT_NODE_VAR: case DT_NODE_FUNC: dt_node_list_free(&dnp->dn_args); break; case DT_NODE_OP1: if (dnp->dn_child != NULL) { dt_node_free(dnp->dn_child); dnp->dn_child = NULL; } break; case DT_NODE_OP3: if (dnp->dn_expr != NULL) { dt_node_free(dnp->dn_expr); dnp->dn_expr = NULL; } /*FALLTHRU*/ case DT_NODE_OP2: if (dnp->dn_left != NULL) { dt_node_free(dnp->dn_left); dnp->dn_left = NULL; } if (dnp->dn_right != NULL) { dt_node_free(dnp->dn_right); dnp->dn_right = NULL; } break; case DT_NODE_DEXPR: case DT_NODE_DFUNC: if (dnp->dn_expr != NULL) { dt_node_free(dnp->dn_expr); dnp->dn_expr = NULL; } break; case DT_NODE_AGG: if (dnp->dn_aggfun != NULL) { dt_node_free(dnp->dn_aggfun); dnp->dn_aggfun = NULL; } dt_node_list_free(&dnp->dn_aggtup); break; case DT_NODE_PDESC: free(dnp->dn_spec); dnp->dn_spec = NULL; free(dnp->dn_desc); dnp->dn_desc = NULL; break; case DT_NODE_CLAUSE: if (dnp->dn_pred != NULL) dt_node_free(dnp->dn_pred); if (dnp->dn_locals != NULL) dt_idhash_destroy(dnp->dn_locals); dt_node_list_free(&dnp->dn_pdescs); dt_node_list_free(&dnp->dn_acts); break; case DT_NODE_MEMBER: free(dnp->dn_membname); dnp->dn_membname = NULL; if (dnp->dn_membexpr != NULL) { dt_node_free(dnp->dn_membexpr); dnp->dn_membexpr = NULL; } break; case DT_NODE_PROBE: if (dnp->dn_ident != NULL) { dt_ident_destroy(dnp->dn_ident); dnp->dn_ident = NULL; } break; case DT_NODE_PROVIDER: dt_node_list_free(&dnp->dn_list); free(dnp->dn_string); dnp->dn_string = NULL; break; case DT_NODE_PROG: dt_node_list_free(&dnp->dn_list); break; }}voiddt_node_attr_assign(dt_node_t *dnp, dtrace_attribute_t attr){ if ((yypcb->pcb_cflags & DTRACE_C_EATTR) && (dt_attr_cmp(attr, yypcb->pcb_amin) < 0)) { char a[DTRACE_ATTR2STR_MAX]; char s[BUFSIZ]; dnerror(dnp, D_ATTR_MIN, "attributes for %s (%s) are less than " "predefined minimum\n", dt_node_name(dnp, s, sizeof (s)), dtrace_attr2str(attr, a, sizeof (a))); } dnp->dn_attr = attr;}voiddt_node_type_assign(dt_node_t *dnp, ctf_file_t *fp, ctf_id_t type){ ctf_id_t base = ctf_type_resolve(fp, type); uint_t kind = ctf_type_kind(fp, base); ctf_encoding_t e; dnp->dn_flags &= ~(DT_NF_SIGNED | DT_NF_REF | DT_NF_BITFIELD | DT_NF_USERLAND); if (kind == CTF_K_INTEGER && ctf_type_encoding(fp, base, &e) == 0) { size_t size = e.cte_bits / NBBY; if (size > 8 || (e.cte_bits % NBBY) != 0 || (size & (size - 1))) dnp->dn_flags |= DT_NF_BITFIELD; if (e.cte_format & CTF_INT_SIGNED) dnp->dn_flags |= DT_NF_SIGNED; } if (kind == CTF_K_FLOAT && ctf_type_encoding(fp, base, &e) == 0) { if (e.cte_bits / NBBY > sizeof (uint64_t)) dnp->dn_flags |= DT_NF_REF; } if (kind == CTF_K_STRUCT || kind == CTF_K_UNION || kind == CTF_K_FORWARD || kind == CTF_K_ARRAY || kind == CTF_K_FUNCTION) dnp->dn_flags |= DT_NF_REF; else if (fp == DT_DYN_CTFP(yypcb->pcb_hdl) && type == DT_DYN_TYPE(yypcb->pcb_hdl)) dnp->dn_flags |= DT_NF_REF; dnp->dn_flags |= DT_NF_COOKED; dnp->dn_ctfp = fp; dnp->dn_type = type;}voiddt_node_type_propagate(const dt_node_t *src, dt_node_t *dst){ assert(src->dn_flags & DT_NF_COOKED); dst->dn_flags = src->dn_flags & ~DT_NF_LVALUE; dst->dn_ctfp = src->dn_ctfp; dst->dn_type = src->dn_type;}const char *dt_node_type_name(const dt_node_t *dnp, char *buf, size_t len){ if (dt_node_is_dynamic(dnp) && dnp->dn_ident != NULL) { (void) snprintf(buf, len, "%s", dt_idkind_name(dnp->dn_ident->di_kind)); return (buf); } if (dnp->dn_flags & DT_NF_USERLAND) { size_t n = snprintf(buf, len, "userland "); len = len > n ? len - n : 0; (void) dt_type_name(dnp->dn_ctfp, dnp->dn_type, buf + n, len); return (buf); } return (dt_type_name(dnp->dn_ctfp, dnp->dn_type, buf, len));}size_tdt_node_type_size(const dt_node_t *dnp){ if (dnp->dn_kind == DT_NODE_STRING) return (strlen(dnp->dn_string) + 1); if (dt_node_is_dynamic(dnp) && dnp->dn_ident != NULL) return (dt_ident_size(dnp->dn_ident)); return (ctf_type_size(dnp->dn_ctfp, dnp->dn_type));}size_tdt_node_sizeof(const dt_node_t *dnp){ dtrace_syminfo_t *sip; GElf_Sym sym; dtrace_hdl_t *dtp = yypcb->pcb_hdl; /* * The size of the node as used for the sizeof() operator depends on * the kind of the node. If the node is a SYM, the size is obtained * from the symbol table; if it is not a SYM, the size is determined * from the node's type. This is slightly different from C's sizeof() * operator in that (for example) when applied to a function, sizeof() * will evaluate to the length of the function rather than the size of * the function type. */ if (dnp->dn_kind != DT_NODE_SYM) return (dt_node_type_size(dnp)); sip = dnp->dn_ident->di_data; if (dtrace_lookup_by_name(dtp, sip->dts_object, sip->dts_name, &sym, NULL) == -1) return (0); return (sym.st_size);}intdt_node_is_integer(const dt_node_t *dnp){ ctf_file_t *fp = dnp->dn_ctfp; ctf_encoding_t e; ctf_id_t type; uint_t kind; assert(dnp->dn_flags & DT_NF_COOKED); type = ctf_type_resolve(fp, dnp->dn_type); kind = ctf_type_kind(fp, type); if (kind == CTF_K_INTEGER && ctf_type_encoding(fp, type, &e) == 0 && IS_VOID(e)) return (0); /* void integer */ return (kind == CTF_K_INTEGER || kind == CTF_K_ENUM);}intdt_node_is_float(const dt_node_t *dnp){ ctf_file_t *fp = dnp->dn_ctfp; ctf_encoding_t e; ctf_id_t type; uint_t kind; assert(dnp->dn_flags & DT_NF_COOKED); type = ctf_type_resolve(fp, dnp->dn_type); kind = ctf_type_kind(fp, type); return (kind == CTF_K_FLOAT && ctf_type_encoding(dnp->dn_ctfp, type, &e) == 0 && ( e.cte_format == CTF_FP_SINGLE || e.cte_format == CTF_FP_DOUBLE || e.cte_format == CTF_FP_LDOUBLE));}intdt_node_is_scalar(const dt_node_t *dnp){ ctf_file_t *fp = dnp->dn_ctfp; ctf_encoding_t e; ctf_id_t type; uint_t kind; assert(dnp->dn_flags & DT_NF_COOKED); type = ctf_type_resolve(fp, dnp->dn_type); kind = ctf_type_kind(fp, type); if (kind == CTF_K_INTEGER && ctf_type_encoding(fp, type, &e) == 0 && IS_VOID(e)) return (0); /* void cannot be used as a scalar */ return (kind == CTF_K_INTEGER || kind == CTF_K_ENUM || kind == CTF_K_POINTER);}intdt_node_is_arith(const dt_node_t *dnp){ ctf_file_t *fp = dnp->dn_ctfp; ctf_encoding_t e; ctf_id_t type; uint_t kind; assert(dnp->dn_flags & DT_NF_COOKED); type = ctf_type_resolve(fp, dnp->dn_type); kind = ctf_type_kind(fp, type); if (kind == CTF_K_INTEGER) return (ctf_type_encoding(fp, type, &e) == 0 && !IS_VOID(e)); else return (kind == CTF_K_ENUM);}intdt_node_is_vfptr(const dt_node_t *dnp){ ctf_file_t *fp = dnp->dn_ctfp; ctf_encoding_t e; ctf_id_t type; uint_t kind; assert(dnp->dn_flags & DT_NF_COOKED); type = ctf_type_resolve(fp, dnp->dn_type); if (ctf_type_kind(fp, type) != CTF_K_POINTER) return (0); /* type is not a pointer */ type = ctf_type_resolve(fp, ctf_type_reference(fp, type)); kind = ctf_type_kind(fp, type); return (kind == CTF_K_FUNCTION || (kind == CTF_K_INTEGER && ctf_type_encoding(fp, type, &e) == 0 && IS_VOID(e)));}intdt_node_is_dynamic(const dt_node_t *dnp){ return (dnp->dn_ctfp == DT_DYN_CTFP(yypcb->pcb_hdl) && dnp->dn_type == DT_DYN_TYPE(yypcb->pcb_hdl));}intdt_node_is_string(const dt_node_t *dnp){ return (dnp->dn_ctfp == DT_STR_CTFP(yypcb->pcb_hdl) && dnp->dn_type == DT_STR_TYPE(yypcb->pcb_hdl));}intdt_node_is_stack(const dt_node_t *dnp){ return (dnp->dn_ctfp == DT_STACK_CTFP(yypcb->pcb_hdl) && dnp->dn_type == DT_STACK_TYPE(yypcb->pcb_hdl));}intdt_node_is_strcompat(const dt_node_t *dnp){ ctf_file_t *fp = dnp->dn_ctfp; ctf_encoding_t e; ctf_arinfo_t r; ctf_id_t base; uint_t kind; assert(dnp->dn_flags & DT_NF_COOKED); base = ctf_type_resolve(fp, dnp->dn_type); kind = ctf_type_kind(fp, base); if (kind == CTF_K_POINTER && (base = ctf_type_reference(fp, base)) != CTF_ERR && (base = ctf_type_resolve(fp, base)) != CTF_ERR && ctf_type_encoding(fp, base, &e) == 0 && IS_CHAR(e)) return (1); /* promote char pointer to string */ if (kind == CTF_K_ARRAY && ctf_array_info(fp, base, &r) == 0 && (base = ctf_type_resolve(fp, r.ctr_contents)) != CTF_ERR && ctf_type_encoding(fp, base, &e) == 0 && IS_CHAR(e)) return (1); /* promote char array to string */ return (0);}intdt_node_is_pointer(const dt_node_t *dnp){ ctf_file_t *fp = dnp->dn_ctfp; uint_t kind; assert(dnp->dn_flags & DT_NF_COOKED); if (dt_node_is_string(dnp)) return (0); /* string are pass-by-ref but act like structs */ kind = ctf_type_kind(fp, ctf_type_resolve(fp, dnp->dn_type)); return (kind == CTF_K_POINTER || kind == CTF_K_ARRAY);}intdt_node_is_void(const dt_node_t *dnp){ ctf_file_t *fp = dnp->dn_ctfp; ctf_encoding_t e; ctf_id_t type; if (dt_node_is_dynamic(dnp)) return (0); /* <DYN> is an alias for void but not the same */ if (dt_node_is_stack(dnp)) return (0); type = ctf_type_resolve(fp, dnp->dn_type); return (ctf_type_kind(fp, type) == CTF_K_INTEGER && ctf_type_encoding(fp, type, &e) == 0 && IS_VOID(e));}intdt_node_is_ptrcompat(const dt_node_t *lp, const dt_node_t *rp, ctf_file_t **fpp, ctf_id_t *tp){ ctf_file_t *lfp = lp->dn_ctfp; ctf_file_t *rfp = rp->dn_ctfp; ctf_id_t lbase = CTF_ERR, rbase = CTF_ERR; ctf_id_t lref = CTF_ERR, rref = CTF_ERR; int lp_is_void, rp_is_void, lp_is_int, rp_is_int, compat; uint_t lkind, rkind; ctf_encoding_t e; ctf_arinfo_t r; assert(lp->dn_flags & DT_NF_COOKED); assert(rp->dn_flags & DT_NF_COOKED); if (dt_node_is_dynamic(lp) || dt_node_is_dynamic(rp)) return (0); /* fail if either node is a dynamic variable */ lp_is_int = dt_node_is_integer(lp); rp_is_int = dt_node_is_integer(rp); if (lp_is_int && rp_is_int) return (0); /* fail if both nodes are integers */ if (lp_is_int && (lp->dn_kind != DT_NODE_INT || lp->dn_value != 0)) return (0); /* fail if lp is an integer that isn't 0 constant */ if (rp_is_int && (rp->dn_kind != DT_NODE_INT || rp->dn_value != 0)) return (0); /* fail if rp is an integer that isn't 0 constant */ if ((lp_is_int == 0 && rp_is_int == 0) && ( (lp->dn_flags & DT_NF_USERLAND) ^ (rp->dn_flags & DT_NF_USERLAND))) return (0); /* fail if only one pointer is a userland address */ /* * Resolve the left-hand and right-hand types to their base type, and * then resolve the referenced type as well (assuming the base type * is CTF_K_POINTER or CTF_K_ARRAY). Otherwise [lr]ref = CTF_ERR. */ if (!lp_is_int) { lbase = ctf_type_resolve(lfp, lp->dn_type); lkind = ctf_type_kind(lfp, lbase); if (lkind == CTF_K_POINTER) { lref = ctf_type_resolve(lfp, ctf_type_reference(lfp, lbase)); } else if (lkind == CTF_K_ARRAY &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -