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>


   6  * Common Development and Distribution License (the "License").
   7  * You may not use this file except in compliance with the License.
   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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  25  */




  26 
  27 #include <string.h>
  28 #include <stdlib.h>
  29 #include <stdio.h>
  30 #include <assert.h>
  31 #include <ctype.h>
  32 #include <errno.h>
  33 
  34 #include <dt_impl.h>
  35 #include <dt_grammar.h>
  36 #include <dt_parser.h>
  37 #include <dt_string.h>
  38 
  39 /*
  40  * We need to undefine lex's input and unput macros so that references to these
  41  * call the functions provided at the end of this source file.
  42  */
  43 #undef input
  44 #undef unput
  45 
  46 static int id_or_type(const char *);
  47 static int input(void);
  48 static void unput(int);
  49 
  50 /*
  51  * We first define a set of labeled states for use in the D lexer and then a
  52  * set of regular expressions to simplify things below. The lexer states are:
  53  *
  54  * S0 - D program clause and expression lexing
  55  * S1 - D comments (i.e. skip everything until end of comment)
  56  * S2 - D program outer scope (probe specifiers and declarations)
  57  * S3 - D control line parsing (i.e. after ^# is seen but before \n)
  58  * S4 - D control line scan (locate control directives only and invoke S3)
  59  */
  60 %}
  61 
  62 %e 1500         /* maximum nodes */
  63 %p 3700         /* maximum positions */
  64 %n 600          /* maximum states */

  65 
  66 %s S0 S1 S2 S3 S4
  67 
  68 RGX_AGG         "@"[a-zA-Z_][0-9a-zA-Z_]*
  69 RGX_PSPEC       [-$:a-zA-Z_.?*\\\[\]!][-$:0-9a-zA-Z_.`?*\\\[\]!]*



  70 RGX_IDENT       [a-zA-Z_`][0-9a-zA-Z_`]*
  71 RGX_INT         ([0-9]+|0[xX][0-9A-Fa-f]+)[uU]?[lL]?[lL]?
  72 RGX_FP          ([0-9]+("."?)[0-9]*|"."[0-9]+)((e|E)("+"|-)?[0-9]+)?[fFlL]?
  73 RGX_WS          [\f\n\r\t\v ]
  74 RGX_STR         ([^"\\\n]|\\[^"\n]|\\\")*
  75 RGX_CHR         ([^'\\\n]|\\[^'\n]|\\')*
  76 RGX_INTERP      ^[\f\t\v ]*#!.*
  77 RGX_CTL         ^[\f\t\v ]*#
  78 
  79 %%
  80 
  81 %{
  82 
  83 /*
  84  * We insert a special prologue into yylex() itself: if the pcb contains a
  85  * context token, we return that prior to running the normal lexer.  This
  86  * allows libdtrace to force yacc into one of our three parsing contexts: D
  87  * expression (DT_CTX_DEXPR), D program (DT_CTX_DPROG) or D type (DT_CTX_DTYPE).
  88  * Once the token is returned, we clear it so this only happens once.
  89  */


 119 <S0>offsetof      return (DT_TOK_OFFSETOF);
 120 <S0>probe return (DT_KEY_PROBE);
 121 <S0>provider      return (DT_KEY_PROVIDER);
 122 <S0>register      return (DT_KEY_REGISTER);
 123 <S0>restrict      return (DT_KEY_RESTRICT);
 124 <S0>return        return (DT_KEY_RETURN);
 125 <S0>self  return (DT_KEY_SELF);
 126 <S0>short return (DT_KEY_SHORT);
 127 <S0>signed        return (DT_KEY_SIGNED);
 128 <S0>sizeof        return (DT_TOK_SIZEOF);
 129 <S0>static        return (DT_KEY_STATIC);
 130 <S0>string        return (DT_KEY_STRING);
 131 <S0>stringof      return (DT_TOK_STRINGOF);
 132 <S0>struct        return (DT_KEY_STRUCT);
 133 <S0>switch        return (DT_KEY_SWITCH);
 134 <S0>this  return (DT_KEY_THIS);
 135 <S0>translator    return (DT_KEY_XLATOR);
 136 <S0>typedef       return (DT_KEY_TYPEDEF);
 137 <S0>union return (DT_KEY_UNION);
 138 <S0>unsigned      return (DT_KEY_UNSIGNED);

 139 <S0>void  return (DT_KEY_VOID);
 140 <S0>volatile      return (DT_KEY_VOLATILE);
 141 <S0>while return (DT_KEY_WHILE);
 142 <S0>xlate return (DT_TOK_XLATE);
 143 
 144 <S2>auto  { yybegin(YYS_EXPR);    return (DT_KEY_AUTO); }
 145 <S2>char  { yybegin(YYS_EXPR);    return (DT_KEY_CHAR); }
 146 <S2>const { yybegin(YYS_EXPR);    return (DT_KEY_CONST); }
 147 <S2>counter       { yybegin(YYS_DEFINE);  return (DT_KEY_COUNTER); }
 148 <S2>double        { yybegin(YYS_EXPR);    return (DT_KEY_DOUBLE); }
 149 <S2>enum  { yybegin(YYS_EXPR);    return (DT_KEY_ENUM); }
 150 <S2>extern        { yybegin(YYS_EXPR);    return (DT_KEY_EXTERN); }
 151 <S2>float { yybegin(YYS_EXPR);    return (DT_KEY_FLOAT); }
 152 <S2>import        { yybegin(YYS_EXPR);    return (DT_KEY_IMPORT); }
 153 <S2>inline        { yybegin(YYS_DEFINE);  return (DT_KEY_INLINE); }
 154 <S2>int           { yybegin(YYS_EXPR);    return (DT_KEY_INT); }
 155 <S2>long  { yybegin(YYS_EXPR);    return (DT_KEY_LONG); }
 156 <S2>provider      { yybegin(YYS_DEFINE);  return (DT_KEY_PROVIDER); }
 157 <S2>register      { yybegin(YYS_EXPR);    return (DT_KEY_REGISTER); }
 158 <S2>restrict      { yybegin(YYS_EXPR);    return (DT_KEY_RESTRICT); }


 297                         dt_ident_t *idp = dt_idhash_lookup(
 298                             yypcb->pcb_hdl->dt_macros, yytext + 1);
 299 
 300                         if (idp == NULL) {
 301                                 xyerror(D_MACRO_UNDEF, "macro variable %s "
 302                                     "is not defined\n", yytext);
 303                         }
 304 
 305                         /*
 306                          * For the moment, all current macro variables are of
 307                          * type id_t (refer to dtrace_update() for details).
 308                          */
 309                         yylval.l_int = (intmax_t)(int)idp->di_id;
 310                         yyintprefix = 0;
 311                         yyintsuffix[0] = '\0';
 312                         yyintdecimal = 1;
 313 
 314                         return (DT_TOK_INT);
 315                 }
 316 
 317 <S0>{RGX_IDENT}   {


 318                         return (id_or_type(yytext));
 319                 }
 320 
 321 <S0>{RGX_AGG}     {
 322                         if ((yylval.l_str = strdup(yytext)) == NULL)
 323                                 longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
 324                         return (DT_TOK_AGG);
 325                 }
 326 
 327 <S0>"@"           {
 328                         if ((yylval.l_str = strdup("@_")) == NULL)
 329                                 longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
 330                         return (DT_TOK_AGG);
 331                 }
 332 
 333 <S0>{RGX_INT}     |
 334 <S2>{RGX_INT}     |
 335 <S3>{RGX_INT}     {
 336                         char *p;
 337 




   6  * Common Development and Distribution License (the "License").
   7  * You may not use this file except in compliance with the License.
   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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  25  */
  26 /*
  27  * Copyright (c) 2013 by Delphix. All rights reserved.
  28  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  29  */
  30 
  31 #include <string.h>
  32 #include <stdlib.h>
  33 #include <stdio.h>
  34 #include <assert.h>
  35 #include <ctype.h>
  36 #include <errno.h>
  37 
  38 #include <dt_impl.h>
  39 #include <dt_grammar.h>
  40 #include <dt_parser.h>
  41 #include <dt_string.h>
  42 
  43 /*
  44  * We need to undefine lex's input and unput macros so that references to these
  45  * call the functions provided at the end of this source file.
  46  */
  47 #undef input
  48 #undef unput
  49 
  50 static int id_or_type(const char *);
  51 static int input(void);
  52 static void unput(int);
  53 
  54 /*
  55  * We first define a set of labeled states for use in the D lexer and then a
  56  * set of regular expressions to simplify things below. The lexer states are:
  57  *
  58  * S0 - D program clause and expression lexing
  59  * S1 - D comments (i.e. skip everything until end of comment)
  60  * S2 - D program outer scope (probe specifiers and declarations)
  61  * S3 - D control line parsing (i.e. after ^# is seen but before \n)
  62  * S4 - D control line scan (locate control directives only and invoke S3)
  63  */
  64 %}
  65 
  66 %e 1500         /* maximum nodes */
  67 %p 4900         /* maximum positions */
  68 %n 600          /* maximum states */
  69 %a 3000         /* maximum transitions */
  70 
  71 %s S0 S1 S2 S3 S4
  72 
  73 RGX_AGG         "@"[a-zA-Z_][0-9a-zA-Z_]*
  74 RGX_PSPEC       [-$:a-zA-Z_.?*\\\[\]!][-$:0-9a-zA-Z_.`?*\\\[\]!]*
  75 RGX_ALTIDENT    [a-zA-Z_][0-9a-zA-Z_]*
  76 RGX_LMID        LM[0-9a-fA-F]+`
  77 RGX_MOD_IDENT   [a-zA-Z_`][0-9a-z.A-Z_`]*`
  78 RGX_IDENT       [a-zA-Z_`][0-9a-zA-Z_`]*
  79 RGX_INT         ([0-9]+|0[xX][0-9A-Fa-f]+)[uU]?[lL]?[lL]?
  80 RGX_FP          ([0-9]+("."?)[0-9]*|"."[0-9]+)((e|E)("+"|-)?[0-9]+)?[fFlL]?
  81 RGX_WS          [\f\n\r\t\v ]
  82 RGX_STR         ([^"\\\n]|\\[^"\n]|\\\")*
  83 RGX_CHR         ([^'\\\n]|\\[^'\n]|\\')*
  84 RGX_INTERP      ^[\f\t\v ]*#!.*
  85 RGX_CTL         ^[\f\t\v ]*#
  86 
  87 %%
  88 
  89 %{
  90 
  91 /*
  92  * We insert a special prologue into yylex() itself: if the pcb contains a
  93  * context token, we return that prior to running the normal lexer.  This
  94  * allows libdtrace to force yacc into one of our three parsing contexts: D
  95  * expression (DT_CTX_DEXPR), D program (DT_CTX_DPROG) or D type (DT_CTX_DTYPE).
  96  * Once the token is returned, we clear it so this only happens once.
  97  */


 127 <S0>offsetof      return (DT_TOK_OFFSETOF);
 128 <S0>probe return (DT_KEY_PROBE);
 129 <S0>provider      return (DT_KEY_PROVIDER);
 130 <S0>register      return (DT_KEY_REGISTER);
 131 <S0>restrict      return (DT_KEY_RESTRICT);
 132 <S0>return        return (DT_KEY_RETURN);
 133 <S0>self  return (DT_KEY_SELF);
 134 <S0>short return (DT_KEY_SHORT);
 135 <S0>signed        return (DT_KEY_SIGNED);
 136 <S0>sizeof        return (DT_TOK_SIZEOF);
 137 <S0>static        return (DT_KEY_STATIC);
 138 <S0>string        return (DT_KEY_STRING);
 139 <S0>stringof      return (DT_TOK_STRINGOF);
 140 <S0>struct        return (DT_KEY_STRUCT);
 141 <S0>switch        return (DT_KEY_SWITCH);
 142 <S0>this  return (DT_KEY_THIS);
 143 <S0>translator    return (DT_KEY_XLATOR);
 144 <S0>typedef       return (DT_KEY_TYPEDEF);
 145 <S0>union return (DT_KEY_UNION);
 146 <S0>unsigned      return (DT_KEY_UNSIGNED);
 147 <S0>userland      return (DT_KEY_USERLAND);
 148 <S0>void  return (DT_KEY_VOID);
 149 <S0>volatile      return (DT_KEY_VOLATILE);
 150 <S0>while return (DT_KEY_WHILE);
 151 <S0>xlate return (DT_TOK_XLATE);
 152 
 153 <S2>auto  { yybegin(YYS_EXPR);    return (DT_KEY_AUTO); }
 154 <S2>char  { yybegin(YYS_EXPR);    return (DT_KEY_CHAR); }
 155 <S2>const { yybegin(YYS_EXPR);    return (DT_KEY_CONST); }
 156 <S2>counter       { yybegin(YYS_DEFINE);  return (DT_KEY_COUNTER); }
 157 <S2>double        { yybegin(YYS_EXPR);    return (DT_KEY_DOUBLE); }
 158 <S2>enum  { yybegin(YYS_EXPR);    return (DT_KEY_ENUM); }
 159 <S2>extern        { yybegin(YYS_EXPR);    return (DT_KEY_EXTERN); }
 160 <S2>float { yybegin(YYS_EXPR);    return (DT_KEY_FLOAT); }
 161 <S2>import        { yybegin(YYS_EXPR);    return (DT_KEY_IMPORT); }
 162 <S2>inline        { yybegin(YYS_DEFINE);  return (DT_KEY_INLINE); }
 163 <S2>int           { yybegin(YYS_EXPR);    return (DT_KEY_INT); }
 164 <S2>long  { yybegin(YYS_EXPR);    return (DT_KEY_LONG); }
 165 <S2>provider      { yybegin(YYS_DEFINE);  return (DT_KEY_PROVIDER); }
 166 <S2>register      { yybegin(YYS_EXPR);    return (DT_KEY_REGISTER); }
 167 <S2>restrict      { yybegin(YYS_EXPR);    return (DT_KEY_RESTRICT); }


 306                         dt_ident_t *idp = dt_idhash_lookup(
 307                             yypcb->pcb_hdl->dt_macros, yytext + 1);
 308 
 309                         if (idp == NULL) {
 310                                 xyerror(D_MACRO_UNDEF, "macro variable %s "
 311                                     "is not defined\n", yytext);
 312                         }
 313 
 314                         /*
 315                          * For the moment, all current macro variables are of
 316                          * type id_t (refer to dtrace_update() for details).
 317                          */
 318                         yylval.l_int = (intmax_t)(int)idp->di_id;
 319                         yyintprefix = 0;
 320                         yyintsuffix[0] = '\0';
 321                         yyintdecimal = 1;
 322 
 323                         return (DT_TOK_INT);
 324                 }
 325 
 326 <S0>{RGX_IDENT} |
 327 <S0>{RGX_MOD_IDENT}{RGX_IDENT} |
 328 <S0>{RGX_MOD_IDENT} {
 329                         return (id_or_type(yytext));
 330                 }
 331 
 332 <S0>{RGX_AGG}     {
 333                         if ((yylval.l_str = strdup(yytext)) == NULL)
 334                                 longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
 335                         return (DT_TOK_AGG);
 336                 }
 337 
 338 <S0>"@"           {
 339                         if ((yylval.l_str = strdup("@_")) == NULL)
 340                                 longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM);
 341                         return (DT_TOK_AGG);
 342                 }
 343 
 344 <S0>{RGX_INT}     |
 345 <S2>{RGX_INT}     |
 346 <S3>{RGX_INT}     {
 347                         char *p;
 348