LCOV - code coverage report
Current view: top level - mnt/wasteland/wcohen/systemtap_write/systemtap - elaborate.h (source / functions) Hit Total Coverage
Test: stap.info Lines: 21 28 75.0 %
Date: 2013-03-08 Functions: 19 33 57.6 %
Branches: 10 24 41.7 %

           Branch data     Line data    Source code
       1                 :            : // -*- C++ -*-
       2                 :            : // Copyright (C) 2005-2011 Red Hat Inc.
       3                 :            : //
       4                 :            : // This file is part of systemtap, and is free software.  You can
       5                 :            : // redistribute it and/or modify it under the terms of the GNU General
       6                 :            : // Public License (GPL); either version 2, or (at your option) any
       7                 :            : // later version.
       8                 :            : 
       9                 :            : #ifndef ELABORATE_H
      10                 :            : #define ELABORATE_H
      11                 :            : 
      12                 :            : #include "staptree.h"
      13                 :            : #include "parse.h"
      14                 :            : #include <string>
      15                 :            : #include <vector>
      16                 :            : //#include <iostream>
      17                 :            : #include <iosfwd>
      18                 :            : #include <sstream>
      19                 :            : #include <map>
      20                 :            : #include <list>
      21                 :            : 
      22                 :            : extern "C" {
      23                 :            : #include <elfutils/libdw.h>
      24                 :            : }
      25                 :            : 
      26                 :            : #include "privilege.h"
      27                 :            : 
      28                 :            : struct recursive_expansion_error : public semantic_error
      29                 :            : {
      30         [ -  + ]:          5 :   ~recursive_expansion_error () throw () {}
      31                 :          5 :   recursive_expansion_error (const std::string& msg, const token* t1=0):
      32                 :          5 :     semantic_error (msg, t1) {}
      33                 :            : 
      34                 :            :   recursive_expansion_error (const std::string& msg, const token* t1,
      35                 :            :                              const token* t2):
      36                 :            :     semantic_error (msg, t1, t2) {}
      37                 :            : };
      38                 :            : 
      39                 :            : // ------------------------------------------------------------------------
      40                 :            : 
      41                 :            : struct derived_probe;
      42                 :            : class match_node;
      43                 :            : 
      44         [ -  + ]:       1352 : struct symresolution_info: public traversing_visitor
      45                 :            : {
      46                 :            : protected:
      47                 :            :   systemtap_session& session;
      48                 :            : 
      49                 :            : public:
      50                 :            :   functiondecl* current_function;
      51                 :            :   derived_probe* current_probe;
      52                 :            :   symresolution_info (systemtap_session& s);
      53                 :            : 
      54                 :            :   vardecl* find_var (const std::string& name, int arity, const token *tok);
      55                 :            :   functiondecl* find_function (const std::string& name, unsigned arity);
      56                 :            : 
      57                 :            :   void visit_block (block *s);
      58                 :            :   void visit_symbol (symbol* e);
      59                 :            :   void visit_foreach_loop (foreach_loop* e);
      60                 :            :   void visit_arrayindex (arrayindex* e);
      61                 :            :   void visit_functioncall (functioncall* e);
      62                 :            :   void visit_delete_statement (delete_statement* s);
      63                 :            : };
      64                 :            : 
      65                 :            : 
      66 [ +  - ][ +  - ]:       1240 : struct typeresolution_info: public visitor
                 [ -  + ]
      67                 :            : {
      68                 :            :   typeresolution_info (systemtap_session& s);
      69                 :            :   systemtap_session& session;
      70                 :            :   unsigned num_newly_resolved;
      71                 :            :   unsigned num_still_unresolved;
      72                 :            :   bool assert_resolvability;
      73                 :            :   functiondecl* current_function;
      74                 :            :   derived_probe* current_probe;
      75                 :            :   std::vector <const token*> resolved_toks; // account for type mis-
      76                 :            :   std::vector <const token*> printed_toks;  // matches (BZ 9719)
      77                 :            : 
      78                 :            :   void check_arg_type (exp_type wanted, expression* arg);
      79                 :            :   void check_local (vardecl* v);
      80                 :            :   void mismatch (const token* tok, exp_type t1, exp_type t2);
      81                 :            :   void unresolved (const token* tok);
      82                 :            :   void resolved (const token* tok, exp_type t);
      83                 :            :   void invalid (const token* tok, exp_type t);
      84                 :            : 
      85                 :            :   exp_type t; // implicit parameter for nested visit call; may clobber
      86                 :            :               // Upon entry to one of the visit_* calls, the incoming
      87                 :            :               // `t' value is the type inferred for that node from 
      88                 :            :               // context.  It may match or conflict with the node's 
      89                 :            :               // preexisting type, or it may be unknown.
      90                 :            : 
      91                 :            :   void visit_block (block* s);
      92                 :            :   void visit_try_block (try_block* s);
      93                 :            :   void visit_embeddedcode (embeddedcode* s);
      94                 :            :   void visit_null_statement (null_statement* s);
      95                 :            :   void visit_expr_statement (expr_statement* s);
      96                 :            :   void visit_if_statement (if_statement* s);
      97                 :            :   void visit_for_loop (for_loop* s);
      98                 :            :   void visit_foreach_loop (foreach_loop* s);
      99                 :            :   void visit_return_statement (return_statement* s);
     100                 :            :   void visit_delete_statement (delete_statement* s);
     101                 :            :   void visit_next_statement (next_statement* s);
     102                 :            :   void visit_break_statement (break_statement* s);
     103                 :            :   void visit_continue_statement (continue_statement* s);
     104                 :            :   void visit_literal_string (literal_string* e);
     105                 :            :   void visit_literal_number (literal_number* e);
     106                 :            :   void visit_embedded_expr (embedded_expr* e);
     107                 :            :   void visit_binary_expression (binary_expression* e);
     108                 :            :   void visit_unary_expression (unary_expression* e);
     109                 :            :   void visit_pre_crement (pre_crement* e);
     110                 :            :   void visit_post_crement (post_crement* e);
     111                 :            :   void visit_logical_or_expr (logical_or_expr* e);
     112                 :            :   void visit_logical_and_expr (logical_and_expr* e);
     113                 :            :   void visit_array_in (array_in* e);
     114                 :            :   void visit_regex_query (regex_query* e);
     115                 :            :   void visit_comparison (comparison* e);
     116                 :            :   void visit_concatenation (concatenation* e);
     117                 :            :   void visit_ternary_expression (ternary_expression* e);
     118                 :            :   void visit_assignment (assignment* e);
     119                 :            :   void visit_symbol (symbol* e);
     120                 :            :   void visit_target_symbol (target_symbol* e);
     121                 :            :   void visit_arrayindex (arrayindex* e);
     122                 :            :   void visit_functioncall (functioncall* e);
     123                 :            :   void visit_print_format (print_format* e);
     124                 :            :   void visit_stat_op (stat_op* e);
     125                 :            :   void visit_hist_op (hist_op* e);
     126                 :            :   void visit_cast_op (cast_op* e);
     127                 :            :   void visit_defined_op (defined_op* e);
     128                 :            :   void visit_entry_op (entry_op* e);
     129                 :            :   void visit_perf_op (perf_op* e);
     130                 :            : };
     131                 :            : 
     132                 :            : 
     133                 :            : // ------------------------------------------------------------------------
     134                 :            : 
     135                 :            : 
     136                 :            : // A derived_probe is a probe that has been elaborated by
     137                 :            : // binding to a matching provider.  The locations std::vector
     138                 :            : // may be smaller or larger than the base probe, since a
     139                 :            : // provider may transform it.
     140                 :            : 
     141                 :            : class translator_output;
     142                 :            : struct derived_probe_group;
     143                 :            : 
     144                 :            : struct derived_probe: public probe
     145                 :            : {
     146                 :            :   derived_probe (probe* b, probe_point* l, bool rewrite_loc=false);
     147                 :            :   probe* base; // the original parsed probe
     148                 :            :   probe_point* base_pp; // the probe_point that led to this derivation
     149                 :          0 :   virtual const probe* basest () const { return base->basest(); }
     150         [ +  + ]:      54400 :   virtual const probe* almost_basest () const { return base->almost_basest() ?: this; }
     151 [ +  - ][ -  + ]:          9 :   virtual ~derived_probe () {}
     152                 :            :   virtual void join_group (systemtap_session& s) = 0;
     153                 :            :   virtual probe_point* sole_location () const;
     154                 :            :   virtual probe_point* script_location () const;
     155                 :            :   virtual void printsig (std::ostream &o) const;
     156                 :            :   // return arguments of probe if there
     157                 :          0 :   virtual void getargs (std::list<std::string> &) const {}
     158                 :            :   void printsig_nested (std::ostream &o) const;
     159                 :            :   virtual void collect_derivation_chain (std::vector<probe*> &probes_list);
     160                 :            :   virtual void collect_derivation_pp_chain (std::vector<probe_point*> &pp_list);
     161                 :            :   std::string derived_locations ();
     162                 :            : 
     163                 :      28622 :   virtual void print_dupe_stamp(std::ostream&) {}
     164                 :            :   // To aid duplication elimination, print a stamp which uniquely identifies
     165                 :            :   // the code that will be added to the probe body.  (Doesn't need to be the
     166                 :            :   // actual code...)
     167                 :            : 
     168                 :       8570 :   virtual void initialize_probe_context_vars (translator_output*) {}
     169                 :            :   // From within unparser::emit_probe, initialized any extra variables
     170                 :            :   // in this probe's context locals.
     171                 :            : 
     172                 :       2395 :   virtual void emit_probe_local_init (systemtap_session& s, translator_output*) {}
     173                 :            :   // From within unparser::emit_probe, emit any extra processing block
     174                 :            :   // for this probe.
     175                 :            : 
     176                 :            :   virtual void emit_privilege_assertion (translator_output*);
     177                 :            :   // From within unparser::emit_probe, emit any unprivileged mode
     178                 :            :   // checking for this probe.
     179                 :            : 
     180                 :            : public:
     181                 :            :   static void emit_common_header (translator_output* o);
     182                 :            :   // from c_unparser::emit_common_header
     183                 :            :   // XXX: probably can move this stuff to a probe_group::emit_module_decls
     184                 :            : 
     185                 :            :   static void emit_process_owner_assertion (translator_output*);
     186                 :            :   // From within unparser::emit_probe, emit a check that the current
     187                 :            :   // process belongs to the user.
     188                 :            : 
     189                 :            :   static void print_dupe_stamp_unprivileged(std::ostream& o);
     190                 :            :   static void print_dupe_stamp_unprivileged_process_owner(std::ostream& o);
     191                 :            : 
     192                 :      69207 :   virtual bool needs_global_locks () { return true; }
     193                 :            :   // by default, probes need locks around global variables
     194                 :            : 
     195                 :            :   // Location of semaphores to activate sdt probes
     196                 :            :   Dwarf_Addr sdt_semaphore_addr;
     197                 :            : 
     198                 :            :   // perf.counter probes that this probe references
     199                 :            :   std::set<derived_probe*> perf_counter_refs;
     200                 :            : 
     201                 :            :   // index into session.probes[], set and used during translation
     202                 :            :   unsigned session_index;
     203                 :            : };
     204                 :            : 
     205                 :            : // ------------------------------------------------------------------------
     206                 :            : 
     207                 :            : struct unparser;
     208                 :            : 
     209                 :            : // Various derived classes derived_probe_group manage the
     210                 :            : // registration/invocation/unregistration of sibling probes.
     211                 :       1602 : struct derived_probe_group
     212                 :            : {
     213         [ #  # ]:          0 :   virtual ~derived_probe_group () {}
     214                 :            : 
     215                 :            :   virtual void emit_module_decls (systemtap_session& s) = 0;
     216                 :            :   // The _decls-generated code may assume that declarations such as
     217                 :            :   // the context, embedded-C code, function and probe handler bodies
     218                 :            :   // are all already generated.  That is, _decls is called near the
     219                 :            :   // end of the code generation process.  It should minimize the
     220                 :            :   // number of separate variables (and to a lesser extent, their
     221                 :            :   // size).
     222                 :            : 
     223                 :            :   virtual void emit_module_init (systemtap_session& s) = 0;
     224                 :            :   // The _init-generated code may assume that it is called only once.
     225                 :            :   // If that code fails at run time, it must set rc=1 and roll back
     226                 :            :   // any partial initializations, for its _exit friend will NOT be
     227                 :            :   // invoked.  The generated code may use pre-declared "int i, j;"
     228                 :            :   // and set "const char* probe_point;".
     229                 :            : 
     230                 :        881 :   virtual void emit_module_post_init (systemtap_session& s) {}
     231                 :            :   // The emit_module_post_init() code is called once session_state is
     232                 :            :   // set to running.
     233                 :            : 
     234                 :        705 :   virtual void emit_module_refresh (systemtap_session& s) {}
     235                 :            :   // The _refresh-generated code may be called multiple times during
     236                 :            :   // a session run, bracketed by _init and _exit calls.
     237                 :            :   // Upon failure, it must set enough state so that
     238                 :            :   // a subsequent _exit call will clean up everything.
     239                 :            :   // The generated code may use pre-declared "int i, j;".
     240                 :            : 
     241                 :            :   virtual void emit_module_exit (systemtap_session& s) = 0;
     242                 :            :   // The _exit-generated code may assume that it is executed exactly
     243                 :            :   // zero times (if the _init-generated code failed) or once.  (_exit
     244                 :            :   // itself may be called a few times, to generate the code in a few
     245                 :            :   // different places in the probe module.)
     246                 :            :   // The generated code may use pre-declared "int i, j;".
     247                 :            : };
     248                 :            : 
     249                 :            : 
     250                 :            : // ------------------------------------------------------------------------
     251                 :            : 
     252                 :            : typedef std::map<std::string, literal*> literal_map_t;
     253                 :            : 
     254                 :    2493500 : struct derived_probe_builder
     255                 :            : {
     256                 :            :   virtual void build(systemtap_session & sess,
     257                 :            :                      probe* base,
     258                 :            :                      probe_point* location,
     259                 :            :                      literal_map_t const & parameters,
     260                 :            :                      std::vector<derived_probe*> & finished_results) = 0;
     261                 :            :   virtual void build_with_suffix(systemtap_session & sess,
     262                 :            :                                  probe * use,
     263                 :            :                                  probe_point * location,
     264                 :            :                                  std::map<std::string, literal *>
     265                 :            :                                    const & parameters,
     266                 :            :                                  std::vector<derived_probe *>
     267                 :            :                                    & finished_results,
     268                 :            :                                  std::vector<probe_point::component *>
     269                 :            :                                    const & suffix);
     270         [ #  # ]:          0 :   virtual ~derived_probe_builder() {}
     271                 :    2549528 :   virtual void build_no_more (systemtap_session &) {}
     272                 :          0 :   virtual bool is_alias () const { return false; }
     273                 :            : 
     274                 :            :   static bool has_null_param (literal_map_t const & parameters,
     275                 :            :                               const std::string& key);
     276                 :            :   static bool get_param (literal_map_t const & parameters,
     277                 :            :                          const std::string& key, std::string& value);
     278                 :            :   static bool get_param (literal_map_t const & parameters,
     279                 :            :                          const std::string& key, int64_t& value);
     280                 :            : };
     281                 :            : 
     282                 :            : 
     283                 :            : struct
     284                 :   27296270 : match_key
     285                 :            : {
     286                 :            :   std::string name;
     287                 :            :   bool have_parameter;
     288                 :            :   exp_type parameter_type;
     289                 :            : 
     290                 :            :   match_key(std::string const & n);
     291                 :            :   match_key(probe_point::component const & c);
     292                 :            : 
     293                 :            :   match_key & with_number();
     294                 :            :   match_key & with_string();
     295                 :            :   std::string str() const;
     296                 :            :   bool operator<(match_key const & other) const;
     297                 :            :   bool globmatch(match_key const & other) const;
     298                 :            : };
     299                 :            : 
     300                 :            : 
     301                 :            : class
     302         [ +  - ]:       2413 : match_node
     303                 :            : {
     304                 :            :   typedef std::map<match_key, match_node*> sub_map_t;
     305                 :            :   typedef std::map<match_key, match_node*>::iterator sub_map_iterator_t;
     306                 :            :   sub_map_t sub;
     307                 :            :   std::vector<derived_probe_builder*> ends;
     308                 :            : 
     309                 :            :  public:
     310                 :            :   match_node();
     311                 :            : 
     312                 :            :   void find_and_build (systemtap_session& s,
     313                 :            :                        probe* p, probe_point *loc, unsigned pos,
     314                 :            :                        std::vector<derived_probe *>& results);
     315                 :            :   void try_suffix_expansion (systemtap_session& s,
     316                 :            :                              probe *p, probe_point *loc, unsigned pos,
     317                 :            :                              std::vector<derived_probe *>& results);
     318                 :            :   void build_no_more (systemtap_session &s);
     319                 :            :   void dump (systemtap_session &s, const std::string &name = "");
     320                 :            : 
     321                 :            :   match_node* bind(match_key const & k);
     322                 :            :   match_node* bind(std::string const & k);
     323                 :            :   match_node* bind_str(std::string const & k);
     324                 :            :   match_node* bind_num(std::string const & k);
     325                 :            :   match_node* bind_privilege(privilege_t p = privilege_t (pr_stapdev | pr_stapsys));
     326                 :            :   void bind(derived_probe_builder* e);
     327                 :            : 
     328                 :            : private:
     329                 :            :   privilege_t privilege;
     330                 :            : };
     331                 :            : 
     332                 :            : // ------------------------------------------------------------------------
     333                 :            : 
     334                 :            : struct
     335         [ #  # ]:          0 : alias_expansion_builder
     336                 :            :   : public derived_probe_builder
     337                 :            : {
     338                 :            :   probe_alias * alias;
     339                 :            : 
     340                 :    2453306 :   alias_expansion_builder(probe_alias * a)
     341                 :    2453306 :     : alias(a)
     342                 :    2453306 :   {}
     343                 :            : 
     344                 :            :   virtual void build(systemtap_session & sess,
     345                 :            :                      probe * use,
     346                 :            :                      probe_point * location,
     347                 :            :                      std::map<std::string, literal *> const &,
     348                 :            :                      std::vector<derived_probe *> & finished_results);
     349                 :            :   virtual void build_with_suffix(systemtap_session & sess,
     350                 :            :                                  probe * use,
     351                 :            :                                  probe_point * location,
     352                 :            :                                  std::map<std::string, literal *>
     353                 :            :                                    const &,
     354                 :            :                                  std::vector<derived_probe *>
     355                 :            :                                    & finished_results,
     356                 :            :                                  std::vector<probe_point::component *>
     357                 :            :                                    const & suffix);
     358                 :          0 :   virtual bool is_alias () const { return true; }
     359                 :            : 
     360                 :            :   bool checkForRecursiveExpansion (probe *use);
     361                 :            : };
     362                 :            : 
     363                 :            : // ------------------------------------------------------------------------
     364                 :            : 
     365                 :            : /* struct systemtap_session moved to session.h */
     366                 :            : 
     367                 :            : int semantic_pass (systemtap_session& s);
     368                 :            : void derive_probes (systemtap_session& s,
     369                 :            :                     probe *p, std::vector<derived_probe*>& dps,
     370                 :            :                     bool optional = false, bool rethrow_errors = false);
     371                 :            : 
     372                 :            : // A helper we use here and in translate, for pulling symbols out of lvalue
     373                 :            : // expressions.
     374                 :            : symbol * get_symbol_within_expression (expression *e);
     375                 :            : 
     376                 :            : 
     377                 :            : struct unparser;
     378                 :            : 
     379                 :            : 
     380                 :            : #endif // ELABORATE_H
     381                 :            : 
     382                 :            : /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */

Generated by: LCOV version 1.9