X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=libctf%2Fctf-types.c;h=b0139e82bd75e9a272016883a5f0156dda5bb58e;hb=1b61f46da5e55bf2df243215f34ffbca4bcf6d9e;hp=5068ff16a560334e887e077bc0c600fa1d8ca447;hpb=12a0b67d289e2c3ed266d93e8a8c80087f7d18f8;p=deliverable%2Fbinutils-gdb.git diff --git a/libctf/ctf-types.c b/libctf/ctf-types.c index 5068ff16a5..b0139e82bd 100644 --- a/libctf/ctf-types.c +++ b/libctf/ctf-types.c @@ -42,6 +42,7 @@ ctf_member_iter (ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg) { ctf_file_t *ofp = fp; const ctf_type_t *tp; + ctf_dtdef_t *dtd; ssize_t size, increment; uint32_t kind, n; int rc; @@ -58,29 +59,43 @@ ctf_member_iter (ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg) if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) return (ctf_set_errno (ofp, ECTF_NOTSOU)); - if (size < CTF_LSTRUCT_THRESH) + if ((dtd = ctf_dynamic_type (fp, type)) == NULL) { - const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp + - increment); - - for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++) + if (size < CTF_LSTRUCT_THRESH) { - const char *name = ctf_strptr (fp, mp->ctm_name); - if ((rc = func (name, mp->ctm_type, mp->ctm_offset, arg)) != 0) + const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp + + increment); + + for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++) + { + const char *name = ctf_strptr (fp, mp->ctm_name); + if ((rc = func (name, mp->ctm_type, mp->ctm_offset, arg)) != 0) return rc; + } } + else + { + const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp + + increment); + for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++) + { + const char *name = ctf_strptr (fp, lmp->ctlm_name); + if ((rc = func (name, lmp->ctlm_type, + (unsigned long) CTF_LMEM_OFFSET (lmp), arg)) != 0) + return rc; + } + } } else { - const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp + - increment); + ctf_dmdef_t *dmd; - for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++) + for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members); + dmd != NULL; dmd = ctf_list_next (dmd)) { - const char *name = ctf_strptr (fp, lmp->ctlm_name); - if ((rc = func (name, lmp->ctlm_type, - (unsigned long) CTF_LMEM_OFFSET (lmp), arg)) != 0) + if ((rc = func (dmd->dmd_name, dmd->dmd_type, + dmd->dmd_offset, arg)) != 0) return rc; } } @@ -97,6 +112,7 @@ ctf_enum_iter (ctf_file_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg) ctf_file_t *ofp = fp; const ctf_type_t *tp; const ctf_enum_t *ep; + ctf_dtdef_t *dtd; ssize_t increment; uint32_t n; int rc; @@ -112,13 +128,27 @@ ctf_enum_iter (ctf_file_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg) (void) ctf_get_ctt_size (fp, tp, NULL, &increment); - ep = (const ctf_enum_t *) ((uintptr_t) tp + increment); + if ((dtd = ctf_dynamic_type (ofp, type)) == NULL) + { + ep = (const ctf_enum_t *) ((uintptr_t) tp + increment); - for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++) + for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++) + { + const char *name = ctf_strptr (fp, ep->cte_name); + if ((rc = func (name, ep->cte_value, arg)) != 0) + return rc; + } + } + else { - const char *name = ctf_strptr (fp, ep->cte_name); - if ((rc = func (name, ep->cte_value, arg)) != 0) - return rc; + ctf_dmdef_t *dmd; + + for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members); + dmd != NULL; dmd = ctf_list_next (dmd)) + { + if ((rc = func (dmd->dmd_name, dmd->dmd_value, arg)) != 0) + return rc; + } } return 0; @@ -144,22 +174,57 @@ ctf_type_iter (ctf_file_t *fp, ctf_type_f *func, void *arg) return 0; } +/* Iterate over every type in the given CTF container, user-visible or not. + We pass the type ID of each type to the specified callback function. */ + +int +ctf_type_iter_all (ctf_file_t *fp, ctf_type_all_f *func, void *arg) +{ + ctf_id_t id, max = fp->ctf_typemax; + int rc, child = (fp->ctf_flags & LCTF_CHILD); + + for (id = 1; id <= max; id++) + { + const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, id); + if ((rc = func (LCTF_INDEX_TO_TYPE (fp, id, child), + LCTF_INFO_ISROOT(fp, tp->ctt_info) + ? CTF_ADD_ROOT : CTF_ADD_NONROOT, arg) != 0)) + return rc; + } + + return 0; +} + /* Iterate over every variable in the given CTF container, in arbitrary order. We pass the name of each variable to the specified callback function. */ int ctf_variable_iter (ctf_file_t *fp, ctf_variable_f *func, void *arg) { - unsigned long i; int rc; if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parent == NULL)) return ECTF_NOPARENT; - for (i = 0; i < fp->ctf_nvars; i++) - if ((rc = func (ctf_strptr (fp, fp->ctf_vars[i].ctv_name), - fp->ctf_vars[i].ctv_type, arg)) != 0) - return rc; + if (!(fp->ctf_flags & LCTF_RDWR)) + { + unsigned long i; + for (i = 0; i < fp->ctf_nvars; i++) + if ((rc = func (ctf_strptr (fp, fp->ctf_vars[i].ctv_name), + fp->ctf_vars[i].ctv_type, arg)) != 0) + return rc; + } + else + { + ctf_dvdef_t *dvd; + + for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; + dvd = ctf_list_next (dvd)) + { + if ((rc = func (dvd->dvd_name, dvd->dvd_type, arg)) != 0) + return rc; + } + } return 0; } @@ -179,6 +244,9 @@ ctf_type_resolve (ctf_file_t *fp, ctf_id_t type) ctf_file_t *ofp = fp; const ctf_type_t *tp; + if (type == 0) + return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE)); + while ((tp = ctf_lookup_by_id (&fp, type)) != NULL) { switch (LCTF_INFO_KIND (fp, tp->ctt_info)) @@ -199,6 +267,8 @@ ctf_type_resolve (ctf_file_t *fp, ctf_id_t type) default: return type; } + if (type == 0) + return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE)); } return CTF_ERR; /* errno is set for us. */ @@ -223,6 +293,29 @@ ctf_type_resolve_unsliced (ctf_file_t *fp, ctf_id_t type) return type; } +/* Look up a name in the given name table, in the appropriate hash given the + kind of the identifier. The name is a raw, undecorated identifier. */ + +ctf_id_t ctf_lookup_by_rawname (ctf_file_t *fp, int kind, const char *name) +{ + return ctf_lookup_by_rawhash (fp, ctf_name_table (fp, kind), name); +} + +/* Look up a name in the given name table, in the appropriate hash given the + readability state of the dictionary. The name is a raw, undecorated + identifier. */ + +ctf_id_t ctf_lookup_by_rawhash (ctf_file_t *fp, ctf_names_t *np, const char *name) +{ + ctf_id_t id; + + if (fp->ctf_flags & LCTF_RDWR) + id = (ctf_id_t) ctf_dynhash_lookup (np->ctn_writable, name); + else + id = ctf_hash_lookup_type (np->ctn_readonly, fp, name); + return id; +} + /* Lookup the given type ID and return its name as a new dynamcally-allocated string. */ @@ -345,11 +438,12 @@ ssize_t ctf_type_lname (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) { char *str = ctf_type_aname (fp, type); - size_t slen = strlen (str); + size_t slen; if (str == NULL) - return CTF_ERR; /* errno is set for us */ + return CTF_ERR; /* errno is set for us. */ + slen = strlen (str); snprintf (buf, len, "%s", str); free (str); @@ -645,7 +739,27 @@ ctf_type_encoding (ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep) if ((dtd = ctf_dynamic_type (ofp, type)) != NULL) { - *ep = dtd->dtd_u.dtu_enc; + switch (LCTF_INFO_KIND (fp, tp->ctt_info)) + { + case CTF_K_INTEGER: + case CTF_K_FLOAT: + *ep = dtd->dtd_u.dtu_enc; + break; + case CTF_K_SLICE: + { + const ctf_slice_t *slice; + ctf_encoding_t underlying_en; + slice = &dtd->dtd_u.dtu_slice; + + data = ctf_type_encoding (fp, slice->cts_type, &underlying_en); + ep->cte_format = underlying_en.cte_format; + ep->cte_offset = slice->cts_offset; + ep->cte_bits = slice->cts_bits; + break; + } + default: + return (ctf_set_errno (ofp, ECTF_NOTINTFP)); + } return 0; } @@ -803,6 +917,7 @@ ctf_member_info (ctf_file_t *fp, ctf_id_t type, const char *name, { ctf_file_t *ofp = fp; const ctf_type_t *tp; + ctf_dtdef_t *dtd; ssize_t size, increment; uint32_t kind, n; @@ -818,32 +933,50 @@ ctf_member_info (ctf_file_t *fp, ctf_id_t type, const char *name, if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) return (ctf_set_errno (ofp, ECTF_NOTSOU)); - if (size < CTF_LSTRUCT_THRESH) + if ((dtd = ctf_dynamic_type (fp, type)) == NULL) { - const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp + - increment); + if (size < CTF_LSTRUCT_THRESH) + { + const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp + + increment); - for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++) + for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++) + { + if (strcmp (ctf_strptr (fp, mp->ctm_name), name) == 0) + { + mip->ctm_type = mp->ctm_type; + mip->ctm_offset = mp->ctm_offset; + return 0; + } + } + } + else { - if (strcmp (ctf_strptr (fp, mp->ctm_name), name) == 0) + const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp + + increment); + + for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++) { - mip->ctm_type = mp->ctm_type; - mip->ctm_offset = mp->ctm_offset; - return 0; + if (strcmp (ctf_strptr (fp, lmp->ctlm_name), name) == 0) + { + mip->ctm_type = lmp->ctlm_type; + mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp); + return 0; + } } } } else { - const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp + - increment); + ctf_dmdef_t *dmd; - for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++) + for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members); + dmd != NULL; dmd = ctf_list_next (dmd)) { - if (strcmp (ctf_strptr (fp, lmp->ctlm_name), name) == 0) + if (strcmp (dmd->dmd_name, name) == 0) { - mip->ctm_type = lmp->ctlm_type; - mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp); + mip->ctm_type = dmd->dmd_type; + mip->ctm_offset = dmd->dmd_offset; return 0; } } @@ -894,6 +1027,7 @@ ctf_enum_name (ctf_file_t *fp, ctf_id_t type, int value) ctf_file_t *ofp = fp; const ctf_type_t *tp; const ctf_enum_t *ep; + const ctf_dtdef_t *dtd; ssize_t increment; uint32_t n; @@ -911,12 +1045,26 @@ ctf_enum_name (ctf_file_t *fp, ctf_id_t type, int value) (void) ctf_get_ctt_size (fp, tp, NULL, &increment); - ep = (const ctf_enum_t *) ((uintptr_t) tp + increment); + if ((dtd = ctf_dynamic_type (ofp, type)) == NULL) + { + ep = (const ctf_enum_t *) ((uintptr_t) tp + increment); - for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++) + for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++) + { + if (ep->cte_value == value) + return (ctf_strptr (fp, ep->cte_name)); + } + } + else { - if (ep->cte_value == value) - return (ctf_strptr (fp, ep->cte_name)); + ctf_dmdef_t *dmd; + + for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members); + dmd != NULL; dmd = ctf_list_next (dmd)) + { + if (dmd->dmd_value == value) + return dmd->dmd_name; + } } (void) ctf_set_errno (ofp, ECTF_NOENUMNAM); @@ -932,6 +1080,7 @@ ctf_enum_value (ctf_file_t * fp, ctf_id_t type, const char *name, int *valp) ctf_file_t *ofp = fp; const ctf_type_t *tp; const ctf_enum_t *ep; + const ctf_dtdef_t *dtd; ssize_t increment; uint32_t n; @@ -951,13 +1100,31 @@ ctf_enum_value (ctf_file_t * fp, ctf_id_t type, const char *name, int *valp) ep = (const ctf_enum_t *) ((uintptr_t) tp + increment); - for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++) + if ((dtd = ctf_dynamic_type (ofp, type)) == NULL) { - if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0) + for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++) { - if (valp != NULL) - *valp = ep->cte_value; - return 0; + if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0) + { + if (valp != NULL) + *valp = ep->cte_value; + return 0; + } + } + } + else + { + ctf_dmdef_t *dmd; + + for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members); + dmd != NULL; dmd = ctf_list_next (dmd)) + { + if (strcmp (dmd->dmd_name, name) == 0) + { + if (valp != NULL) + *valp = dmd->dmd_value; + return 0; + } } } @@ -974,6 +1141,7 @@ ctf_func_type_info (ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip) const ctf_type_t *tp; uint32_t kind; const uint32_t *args; + const ctf_dtdef_t *dtd; ssize_t size, increment; if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) @@ -989,10 +1157,13 @@ ctf_func_type_info (ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip) return (ctf_set_errno (fp, ECTF_NOTFUNC)); fip->ctc_return = tp->ctt_type; - fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info); fip->ctc_flags = 0; + fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info); - args = (uint32_t *) ((uintptr_t) tp + increment); + if ((dtd = ctf_dynamic_type (fp, type)) == NULL) + args = (uint32_t *) ((uintptr_t) tp + increment); + else + args = (uint32_t *) dtd->dtd_u.dtu_argv; if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0) { @@ -1011,6 +1182,7 @@ ctf_func_type_args (ctf_file_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv { const ctf_type_t *tp; const uint32_t *args; + const ctf_dtdef_t *dtd; ssize_t size, increment; ctf_funcinfo_t f; @@ -1025,7 +1197,10 @@ ctf_func_type_args (ctf_file_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv (void) ctf_get_ctt_size (fp, tp, &size, &increment); - args = (uint32_t *) ((uintptr_t) tp + increment); + if ((dtd = ctf_dynamic_type (fp, type)) == NULL) + args = (uint32_t *) ((uintptr_t) tp + increment); + else + args = (uint32_t *) dtd->dtd_u.dtu_argv; for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--) *argv++ = *args++; @@ -1045,6 +1220,7 @@ ctf_type_rvisit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, { ctf_id_t otype = type; const ctf_type_t *tp; + const ctf_dtdef_t *dtd; ssize_t size, increment; uint32_t kind, n; int rc; @@ -1065,32 +1241,48 @@ ctf_type_rvisit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, (void) ctf_get_ctt_size (fp, tp, &size, &increment); - if (size < CTF_LSTRUCT_THRESH) + if ((dtd = ctf_dynamic_type (fp, type)) == NULL) { - const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp + - increment); - - for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++) + if (size < CTF_LSTRUCT_THRESH) { - if ((rc = ctf_type_rvisit (fp, mp->ctm_type, - func, arg, ctf_strptr (fp, mp->ctm_name), - offset + mp->ctm_offset, - depth + 1)) != 0) - return rc; + const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp + + increment); + + for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++) + { + if ((rc = ctf_type_rvisit (fp, mp->ctm_type, + func, arg, ctf_strptr (fp, + mp->ctm_name), + offset + mp->ctm_offset, + depth + 1)) != 0) + return rc; + } } + else + { + const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp + + increment); + for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++) + { + if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type, + func, arg, ctf_strptr (fp, + lmp->ctlm_name), + offset + (unsigned long) CTF_LMEM_OFFSET (lmp), + depth + 1)) != 0) + return rc; + } + } } else { - const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp + - increment); + ctf_dmdef_t *dmd; - for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++) + for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members); + dmd != NULL; dmd = ctf_list_next (dmd)) { - if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type, - func, arg, ctf_strptr (fp, - lmp->ctlm_name), - offset + (unsigned long) CTF_LMEM_OFFSET (lmp), + if ((rc = ctf_type_rvisit (fp, dmd->dmd_type, func, arg, + dmd->dmd_name, dmd->dmd_offset, depth + 1)) != 0) return rc; }