📄 ctf_create.c
字号:
} nmd = ctf_list_next(dmd); ctf_free(dmd, sizeof (ctf_dmdef_t)); } break; case CTF_K_FUNCTION: ctf_free(dtd->dtd_u.dtu_argv, sizeof (ctf_id_t) * CTF_INFO_VLEN(dtd->dtd_data.ctt_info)); break; } if (dtd->dtd_name) { len = strlen(dtd->dtd_name) + 1; ctf_free(dtd->dtd_name, len); fp->ctf_dtstrlen -= len; } ntd = ctf_list_next(dtd); ctf_list_delete(&fp->ctf_dtdefs, dtd); ctf_free(dtd, sizeof (ctf_dtdef_t)); } fp->ctf_dtnextid = fp->ctf_dtoldid + 1; fp->ctf_flags &= ~LCTF_DIRTY; return (0);}static ctf_id_tctf_add_generic(ctf_file_t *fp, uint_t flag, const char *name, ctf_dtdef_t **rp){ ctf_dtdef_t *dtd; ctf_id_t type; char *s = NULL; if (flag != CTF_ADD_NONROOT && flag != CTF_ADD_ROOT) return (ctf_set_errno(fp, EINVAL)); if (!(fp->ctf_flags & LCTF_RDWR)) return (ctf_set_errno(fp, ECTF_RDONLY)); if (CTF_INDEX_TO_TYPE(fp->ctf_dtnextid, 1) > CTF_MAX_TYPE) return (ctf_set_errno(fp, ECTF_FULL)); if ((dtd = ctf_alloc(sizeof (ctf_dtdef_t))) == NULL) return (ctf_set_errno(fp, EAGAIN)); if (name != NULL && (s = ctf_strdup(name)) == NULL) { ctf_free(dtd, sizeof (ctf_dtdef_t)); return (ctf_set_errno(fp, EAGAIN)); } type = fp->ctf_dtnextid++; type = CTF_INDEX_TO_TYPE(type, (fp->ctf_flags & LCTF_CHILD)); bzero(dtd, sizeof (ctf_dtdef_t)); dtd->dtd_name = s; dtd->dtd_type = type; if (s != NULL) fp->ctf_dtstrlen += strlen(s) + 1; ctf_list_append(&fp->ctf_dtdefs, dtd); fp->ctf_flags |= LCTF_DIRTY; *rp = dtd; return (type);}/* * When encoding integer sizes, we want to convert a byte count in the range * 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function * is a clever implementation from "Hacker's Delight" by Henry Warren, Jr. */static size_tclp2(size_t x){ x--; x |= (x >> 1); x |= (x >> 2); x |= (x >> 4); x |= (x >> 8); x |= (x >> 16); return (x + 1);}static ctf_id_tctf_add_encoded(ctf_file_t *fp, uint_t flag, const char *name, const ctf_encoding_t *ep, uint_t kind){ ctf_dtdef_t *dtd; ctf_id_t type; if (ep == NULL) return (ctf_set_errno(fp, EINVAL)); if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) return (CTF_ERR); /* errno is set for us */ dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, 0); dtd->dtd_data.ctt_size = clp2(P2ROUNDUP(ep->cte_bits, NBBY) / NBBY); dtd->dtd_u.dtu_enc = *ep; return (type);}static ctf_id_tctf_add_reftype(ctf_file_t *fp, uint_t flag, ctf_id_t ref, uint_t kind){ ctf_dtdef_t *dtd; ctf_id_t type; if (ref == CTF_ERR || ref < 0 || ref > CTF_MAX_TYPE) return (ctf_set_errno(fp, EINVAL)); if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR) return (CTF_ERR); /* errno is set for us */ dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, 0); dtd->dtd_data.ctt_type = (ushort_t)ref; return (type);}ctf_id_tctf_add_integer(ctf_file_t *fp, uint_t flag, const char *name, const ctf_encoding_t *ep){ return (ctf_add_encoded(fp, flag, name, ep, CTF_K_INTEGER));}ctf_id_tctf_add_float(ctf_file_t *fp, uint_t flag, const char *name, const ctf_encoding_t *ep){ return (ctf_add_encoded(fp, flag, name, ep, CTF_K_FLOAT));}ctf_id_tctf_add_pointer(ctf_file_t *fp, uint_t flag, ctf_id_t ref){ return (ctf_add_reftype(fp, flag, ref, CTF_K_POINTER));}ctf_id_tctf_add_array(ctf_file_t *fp, uint_t flag, const ctf_arinfo_t *arp){ ctf_dtdef_t *dtd; ctf_id_t type; if (arp == NULL) return (ctf_set_errno(fp, EINVAL)); if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR) return (CTF_ERR); /* errno is set for us */ dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ARRAY, flag, 0); dtd->dtd_data.ctt_size = 0; dtd->dtd_u.dtu_arr = *arp; return (type);}intctf_set_array(ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp){ ctf_dtdef_t *dtd; if (!(fp->ctf_flags & LCTF_RDWR)) return (ctf_set_errno(fp, ECTF_RDONLY)); for (dtd = ctf_list_next(&fp->ctf_dtdefs); dtd != NULL; dtd = ctf_list_next(dtd)) { if (dtd->dtd_type == type) break; } if (dtd == NULL || CTF_INFO_KIND(dtd->dtd_data.ctt_info) != CTF_K_ARRAY) return (ctf_set_errno(fp, ECTF_BADID)); fp->ctf_flags |= LCTF_DIRTY; dtd->dtd_u.dtu_arr = *arp; return (0);}ctf_id_tctf_add_function(ctf_file_t *fp, uint_t flag, const ctf_funcinfo_t *ctc, const ctf_id_t *argv){ ctf_dtdef_t *dtd; ctf_id_t type; uint_t vlen; ctf_id_t *vdat = NULL; if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0 || (ctc->ctc_argc != 0 && argv == NULL)) return (ctf_set_errno(fp, EINVAL)); vlen = ctc->ctc_argc; if (ctc->ctc_flags & CTF_FUNC_VARARG) vlen++; /* add trailing zero to indicate varargs (see below) */ if (vlen > CTF_MAX_VLEN) return (ctf_set_errno(fp, EOVERFLOW)); if (vlen != 0 && (vdat = ctf_alloc(sizeof (ctf_id_t) * vlen)) == NULL) return (ctf_set_errno(fp, EAGAIN)); if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR) { ctf_free(vdat, sizeof (ctf_id_t) * vlen); return (CTF_ERR); /* errno is set for us */ } dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_FUNCTION, flag, vlen); dtd->dtd_data.ctt_type = (ushort_t)ctc->ctc_return; bcopy(argv, vdat, sizeof (ctf_id_t) * ctc->ctc_argc); if (ctc->ctc_flags & CTF_FUNC_VARARG) vdat[vlen - 1] = 0; /* add trailing zero to indicate varargs */ dtd->dtd_u.dtu_argv = vdat; return (type);}ctf_id_tctf_add_struct(ctf_file_t *fp, uint_t flag, const char *name){ ctf_dtdef_t *dtd; ctf_id_t type; if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) return (CTF_ERR); /* errno is set for us */ dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_STRUCT, flag, 0); return (type);}ctf_id_tctf_add_union(ctf_file_t *fp, uint_t flag, const char *name){ ctf_dtdef_t *dtd; ctf_id_t type; if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) return (CTF_ERR); /* errno is set for us */ dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_UNION, flag, 0); return (type);}ctf_id_tctf_add_enum(ctf_file_t *fp, uint_t flag, const char *name){ ctf_dtdef_t *dtd; ctf_id_t type; if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) return (CTF_ERR); /* errno is set for us */ dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, flag, 0); dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int; return (type);}ctf_id_tctf_add_forward(ctf_file_t *fp, uint_t flag, const char *name, uint_t kind){ ctf_dtdef_t *dtd; ctf_id_t type; if (kind != CTF_K_STRUCT && kind != CTF_K_UNION && kind != CTF_K_ENUM) return (ctf_set_errno(fp, ECTF_NOTSUE)); if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) return (CTF_ERR); /* errno is set for us */ dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_FORWARD, flag, 0); return (type);}ctf_id_tctf_add_typedef(ctf_file_t *fp, uint_t flag, const char *name, ctf_id_t ref){ ctf_dtdef_t *dtd; ctf_id_t type; if (ref == CTF_ERR || ref < 0 || ref > CTF_MAX_TYPE) return (ctf_set_errno(fp, EINVAL)); if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR) return (CTF_ERR); /* errno is set for us */ dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_TYPEDEF, flag, 0); dtd->dtd_data.ctt_type = (ushort_t)ref; return (type);}ctf_id_tctf_add_volatile(ctf_file_t *fp, uint_t flag, ctf_id_t ref){ return (ctf_add_reftype(fp, flag, ref, CTF_K_VOLATILE));}ctf_id_tctf_add_const(ctf_file_t *fp, uint_t flag, ctf_id_t ref){ return (ctf_add_reftype(fp, flag, ref, CTF_K_CONST));}ctf_id_tctf_add_restrict(ctf_file_t *fp, uint_t flag, ctf_id_t ref){ return (ctf_add_reftype(fp, flag, ref, CTF_K_RESTRICT));}intctf_add_enumerator(ctf_file_t *fp, ctf_id_t enid, const char *name, int value){ ctf_dtdef_t *dtd; ctf_dmdef_t *dmd; uint_t kind, vlen, root; char *s; if (name == NULL) return (ctf_set_errno(fp, EINVAL)); if (!(fp->ctf_flags & LCTF_RDWR)) return (ctf_set_errno(fp, ECTF_RDONLY)); for (dtd = ctf_list_next(&fp->ctf_dtdefs); dtd != NULL; dtd = ctf_list_next(dtd)) { if (dtd->dtd_type == enid) break; } if (dtd == NULL) return (ctf_set_errno(fp, ECTF_BADID)); kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info); root = CTF_INFO_ISROOT(dtd->dtd_data.ctt_info); vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info); if (kind != CTF_K_ENUM) return (ctf_set_errno(fp, ECTF_NOTENUM)); if (vlen == CTF_MAX_VLEN) return (ctf_set_errno(fp, ECTF_DTFULL)); for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members); dmd != NULL; dmd = ctf_list_next(dmd)) { if (strcmp(dmd->dmd_name, name) == 0) return (ctf_set_errno(fp, ECTF_DUPMEMBER)); } if ((dmd = ctf_alloc(sizeof (ctf_dmdef_t))) == NULL) return (ctf_set_errno(fp, EAGAIN)); if ((s = ctf_strdup(name)) == NULL) { ctf_free(dmd, sizeof (ctf_dmdef_t)); return (ctf_set_errno(fp, EAGAIN)); } dmd->dmd_name = s; dmd->dmd_type = CTF_ERR; dmd->dmd_offset = 0; dmd->dmd_value = value; dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, root, vlen + 1); ctf_list_append(&dtd->dtd_u.dtu_members, dmd); fp->ctf_dtstrlen += strlen(s) + 1; fp->ctf_flags |= LCTF_DIRTY; return (0);}intctf_add_member(ctf_file_t *fp, ctf_id_t souid, const char *name, ctf_id_t type){ ctf_dtdef_t *dtd; ctf_dmdef_t *dmd; ssize_t msize, malign, ssize; uint_t kind, vlen, root; char *s = NULL; if (!(fp->ctf_flags & LCTF_RDWR)) return (ctf_set_errno(fp, ECTF_RDONLY)); for (dtd = ctf_list_next(&fp->ctf_dtdefs); dtd != NULL; dtd = ctf_list_next(dtd)) { if (dtd->dtd_type == souid) break; } if (dtd == NULL) return (ctf_set_errno(fp, ECTF_BADID)); kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info); root = CTF_INFO_ISROOT(dtd->dtd_data.ctt_info); vlen = CTF_INFO_VLEN(dtd->dtd_data.ctt_info); if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) return (ctf_set_errno(fp, ECTF_NOTSOU)); if (vlen == CTF_MAX_VLEN) return (ctf_set_errno(fp, ECTF_DTFULL)); if (name != NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -