Print this page
4474 DTrace Userland CTF Support
4475 DTrace userland Keyword
4476 DTrace tests should be better citizens
4479 pid provider types
4480 dof emulation missing checks
Reviewed by: Bryan Cantrill <bryan@joyent.com>


   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 
  23 /*
  24  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  25  * Use is subject to license terms.
  26  */
  27 
  28 #pragma ident   "%Z%%M% %I%     %E% SMI"
  29 
  30 #include <ctf_impl.h>
  31 
  32 ssize_t
  33 ctf_get_ctt_size(const ctf_file_t *fp, const ctf_type_t *tp, ssize_t *sizep,
  34     ssize_t *incrementp)
  35 {
  36         ssize_t size, increment;
  37 
  38         if (fp->ctf_version > CTF_VERSION_1 &&
  39             tp->ctt_size == CTF_LSIZE_SENT) {
  40                 size = CTF_TYPE_LSIZE(tp);
  41                 increment = sizeof (ctf_type_t);
  42         } else {
  43                 size = tp->ctt_size;
  44                 increment = sizeof (ctf_stype_t);
  45         }
  46 
  47         if (sizep)
  48                 *sizep = size;
  49         if (incrementp)


 182                         if (tp->ctt_type == type || tp->ctt_type == otype ||
 183                             tp->ctt_type == prev) {
 184                                 ctf_dprintf("type %ld cycle detected\n", otype);
 185                                 return (ctf_set_errno(ofp, ECTF_CORRUPT));
 186                         }
 187                         prev = type;
 188                         type = tp->ctt_type;
 189                         break;
 190                 default:
 191                         return (type);
 192                 }
 193         }
 194 
 195         return (CTF_ERR); /* errno is set for us */
 196 }
 197 
 198 /*
 199  * Lookup the given type ID and print a string name for it into buf.  Return
 200  * the actual number of bytes (not including \0) needed to format the name.
 201  */
 202 ssize_t
 203 ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)

 204 {
 205         ctf_decl_t cd;
 206         ctf_decl_node_t *cdp;
 207         ctf_decl_prec_t prec, lp, rp;
 208         int ptr, arr;
 209         uint_t k;
 210 
 211         if (fp == NULL && type == CTF_ERR)
 212                 return (-1); /* simplify caller code by permitting CTF_ERR */
 213 
 214         ctf_decl_init(&cd, buf, len);
 215         ctf_decl_push(&cd, fp, type);
 216 
 217         if (cd.cd_err != 0) {
 218                 ctf_decl_fini(&cd);
 219                 return (ctf_set_errno(fp, cd.cd_err));
 220         }
 221 
 222         /*
 223          * If the type graph's order conflicts with lexical precedence order


 238                 for (cdp = ctf_list_next(&cd.cd_nodes[prec]);
 239                     cdp != NULL; cdp = ctf_list_next(cdp)) {
 240 
 241                         ctf_file_t *rfp = fp;
 242                         const ctf_type_t *tp =
 243                             ctf_lookup_by_id(&rfp, cdp->cd_type);
 244                         const char *name = ctf_strptr(rfp, tp->ctt_name);
 245 
 246                         if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
 247                                 ctf_decl_sprintf(&cd, " ");
 248 
 249                         if (lp == prec) {
 250                                 ctf_decl_sprintf(&cd, "(");
 251                                 lp = -1;
 252                         }
 253 
 254                         switch (cdp->cd_kind) {
 255                         case CTF_K_INTEGER:
 256                         case CTF_K_FLOAT:
 257                         case CTF_K_TYPEDEF:


 258                                 ctf_decl_sprintf(&cd, "%s", name);
 259                                 break;
 260                         case CTF_K_POINTER:
 261                                 ctf_decl_sprintf(&cd, "*");
 262                                 break;
 263                         case CTF_K_ARRAY:
 264                                 ctf_decl_sprintf(&cd, "[%u]", cdp->cd_n);
 265                                 break;
 266                         case CTF_K_FUNCTION:
 267                                 ctf_decl_sprintf(&cd, "()");
 268                                 break;
 269                         case CTF_K_STRUCT:
 270                         case CTF_K_FORWARD:
 271                                 ctf_decl_sprintf(&cd, "struct %s", name);



 272                                 break;
 273                         case CTF_K_UNION:
 274                                 ctf_decl_sprintf(&cd, "union %s", name);



 275                                 break;
 276                         case CTF_K_ENUM:
 277                                 ctf_decl_sprintf(&cd, "enum %s", name);



 278                                 break;
 279                         case CTF_K_VOLATILE:
 280                                 ctf_decl_sprintf(&cd, "volatile");
 281                                 break;
 282                         case CTF_K_CONST:
 283                                 ctf_decl_sprintf(&cd, "const");
 284                                 break;
 285                         case CTF_K_RESTRICT:
 286                                 ctf_decl_sprintf(&cd, "restrict");
 287                                 break;
 288                         }
 289 
 290                         k = cdp->cd_kind;
 291                 }
 292 
 293                 if (rp == prec)
 294                         ctf_decl_sprintf(&cd, ")");
 295         }
 296 
 297         if (cd.cd_len >= len)
 298                 (void) ctf_set_errno(fp, ECTF_NAMELEN);
 299 
 300         ctf_decl_fini(&cd);
 301         return (cd.cd_len);
 302 }
 303 






 304 /*
 305  * Lookup the given type ID and print a string name for it into buf.  If buf
 306  * is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us.
 307  */
 308 char *
 309 ctf_type_name(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
 310 {
 311         ssize_t rv = ctf_type_lname(fp, type, buf, len);








 312         return (rv >= 0 && rv < len ? buf : NULL);
 313 }
 314 

 315 /*
 316  * Resolve the type down to a base type node, and then return the size
 317  * of the type storage in bytes.
 318  */
 319 ssize_t
 320 ctf_type_size(ctf_file_t *fp, ctf_id_t type)
 321 {
 322         const ctf_type_t *tp;
 323         ssize_t size;
 324         ctf_arinfo_t ar;
 325 
 326         if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
 327                 return (-1); /* errno is set for us */
 328 
 329         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 330                 return (-1); /* errno is set for us */
 331 
 332         switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
 333         case CTF_K_POINTER:
 334                 return (fp->ctf_dmodel->ctd_pointer);




   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 
  23 /*
  24  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  25  * Use is subject to license terms.
  26  */
  27 


  28 #include <ctf_impl.h>
  29 
  30 ssize_t
  31 ctf_get_ctt_size(const ctf_file_t *fp, const ctf_type_t *tp, ssize_t *sizep,
  32     ssize_t *incrementp)
  33 {
  34         ssize_t size, increment;
  35 
  36         if (fp->ctf_version > CTF_VERSION_1 &&
  37             tp->ctt_size == CTF_LSIZE_SENT) {
  38                 size = CTF_TYPE_LSIZE(tp);
  39                 increment = sizeof (ctf_type_t);
  40         } else {
  41                 size = tp->ctt_size;
  42                 increment = sizeof (ctf_stype_t);
  43         }
  44 
  45         if (sizep)
  46                 *sizep = size;
  47         if (incrementp)


 180                         if (tp->ctt_type == type || tp->ctt_type == otype ||
 181                             tp->ctt_type == prev) {
 182                                 ctf_dprintf("type %ld cycle detected\n", otype);
 183                                 return (ctf_set_errno(ofp, ECTF_CORRUPT));
 184                         }
 185                         prev = type;
 186                         type = tp->ctt_type;
 187                         break;
 188                 default:
 189                         return (type);
 190                 }
 191         }
 192 
 193         return (CTF_ERR); /* errno is set for us */
 194 }
 195 
 196 /*
 197  * Lookup the given type ID and print a string name for it into buf.  Return
 198  * the actual number of bytes (not including \0) needed to format the name.
 199  */
 200 static ssize_t
 201 ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len,
 202     const char *qname)
 203 {
 204         ctf_decl_t cd;
 205         ctf_decl_node_t *cdp;
 206         ctf_decl_prec_t prec, lp, rp;
 207         int ptr, arr;
 208         uint_t k;
 209 
 210         if (fp == NULL && type == CTF_ERR)
 211                 return (-1); /* simplify caller code by permitting CTF_ERR */
 212 
 213         ctf_decl_init(&cd, buf, len);
 214         ctf_decl_push(&cd, fp, type);
 215 
 216         if (cd.cd_err != 0) {
 217                 ctf_decl_fini(&cd);
 218                 return (ctf_set_errno(fp, cd.cd_err));
 219         }
 220 
 221         /*
 222          * If the type graph's order conflicts with lexical precedence order


 237                 for (cdp = ctf_list_next(&cd.cd_nodes[prec]);
 238                     cdp != NULL; cdp = ctf_list_next(cdp)) {
 239 
 240                         ctf_file_t *rfp = fp;
 241                         const ctf_type_t *tp =
 242                             ctf_lookup_by_id(&rfp, cdp->cd_type);
 243                         const char *name = ctf_strptr(rfp, tp->ctt_name);
 244 
 245                         if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
 246                                 ctf_decl_sprintf(&cd, " ");
 247 
 248                         if (lp == prec) {
 249                                 ctf_decl_sprintf(&cd, "(");
 250                                 lp = -1;
 251                         }
 252 
 253                         switch (cdp->cd_kind) {
 254                         case CTF_K_INTEGER:
 255                         case CTF_K_FLOAT:
 256                         case CTF_K_TYPEDEF:
 257                                 if (qname != NULL)
 258                                         ctf_decl_sprintf(&cd, "%s`", qname);
 259                                 ctf_decl_sprintf(&cd, "%s", name);
 260                                 break;
 261                         case CTF_K_POINTER:
 262                                 ctf_decl_sprintf(&cd, "*");
 263                                 break;
 264                         case CTF_K_ARRAY:
 265                                 ctf_decl_sprintf(&cd, "[%u]", cdp->cd_n);
 266                                 break;
 267                         case CTF_K_FUNCTION:
 268                                 ctf_decl_sprintf(&cd, "()");
 269                                 break;
 270                         case CTF_K_STRUCT:
 271                         case CTF_K_FORWARD:
 272                                 ctf_decl_sprintf(&cd, "struct ");
 273                                 if (qname != NULL)
 274                                         ctf_decl_sprintf(&cd, "%s`", qname);
 275                                 ctf_decl_sprintf(&cd, "%s", name);
 276                                 break;
 277                         case CTF_K_UNION:
 278                                 ctf_decl_sprintf(&cd, "union ");
 279                                 if (qname != NULL)
 280                                         ctf_decl_sprintf(&cd, "%s`", qname);
 281                                 ctf_decl_sprintf(&cd, "%s", name);
 282                                 break;
 283                         case CTF_K_ENUM:
 284                                 ctf_decl_sprintf(&cd, "enum ");
 285                                 if (qname != NULL)
 286                                         ctf_decl_sprintf(&cd, "%s`", qname);
 287                                 ctf_decl_sprintf(&cd, "%s", name);
 288                                 break;
 289                         case CTF_K_VOLATILE:
 290                                 ctf_decl_sprintf(&cd, "volatile");
 291                                 break;
 292                         case CTF_K_CONST:
 293                                 ctf_decl_sprintf(&cd, "const");
 294                                 break;
 295                         case CTF_K_RESTRICT:
 296                                 ctf_decl_sprintf(&cd, "restrict");
 297                                 break;
 298                         }
 299 
 300                         k = cdp->cd_kind;
 301                 }
 302 
 303                 if (rp == prec)
 304                         ctf_decl_sprintf(&cd, ")");
 305         }
 306 
 307         if (cd.cd_len >= len)
 308                 (void) ctf_set_errno(fp, ECTF_NAMELEN);
 309 
 310         ctf_decl_fini(&cd);
 311         return (cd.cd_len);
 312 }
 313 
 314 ssize_t
 315 ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
 316 {
 317         return (ctf_type_qlname(fp, type, buf, len, NULL));
 318 }
 319 
 320 /*
 321  * Lookup the given type ID and print a string name for it into buf.  If buf
 322  * is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us.
 323  */
 324 char *
 325 ctf_type_name(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
 326 {
 327         ssize_t rv = ctf_type_qlname(fp, type, buf, len, NULL);
 328         return (rv >= 0 && rv < len ? buf : NULL);
 329 }
 330 
 331 char *
 332 ctf_type_qname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len,
 333     const char *qname)
 334 {
 335         ssize_t rv = ctf_type_qlname(fp, type, buf, len, qname);
 336         return (rv >= 0 && rv < len ? buf : NULL);
 337 }
 338 
 339 
 340 /*
 341  * Resolve the type down to a base type node, and then return the size
 342  * of the type storage in bytes.
 343  */
 344 ssize_t
 345 ctf_type_size(ctf_file_t *fp, ctf_id_t type)
 346 {
 347         const ctf_type_t *tp;
 348         ssize_t size;
 349         ctf_arinfo_t ar;
 350 
 351         if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
 352                 return (-1); /* errno is set for us */
 353 
 354         if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
 355                 return (-1); /* errno is set for us */
 356 
 357         switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
 358         case CTF_K_POINTER:
 359                 return (fp->ctf_dmodel->ctd_pointer);