LTP GCOV extension - code coverage report
Current view: directory - src - tapsets.cxx
Test: stap.info
Date: 2008-03-12 Instrumented lines: 2698
Code covered: 77.2 % Executed lines: 2083

       1                 : // tapset resolution
       2                 : // Copyright (C) 2005-2008 Red Hat Inc.
       3                 : // Copyright (C) 2005-2007 Intel Corporation.
       4                 : //
       5                 : // This file is part of systemtap, and is free software.  You can
       6                 : // redistribute it and/or modify it under the terms of the GNU General
       7                 : // Public License (GPL); either version 2, or (at your option) any
       8                 : // later version.
       9                 : 
      10                 : #include "config.h"
      11                 : #include "staptree.h"
      12                 : #include "elaborate.h"
      13                 : #include "tapsets.h"
      14                 : #include "translate.h"
      15                 : #include "session.h"
      16                 : #include "util.h"
      17                 : 
      18                 : #include <cstdlib>
      19                 : #include <algorithm>
      20                 : #include <deque>
      21                 : #include <iostream>
      22                 : #include <map>
      23                 : #include <set>
      24                 : #include <sstream>
      25                 : #include <stdexcept>
      26                 : #include <vector>
      27                 : #include <cstdarg>
      28                 : #include <cassert>
      29                 : #include <iomanip>
      30                 : #include <cerrno>
      31                 : 
      32                 : extern "C" {
      33                 : #include <fcntl.h>
      34                 : #include <elfutils/libdwfl.h>
      35                 : #include <elfutils/libdw.h>
      36                 : #include <elfutils/libebl.h>
      37                 : #include <dwarf.h>
      38                 : #include <elf.h>
      39                 : #include <obstack.h>
      40                 : #include <regex.h>
      41                 : #include <glob.h>
      42                 : #include <fnmatch.h>
      43                 : 
      44                 : #include "loc2c.h"
      45                 : #define __STDC_FORMAT_MACROS
      46                 : #include <inttypes.h>
      47                 : }
      48                 : 
      49                 : 
      50                 : #ifdef PERFMON
      51                 : #include <perfmon/pfmlib.h>
      52                 : #include <perfmon/perfmon.h>
      53                 : #endif
      54                 : 
      55                 : using namespace std;
      56                 : 
      57                 : 
      58                 : // ------------------------------------------------------------------------
      59                 : // Generic derived_probe_group: contains an ordinary vector of the
      60                 : // given type.  It provides only the enrollment function.
      61                 : 
      62                 : template <class DP> struct generic_dpg: public derived_probe_group
      63               0 : {
      64                 : protected:
      65                 :   vector <DP*> probes;
      66                 : public:
      67             400 :   generic_dpg () {}
      68            1391 :   void enroll (DP* probe) { probes.push_back (probe); }
      69                 : };
      70                 : 
      71                 : 
      72                 : 
      73                 : // ------------------------------------------------------------------------
      74                 : // begin/end/error probes are run right during registration / deregistration
      75                 : // ------------------------------------------------------------------------
      76                 : 
      77                 : enum be_t { BEGIN, END, ERROR };
      78                 : 
      79                 : struct be_derived_probe: public derived_probe
      80               0 : {
      81                 :   be_t type;
      82                 :   int64_t priority;
      83                 : 
      84            1301 :   be_derived_probe (probe* p, probe_point* l, be_t t, int64_t pr):
      85            1301 :     derived_probe (p, l), type (t), priority (pr) {}
      86                 : 
      87                 :   void join_group (systemtap_session& s);
      88                 : 
      89                 :   static inline bool comp(be_derived_probe const *a,
      90            4569 :                           be_derived_probe const *b)
      91                 :   {
      92                 :     // This allows the BEGIN/END/ERROR probes to intermingle.
      93                 :     // But that's OK - they're always treversed with a nested
      94                 :     // "if (type==FOO)" conditional.
      95            4569 :     return a->priority < b->priority;
      96                 :   }
      97                 : 
      98            3678 :   bool needs_global_locks () { return false; }
      99                 :   // begin/end probes don't need locks around global variables, since
     100                 :   // they aren't run concurrently with any other probes
     101                 : };
     102                 : 
     103                 : 
     104                 : struct be_derived_probe_group: public generic_dpg<be_derived_probe>
     105             357 : {
     106                 : public:
     107                 :   void emit_module_decls (systemtap_session& s);
     108                 :   void emit_module_init (systemtap_session& s);
     109                 :   void emit_module_exit (systemtap_session& s);
     110                 : };
     111                 : 
     112                 : 
     113                 : struct be_builder: public derived_probe_builder
     114               0 : {
     115                 :   be_t type;
     116                 : 
     117            2910 :   be_builder(be_t t) : type(t) {}
     118                 : 
     119                 :   virtual void build(systemtap_session &,
     120                 :                      probe * base,
     121                 :                      probe_point * location,
     122                 :                      std::map<std::string, literal *> const & parameters,
     123            1301 :                      vector<derived_probe *> & finished_results)
     124                 :   {
     125                 :     int64_t priority;
     126            1301 :     if ((type == BEGIN && !get_param(parameters, "begin", priority)) ||
     127                 :         (type == END && !get_param(parameters, "end", priority)) ||
     128                 :         (type == ERROR && !get_param(parameters, "error", priority)))
     129            1258 :       priority = 0;
     130                 :     finished_results.push_back(
     131            1301 :         new be_derived_probe(base, location, type, priority));
     132            1301 :   }
     133                 : };
     134                 : 
     135                 : 
     136                 : void
     137            1301 : be_derived_probe::join_group (systemtap_session& s)
     138                 : {
     139            1301 :   if (! s.be_derived_probes)
     140             357 :     s.be_derived_probes = new be_derived_probe_group ();
     141            1301 :   s.be_derived_probes->enroll (this);
     142            1301 : }
     143                 : 
     144                 : 
     145                 : // ------------------------------------------------------------------------
     146                 : void
     147                 : common_probe_entryfn_prologue (translator_output* o, string statestr,
     148                 :                                bool overload_processing = true,
     149             943 :                                bool interruptible = false)
     150                 : {
     151             943 :   o->newline() << "struct context* __restrict__ c;";
     152             943 :   if (! interruptible)
     153             244 :     o->newline() << "unsigned long flags;";
     154                 : 
     155             943 :   if (overload_processing)
     156             244 :     o->newline() << "#if defined(STP_TIMING) || defined(STP_OVERLOAD)";
     157                 :   else
     158             699 :     o->newline() << "#ifdef STP_TIMING";
     159             943 :   o->newline() << "cycles_t cycles_atstart = get_cycles ();";
     160             943 :   o->newline() << "#endif";
     161                 : 
     162                 : #if 0 /* XXX: PERFMON */
     163                 :   o->newline() << "static struct pfarg_ctx _pfm_context;";
     164                 :   o->newline() << "static void *_pfm_desc;";
     165                 :   o->newline() << "static struct pfarg_pmc *_pfm_pmc_x;";
     166                 :   o->newline() << "static int _pfm_num_pmc_x;";
     167                 :   o->newline() << "static struct pfarg_pmd *_pfm_pmd_x;";
     168                 :   o->newline() << "static int _pfm_num_pmd_x;";
     169                 : #endif
     170                 : 
     171             943 :   if (! interruptible)
     172             244 :     o->newline() << "local_irq_save (flags);";
     173                 :   else
     174             699 :     o->newline() << "preempt_disable ();";
     175                 : 
     176                 :   // Check for enough free enough stack space
     177             943 :   o->newline() << "if (unlikely ((((unsigned long) (& c)) & (THREAD_SIZE-1))"; // free space
     178             943 :   o->newline(1) << "< (MINSTACKSPACE + sizeof (struct thread_info)))) {"; // needed space
     179                 :   // XXX: may need porting to platforms where task_struct is not at bottom of kernel stack
     180                 :   // NB: see also CONFIG_DEBUG_STACKOVERFLOW
     181             943 :   o->newline() << "if (unlikely (atomic_inc_return (& skipped_count) > MAXSKIPPED)) {";
     182             943 :   o->newline(1) << "atomic_set (& session_state, STAP_SESSION_ERROR);";
     183             943 :   o->newline() << "_stp_exit ();";
     184             943 :   o->newline(-1) << "}";
     185             943 :   o->newline() << "goto probe_epilogue;";
     186             943 :   o->newline(-1) << "}";
     187                 : 
     188             943 :   o->newline() << "if (atomic_read (&session_state) != " << statestr << ")";
     189             943 :   o->newline(1) << "goto probe_epilogue;";
     190             943 :   o->indent(-1);
     191                 : 
     192             943 :   o->newline() << "c = per_cpu_ptr (contexts, smp_processor_id());";
     193             943 :   o->newline() << "if (unlikely (atomic_inc_return (&c->busy) != 1)) {";
     194             943 :   o->newline(1) << "if (atomic_inc_return (& skipped_count) > MAXSKIPPED) {";
     195             943 :   o->newline(1) << "atomic_set (& session_state, STAP_SESSION_ERROR);";
     196                 :   // NB: We don't assume that we can safely call stp_error etc. in such
     197                 :   // a reentrant context.  But this is OK:
     198             943 :   o->newline() << "_stp_exit ();";
     199             943 :   o->newline(-1) << "}";
     200             943 :   o->newline() << "atomic_dec (& c->busy);";
     201             943 :   o->newline() << "goto probe_epilogue;";
     202             943 :   o->newline(-1) << "}";
     203             943 :   o->newline();
     204             943 :   o->newline() << "c->last_error = 0;";
     205             943 :   o->newline() << "c->nesting = 0;";
     206             943 :   o->newline() << "c->regs = 0;";
     207             943 :   o->newline() << "c->pi = 0;";
     208             943 :   o->newline() << "c->probe_point = 0;";
     209             943 :   if (! interruptible)
     210             244 :     o->newline() << "c->actionremaining = MAXACTION;";
     211                 :   else
     212             699 :     o->newline() << "c->actionremaining = MAXACTION_INTERRUPTIBLE;";
     213             943 :   o->newline() << "#ifdef STP_TIMING";
     214             943 :   o->newline() << "c->statp = 0;";
     215             943 :   o->newline() << "#endif";
     216             943 : }
     217                 : 
     218                 : 
     219                 : void
     220                 : common_probe_entryfn_epilogue (translator_output* o,
     221                 :                                bool overload_processing = true,
     222             943 :                                bool interruptible = false)
     223                 : {
     224             943 :   if (overload_processing)
     225             244 :     o->newline() << "#if defined(STP_TIMING) || defined(STP_OVERLOAD)";
     226                 :   else
     227             699 :     o->newline() << "#ifdef STP_TIMING";
     228             943 :   o->newline() << "{";
     229             943 :   o->newline(1) << "cycles_t cycles_atend = get_cycles ();";
     230                 :   // NB: we truncate cycles counts to 32 bits.  Perhaps it should be
     231                 :   // fewer, if the hardware counter rolls over really quickly.  We
     232                 :   // handle 32-bit wraparound here.
     233             943 :   o->newline() << "int32_t cycles_elapsed = ((int32_t)cycles_atend > (int32_t)cycles_atstart)";
     234             943 :   o->newline(1) << "? ((int32_t)cycles_atend - (int32_t)cycles_atstart)";
     235             943 :   o->newline() << ": (~(int32_t)0) - (int32_t)cycles_atstart + (int32_t)cycles_atend + 1;";
     236             943 :   o->indent(-1);
     237                 : 
     238             943 :   o->newline() << "#ifdef STP_TIMING";
     239             943 :   o->newline() << "if (likely (c->statp)) _stp_stat_add(*c->statp, cycles_elapsed);";
     240             943 :   o->newline() << "#endif";
     241                 : 
     242             943 :   if (overload_processing)
     243                 :     {
     244             244 :       o->newline() << "#ifdef STP_OVERLOAD";
     245             244 :       o->newline() << "{";
     246                 :       // If the cycle count has wrapped (cycles_atend > cycles_base),
     247                 :       // let's go ahead and pretend the interval has been reached.
     248                 :       // This should reset cycles_base and cycles_sum.
     249             244 :       o->newline(1) << "cycles_t interval = (cycles_atend > c->cycles_base)";
     250             244 :       o->newline(1) << "? (cycles_atend - c->cycles_base)";
     251             244 :       o->newline() << ": (STP_OVERLOAD_INTERVAL + 1);";
     252             244 :       o->newline(-1) << "c->cycles_sum += cycles_elapsed;";
     253                 : 
     254                 :       // If we've spent more than STP_OVERLOAD_THRESHOLD cycles in a
     255                 :       // probe during the last STP_OVERLOAD_INTERVAL cycles, the probe
     256                 :       // has overloaded the system and we need to quit.
     257             244 :       o->newline() << "if (interval > STP_OVERLOAD_INTERVAL) {";
     258             244 :       o->newline(1) << "if (c->cycles_sum > STP_OVERLOAD_THRESHOLD) {";
     259             244 :       o->newline(1) << "_stp_error (\"probe overhead exceeded threshold\");";
     260             244 :       o->newline() << "atomic_set (&session_state, STAP_SESSION_ERROR);";
     261             244 :       o->newline() << "atomic_inc (&error_count);";
     262             244 :       o->newline(-1) << "}";
     263                 : 
     264             244 :       o->newline() << "c->cycles_base = cycles_atend;";
     265             244 :       o->newline() << "c->cycles_sum = 0;";
     266             244 :       o->newline(-1) << "}";
     267             244 :       o->newline(-1) << "}";
     268             244 :       o->newline() << "#endif";
     269                 :     }
     270                 : 
     271             943 :   o->newline(-1) << "}";
     272             943 :   o->newline() << "#endif";
     273                 : 
     274             943 :   o->newline() << "if (unlikely (c->last_error && c->last_error[0])) {";
     275             943 :   o->newline(1) << "if (c->last_stmt != NULL)";
     276             943 :   o->newline(1) << "_stp_softerror (\"%s near %s\", c->last_error, c->last_stmt);";
     277             943 :   o->newline(-1) << "else";
     278             943 :   o->newline(1) << "_stp_softerror (\"%s\", c->last_error);";
     279             943 :   o->indent(-1);
     280             943 :   o->newline() << "atomic_inc (& error_count);";
     281             943 :   o->newline() << "if (atomic_read (& error_count) > MAXERRORS) {";
     282             943 :   o->newline(1) << "atomic_set (& session_state, STAP_SESSION_ERROR);";
     283             943 :   o->newline() << "_stp_exit ();";
     284             943 :   o->newline(-1) << "}";
     285             943 :   o->newline(-1) << "}";
     286             943 :   o->newline() << "atomic_dec (&c->busy);";
     287                 : 
     288             943 :   o->newline(-1) << "probe_epilogue:"; // context is free
     289             943 :   o->indent(1);
     290                 : 
     291             943 :   if (! interruptible)
     292             244 :     o->newline() << "local_irq_restore (flags);";
     293                 :   else
     294             699 :     o->newline() << "preempt_enable_no_resched ();";
     295             943 : }
     296                 : 
     297                 : 
     298                 : // ------------------------------------------------------------------------
     299                 : 
     300                 : void
     301             233 : be_derived_probe_group::emit_module_decls (systemtap_session& s)
     302                 : {
     303             233 :   if (probes.empty()) return;
     304                 : 
     305             233 :   s.op->newline() << "/* ---- begin/end probes ---- */";
     306             233 :   s.op->newline() << "void enter_begin_probe (void (*fn)(struct context*), const char* pp) {";
     307             233 :   s.op->indent(1);
     308             233 :   common_probe_entryfn_prologue (s.op, "STAP_SESSION_STARTING", false, true);
     309             233 :   s.op->newline() << "c->probe_point = pp;";
     310             233 :   s.op->newline() << "(*fn) (c);";
     311             233 :   common_probe_entryfn_epilogue (s.op, false, true);
     312             233 :   s.op->newline(-1) << "}";
     313                 : 
     314             233 :   s.op->newline() << "void enter_end_probe (void (*fn)(struct context*), const char* pp) {";
     315             233 :   s.op->indent(1);
     316             466 :   common_probe_entryfn_prologue (s.op, "STAP_SESSION_STOPPING", false, true);
     317             233 :   s.op->newline() << "c->probe_point = pp;";
     318             233 :   s.op->newline() << "(*fn) (c);";
     319             233 :   common_probe_entryfn_epilogue (s.op, false, true);
     320             233 :   s.op->newline(-1) << "}";
     321                 : 
     322             233 :   s.op->newline() << "void enter_error_probe (void (*fn)(struct context*), const char* pp) {";
     323             233 :   s.op->indent(1);
     324             466 :   common_probe_entryfn_prologue (s.op, "STAP_SESSION_ERROR", false, true);
     325             233 :   s.op->newline() << "c->probe_point = pp;";
     326             233 :   s.op->newline() << "(*fn) (c);";
     327             233 :   common_probe_entryfn_epilogue (s.op, false, true);
     328             233 :   s.op->newline(-1) << "}";
     329                 : 
     330             233 :   s.op->newline() << "struct stap_be_probe {";
     331             233 :   s.op->newline(1) << "void (*ph)(struct context*);";
     332             233 :   s.op->newline() << "const char* pp;";
     333             233 :   s.op->newline() << "int type;";
     334             233 :   s.op->newline(-1) << "} stap_be_probes[] = {";
     335             233 :   s.op->indent(1);
     336                 : 
     337                 :   // NB: We emit the table in sorted order here, so we don't have to
     338                 :   // store the priority numbers as integers and sort at run time.
     339                 : 
     340             233 :   sort(probes.begin(), probes.end(), be_derived_probe::comp);
     341                 : 
     342            2380 :   for (unsigned i=0; i < probes.size(); i++)
     343                 :     {
     344             957 :       s.op->newline () << "{";
     345                 :       s.op->line() << " .pp="
     346             957 :                    << lex_cast_qstring (*probes[i]->sole_location()) << ",";
     347             957 :       s.op->line() << " .ph=&" << probes[i]->name << ",";
     348             957 :       s.op->line() << " .type=" << probes[i]->type;
     349             957 :       s.op->line() << " },";
     350                 :     }
     351             233 :   s.op->newline(-1) << "};";
     352                 : }
     353                 : 
     354                 : void
     355             233 : be_derived_probe_group::emit_module_init (systemtap_session& s)
     356                 : {
     357             233 :   if (probes.empty()) return;
     358                 : 
     359             233 :   s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
     360             233 :   s.op->newline(1) << "struct stap_be_probe* stp = & stap_be_probes [i];";
     361             233 :   s.op->newline() << "if (stp->type != " << BEGIN << ") continue;";
     362             233 :   s.op->newline() << "enter_begin_probe (stp->ph, stp->pp);";
     363             233 :   s.op->newline() << "/* rc = 0; */";
     364                 :   // NB: begin probes that cause errors do not constitute registration
     365                 :   // failures.  An error message will probably get printed and if
     366                 :   // MAXERRORS was left at 1, we'll get an stp_exit.  The
     367                 :   // error-handling probes will be run during the ordinary
     368                 :   // unregistration phase.
     369             233 :   s.op->newline(-1) << "}";
     370                 : }
     371                 : 
     372                 : void
     373             323 : be_derived_probe_group::emit_module_exit (systemtap_session& s)
     374                 : {
     375             323 :   if (probes.empty()) return;
     376                 : 
     377             323 :   s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
     378             323 :   s.op->newline(1) << "struct stap_be_probe* stp = & stap_be_probes [i];";
     379             323 :   s.op->newline() << "if (stp->type != " << END << ") continue;";
     380             323 :   s.op->newline() << "enter_end_probe (stp->ph, stp->pp);";
     381             323 :   s.op->newline(-1) << "}";
     382                 : 
     383             323 :   s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
     384             323 :   s.op->newline(1) << "struct stap_be_probe* stp = & stap_be_probes [i];";
     385             323 :   s.op->newline() << "if (stp->type != " << ERROR << ") continue;";
     386             323 :   s.op->newline() << "enter_error_probe (stp->ph, stp->pp);";
     387             323 :   s.op->newline(-1) << "}";
     388                 : }
     389                 : 
     390                 : 
     391                 : 
     392                 : // ------------------------------------------------------------------------
     393                 : // never probes are never run
     394                 : // ------------------------------------------------------------------------
     395                 : 
     396                 : struct never_derived_probe: public derived_probe
     397               0 : {
     398                 :   never_derived_probe (probe* p): derived_probe (p) {}
     399               5 :   never_derived_probe (probe* p, probe_point* l): derived_probe (p, l) {}
     400               5 :   void join_group (systemtap_session&) { /* thus no probe_group */ }
     401                 : };
     402                 : 
     403                 : 
     404                 : struct never_builder: public derived_probe_builder
     405               0 : {
     406             485 :   never_builder() {}
     407                 :   virtual void build(systemtap_session &,
     408                 :                      probe * base,
     409                 :                      probe_point * location,
     410                 :                      std::map<std::string, literal *> const &,
     411               5 :                      vector<derived_probe *> & finished_results)
     412                 :   {
     413               5 :     finished_results.push_back(new never_derived_probe(base, location));
     414               5 :   }
     415                 : };
     416                 : 
     417                 : 
     418                 : 
     419                 : // ------------------------------------------------------------------------
     420                 : //  Dwarf derived probes.  "We apologize for the inconvience."
     421                 : // ------------------------------------------------------------------------
     422                 : 
     423            2188 : static string TOK_KERNEL("kernel");
     424            3282 : static string TOK_MODULE("module");
     425            3282 : static string TOK_FUNCTION("function");
     426            3282 : static string TOK_INLINE("inline");
     427            3282 : static string TOK_CALL("call");
     428            3282 : static string TOK_RETURN("return");
     429            3282 : static string TOK_MAXACTIVE("maxactive");
     430            3282 : static string TOK_STATEMENT("statement");
     431            3282 : static string TOK_ABSOLUTE("absolute");
     432            3282 : static string TOK_PROCESS("process");
     433                 : 
     434                 : 
     435                 : struct
     436                 : func_info
     437         1479947 : {
     438          422842 :   func_info()
     439          422842 :     : decl_file(NULL), decl_line(-1), prologue_end(0)
     440                 :   {
     441          422842 :     memset(&die, 0, sizeof(die));
     442          422842 :   }
     443                 :   string name;
     444                 :   char const * decl_file;
     445                 :   int decl_line;
     446                 :   Dwarf_Die die;
     447                 :   Dwarf_Addr prologue_end;
     448                 : };
     449                 : 
     450                 : struct
     451                 : inline_instance_info
     452         2392165 : {
     453          710411 :   inline_instance_info()
     454          710411 :     : decl_file(NULL), decl_line(-1)
     455                 :   {
     456          710411 :     memset(&die, 0, sizeof(die));
     457          710411 :   }
     458                 :   string name;
     459                 :   char const * decl_file;
     460                 :   int decl_line;
     461                 :   Dwarf_Die die;
     462                 : };
     463                 : 
     464                 : 
     465                 : static int
     466                 : query_cu (Dwarf_Die * cudie, void * arg);
     467                 : 
     468                 : 
     469                 : // Helper for dealing with selected portions of libdwfl in a more readable
     470                 : // fashion, and with specific cleanup / checking / logging options.
     471                 : 
     472                 : static const char *
     473           11884 : dwarf_diename_integrate (Dwarf_Die *die)
     474                 : {
     475                 :   Dwarf_Attribute attr_mem;
     476           11884 :   return dwarf_formstring (dwarf_attr_integrate (die, DW_AT_name, &attr_mem));
     477                 : }
     478                 : 
     479                 : 
     480                 : struct dwarf_query; // forward decl
     481                 : 
     482                 : struct dwflpp
     483                 : {
     484                 :   systemtap_session & sess;
     485                 :   Dwfl * dwfl;
     486                 : 
     487                 :   // These are "current" values we focus on.
     488                 :   Dwfl_Module * module;
     489                 :   Dwarf * module_dwarf;
     490                 :   Dwarf_Addr module_bias;
     491                 : 
     492                 :   // These describe the current module's PC address range
     493                 :   Dwarf_Addr module_start;
     494                 :   Dwarf_Addr module_end;
     495                 : 
     496                 :   Dwarf_Die * cu;
     497                 :   Dwarf_Die * function;
     498                 : 
     499                 :   string module_name;
     500                 :   string cu_name;
     501                 :   string function_name;
     502                 : 
     503                 :   string const default_name(char const * in,
     504      1616384592 :                             char const *)
     505                 :   {
     506      1616384592 :     if (in)
     507      1616384592 :       return in;
     508               0 :     return string("");
     509                 :   }
     510                 : 
     511                 : 
     512           61218 :   void get_module_dwarf(bool required = false)
     513                 :   {
     514           61218 :     if (!module_dwarf)
     515           61193 :       module_dwarf = dwfl_module_getdwarf(module, &module_bias);
     516                 : 
     517           61218 :     if (!module_dwarf)
     518                 :       {
     519               0 :         string msg = "cannot find ";
     520               0 :         if (module_name == "")
     521               0 :           msg += "kernel";
     522                 :         else
     523               0 :           msg += string("module ") + module_name;
     524               0 :         msg += " debuginfo";
     525                 : 
     526               0 :         int i = dwfl_errno();
     527               0 :         if (i)
     528               0 :           msg += string(": ") + dwfl_errmsg (i);
     529                 : 
     530               0 :         if (required)
     531               0 :           throw semantic_error (msg);
     532                 :         else
     533               0 :           cerr << "WARNING: " << msg << "\n";
     534                 :       }
     535           61218 :   }
     536                 : 
     537        59557156 :   void focus_on_module(Dwfl_Module * m)
     538                 :   {
     539        59557156 :     assert(m);
     540        59557156 :     module = m;
     541                 :     module_name = default_name(dwfl_module_info(module, NULL,
     542                 :                                                 &module_start, &module_end,
     543                 :                                                 NULL, NULL,
     544                 :                                                 NULL, NULL),
     545        59557156 :                                "module");
     546                 : 
     547                 :     // Reset existing pointers and names
     548                 : 
     549        59557156 :     module_dwarf = NULL;
     550                 : 
     551        59557156 :     cu_name.clear();
     552        59557156 :     cu = NULL;
     553                 : 
     554        59557156 :     function_name.clear();
     555        59557156 :     function = NULL;
     556        59557156 :   }
     557                 : 
     558                 : 
     559        51344637 :   void focus_on_cu(Dwarf_Die * c)
     560                 :   {
     561        51344637 :     assert(c);
     562        51344637 :     assert(module);
     563                 : 
     564        51344637 :     cu = c;
     565        51344637 :     cu_name = default_name(dwarf_diename(c), "CU");
     566                 : 
     567                 :     // Reset existing pointers and names
     568        51344637 :     function_name.clear();
     569        51344637 :     function = NULL;
     570        51344637 :   }
     571                 : 
     572                 : 
     573      1505482799 :   void focus_on_function(Dwarf_Die * f)
     574                 :   {
     575      1505482799 :     assert(f);
     576      1505482799 :     assert(module);
     577      1505482799 :     assert(cu);
     578                 : 
     579      1505482799 :     function = f;
     580                 :     function_name = default_name(dwarf_diename(function),
     581      1505482799 :                                  "function");
     582      1505482799 :   }
     583                 : 
     584                 : 
     585                 :   void focus_on_module_containing_global_address(Dwarf_Addr a)
     586                 :   {
     587                 :     assert(dwfl);
     588                 :     cu = NULL;
     589                 :     Dwfl_Module* mod = dwfl_addrmodule(dwfl, a);
     590                 :     if (mod) // address could be wildly out of range
     591                 :       focus_on_module(mod);
     592                 :   }
     593                 : 
     594                 : 
     595               1 :   void query_cu_containing_global_address(Dwarf_Addr a, void *arg)
     596                 :   {
     597                 :     Dwarf_Addr bias;
     598               1 :     assert(dwfl);
     599               1 :     get_module_dwarf();
     600               1 :     Dwarf_Die* cudie = dwfl_module_addrdie(module, a, &bias);
     601               1 :     if (cudie) // address could be wildly out of range
     602               1 :       query_cu (cudie, arg);
     603               1 :     assert(bias == module_bias);
     604               1 :   }
     605                 : 
     606                 : 
     607               1 :   void query_cu_containing_module_address(Dwarf_Addr a, void *arg)
     608                 :   {
     609               1 :     query_cu_containing_global_address(module_address_to_global(a), arg);
     610               1 :   }
     611                 : 
     612                 : 
     613              16 :   Dwarf_Addr module_address_to_global(Dwarf_Addr a)
     614                 :   {
     615              16 :     assert(dwfl);
     616              16 :     assert(module);
     617              16 :     get_module_dwarf();
     618              16 :     if (module_name == TOK_KERNEL)
     619              16 :       return a;
     620               0 :     return a + module_start;
     621                 :   }
     622                 : 
     623                 : 
     624                 :   Dwarf_Addr global_address_to_module(Dwarf_Addr a)
     625                 :   {
     626                 :     assert(module);
     627                 :     get_module_dwarf();
     628                 :     return a - module_bias;
     629                 :   }
     630                 : 
     631                 : 
     632        59557156 :   bool module_name_matches(string pattern)
     633                 :   {
     634        59557156 :     assert(module);
     635        59557156 :     bool t = (fnmatch(pattern.c_str(), module_name.c_str(), 0) == 0);
     636        59557156 :     if (t && sess.verbose>3)
     637                 :       clog << "pattern '" << pattern << "' "
     638                 :            << "matches "
     639               0 :            << "module '" << module_name << "'" << "\n";
     640        59557156 :     return t;
     641                 :   }
     642          393994 :   bool module_name_final_match(string pattern)
     643                 :   {
     644                 :     // Assume module_name_matches().  Can there be any more matches?
     645                 :     // Not unless the pattern is a wildcard, since module names are
     646                 :     // presumed unique.
     647                 :     return (pattern.find('*') == string::npos &&
     648                 :             pattern.find('?') == string::npos &&
     649          393994 :             pattern.find('[') == string::npos);
     650                 :   }
     651                 : 
     652                 : 
     653      1112660334 :   bool function_name_matches(string pattern)
     654                 :   {
     655      1112660334 :     assert(function);
     656      1112660334 :     bool t = (fnmatch(pattern.c_str(), function_name.c_str(), 0) == 0);
     657      1112660334 :     if (t && sess.verbose>3)
     658                 :       clog << "pattern '" << pattern << "' "
     659                 :            << "matches "
     660               0 :            << "function '" << function_name << "'" << "\n";
     661      1112660334 :     return t;
     662                 :   }
     663          332801 :   bool function_name_final_match(string pattern)
     664                 :   {
     665          332801 :     return module_name_final_match (pattern);
     666                 :   }
     667                 : 
     668                 : 
     669                 :   bool cu_name_matches(string pattern)
     670                 :   {
     671                 :     assert(cu);
     672                 :     bool t = (fnmatch(pattern.c_str(), cu_name.c_str(), 0) == 0);
     673                 :     if (t && sess.verbose>3)
     674                 :       clog << "pattern '" << pattern << "' "
     675                 :            << "matches "
     676                 :            << "CU '" << cu_name << "'" << "\n";
     677                 :     return t;
     678                 :   }
     679                 : 
     680                 : 
     681                 :   // NB: "rc == 0" means OK in this case
     682          151480 :   static void dwfl_assert(string desc, int rc, string extra_msg = "")
     683                 :   {
     684          151480 :     string msg = "libdwfl failure (" + desc + "): ";
     685          151480 :     if (rc < 0) msg += dwfl_errmsg (rc);
     686          151480 :     else if (rc > 0) msg += strerror (rc);
     687          151480 :     if (rc != 0)
     688                 :       {
     689               1 :         if (extra_msg.length() > 0)
     690               0 :           msg += "\n" + extra_msg;
     691               1 :         throw semantic_error (msg);
     692          151480 :       }
     693          151479 :   }
     694                 : 
     695           34554 :   void dwarf_assert(string desc, int rc) // NB: "rc == 0" means OK in this case
     696                 :   {
     697           34554 :     string msg = "libdw failure (" + desc + "): ";
     698           34554 :     if (rc < 0) msg += dwarf_errmsg (rc);
     699           34554 :     else if (rc > 0) msg += strerror (rc);
     700           34554 :     if (rc != 0)
     701               0 :       throw semantic_error (msg);
     702           34554 :   }
     703                 : 
     704                 : 
     705             207 :   dwflpp(systemtap_session & sess)
     706                 :     :
     707                 :     sess(sess),
     708                 :     dwfl(NULL),
     709                 :     module(NULL),
     710                 :     module_dwarf(NULL),
     711                 :     module_bias(0),
     712                 :     module_start(0),
     713                 :     module_end(0),
     714                 :     cu(NULL),
     715             207 :     function(NULL)
     716             207 :   {}
     717                 : 
     718                 : 
     719             207 :   void setup(bool kernel, bool debuginfo_needed = true)
     720                 :   {
     721                 :     // XXX: this is where the session -R parameter could come in
     722                 :     static char debuginfo_path_arr[] = "-:.debug:/usr/lib/debug";
     723             207 :     static char *debuginfo_env_arr = getenv("SYSTEMTAP_DEBUGINFO_PATH");
     724                 : 
     725                 :     static char *debuginfo_path = (debuginfo_env_arr ?
     726             207 :                                    debuginfo_env_arr : debuginfo_path_arr);
     727                 : 
     728                 :     static const Dwfl_Callbacks proc_callbacks =
     729                 :       {
     730                 :         dwfl_linux_proc_find_elf,
     731                 :         dwfl_standard_find_debuginfo,
     732                 :         NULL,
     733                 :         & debuginfo_path
     734                 :       };
     735                 : 
     736                 :     static const Dwfl_Callbacks kernel_callbacks =
     737                 :       {
     738                 :         dwfl_linux_kernel_find_elf,
     739                 :         dwfl_standard_find_debuginfo,
     740                 :         dwfl_offline_section_address,
     741                 :         & debuginfo_path
     742                 :       };
     743                 : 
     744             207 :     if (kernel)
     745                 :       {
     746             207 :         dwfl = dwfl_begin (&kernel_callbacks);
     747             207 :         if (!dwfl)
     748               0 :           throw semantic_error ("cannot open dwfl");
     749             207 :         dwfl_report_begin (dwfl);
     750                 : 
     751                 :         int rc = dwfl_linux_kernel_report_offline (dwfl,
     752                 :                                                    sess.kernel_release.c_str(),
     753                 :                                                    /* selection predicate */
     754             207 :                                                    NULL);
     755             207 :         if (debuginfo_needed)
     756                 :           dwfl_assert (string("missing kernel ") +
     757                 :                        sess.kernel_release +
     758                 :                        string(" ") +
     759                 :                        sess.architecture +
     760                 :                        string(" debuginfo"),
     761             207 :                        rc);
     762                 : 
     763                 :         // XXX: it would be nice if we could do a single
     764                 :         // ..._report_offline call for an entire systemtap script, so
     765                 :         // that a selection predicate would filter out modules outside
     766                 :         // the union of all the requested wildcards.  But we build
     767                 :         // derived_probes one-by-one and we don't have lookahead.
     768                 : 
     769                 :         // XXX: a special case: if we have only kernel.* probe points,
     770                 :         // we shouldn't waste time looking for module debug-info (and
     771                 :         // vice versa).
     772                 : 
     773                 :         // NB: the result of an _offline call is the assignment of
     774                 :         // virtualized addresses to relocatable objects such as
     775                 :         // modules.  These have to be converted to real addresses at
     776                 :         // run time.  See the dwarf_derived_probe ctor and its caller.
     777                 :       }
     778                 :     else
     779                 :       {
     780               0 :         dwfl = dwfl_begin (&proc_callbacks);
     781               0 :         dwfl_report_begin (dwfl);
     782               0 :         if (!dwfl)
     783               0 :           throw semantic_error ("cannot open dwfl");
     784                 : 
     785               0 :         throw semantic_error ("user-space probes not yet implemented");
     786                 :         // XXX: Find pids or processes, do userspace stuff.
     787                 :       }
     788                 : 
     789             412 :     dwfl_assert ("dwfl_report_end", dwfl_report_end(dwfl, NULL, NULL));
     790             206 :   }
     791                 : 
     792                 : 
     793                 : 
     794                 :   // -----------------------------------------------------------------
     795                 : 
     796          648082 :   struct module_cache_entry {
     797                 :     Dwfl_Module* mod;
     798                 :     const char* name;
     799                 :     Dwarf_Addr addr;
     800                 :   };
     801                 :   typedef vector<module_cache_entry> module_cache_t;
     802                 :   module_cache_t module_cache;
     803                 : 
     804                 :   static int module_caching_callback(Dwfl_Module * mod,
     805                 :                                      void **,
     806                 :                                      const char *name,
     807                 :                                      Dwarf_Addr addr,
     808          226400 :                                      void *param)
     809                 :   {
     810          226400 :     module_cache_t* cache = static_cast<module_cache_t*>(param);
     811                 :     module_cache_entry it;
     812          226400 :     it.mod = mod;
     813          226400 :     it.name = name;
     814          226400 :     it.addr = addr;
     815          226400 :     cache->push_back (it);
     816          226400 :     return DWARF_CB_OK;
     817                 :   }
     818                 : 
     819                 : 
     820                 :   void iterate_over_modules(int (* callback)(Dwfl_Module *, void **,
     821                 :                                              const char *, Dwarf_Addr,
     822                 :                                              void *),
     823          109194 :                             void * data)
     824                 :   {
     825          109194 :     if (module_cache.empty())
     826                 :       {
     827             206 :         ptrdiff_t off = 0;
     828             206 :         do
     829                 :           {
     830             206 :             if (pending_interrupts) return;
     831                 :             off = dwfl_getmodules (dwfl, module_caching_callback,
     832             206 :                                    & module_cache, off);
     833                 :           }
     834                 :         while (off > 0);
     835             206 :         dwfl_assert("dwfl_getmodules", off);
     836                 :       }
     837                 : 
     838                 :     // Traverse the cache.
     839       119561497 :     for (unsigned i = 0; i < module_cache.size(); i++)
     840                 :       {
     841       119561487 :         if (pending_interrupts) return;
     842       119561487 :         module_cache_entry& it = module_cache[i];
     843       119561487 :         int rc = callback (it.mod, 0, it.name, it.addr, data);
     844       119561487 :         if (rc != DWARF_CB_OK) break;
     845                 :       }
     846                 :   }
     847                 : 
     848                 : 
     849                 : 
     850                 :   // -----------------------------------------------------------------
     851                 : 
     852                 :   typedef map<Dwarf*, vector<Dwarf_Die>*> module_cu_cache_t;
     853                 :   module_cu_cache_t module_cu_cache;
     854                 : 
     855                 :   void iterate_over_cus (int (*callback)(Dwarf_Die * die, void * arg),
     856           61192 :                          void * data)
     857                 :   {
     858           61192 :     get_module_dwarf(false);
     859           61192 :     Dwarf *dw = module_dwarf;
     860           61192 :     if (!dw) return;
     861                 : 
     862           61192 :     vector<Dwarf_Die>* v = module_cu_cache[dw];
     863           61192 :     if (v == 0)
     864                 :       {
     865            2414 :         v = new vector<Dwarf_Die>;
     866            2414 :         module_cu_cache[dw] = v;
     867                 : 
     868            2414 :         Dwarf_Off off = 0;
     869                 :         size_t cuhl;
     870                 :         Dwarf_Off noff;
     871          195098 :         while (dwarf_nextcu (dw, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
     872                 :           {
     873          190270 :             if (pending_interrupts) return;
     874                 :             Dwarf_Die die_mem;
     875                 :             Dwarf_Die *die;
     876          190270 :             die = dwarf_offdie (dw, off + cuhl, &die_mem);
     877          190270 :             v->push_back (*die); /* copy */
     878          190270 :             off = noff;
     879                 :           }
     880                 :       }
     881                 : 
     882        51405827 :     for (unsigned i = 0; i < v->size(); i++)
     883                 :       {
     884        51344636 :         if (pending_interrupts) return;
     885        51344636 :         Dwarf_Die die = v->at(i);
     886        51344636 :         int rc = (*callback)(& die, data);
     887        51344636 :         if (rc != DWARF_CB_OK) break;
     888                 :       }
     889                 :   }
     890                 : 
     891                 : 
     892                 :   // -----------------------------------------------------------------
     893                 : 
     894      3010965598 :   bool func_is_inline()
     895                 :   {
     896      3010965598 :     assert (function);
     897      3010965598 :     return dwarf_func_inline (function) != 0;
     898                 :   }
     899                 : 
     900                 : 
     901                 :   typedef map<string, vector<Dwarf_Die>*> cu_inl_function_cache_t;
     902                 :   cu_inl_function_cache_t cu_inl_function_cache;
     903                 : 
     904          193947 :   static int cu_inl_function_caching_callback (Dwarf_Die* func, void *arg)
     905                 :   {
     906          193947 :     vector<Dwarf_Die>* v = static_cast<vector<Dwarf_Die>*>(arg);
     907          193947 :     v->push_back (* func);
     908          193947 :     return DWARF_CB_OK;
     909                 :   }
     910                 : 
     911                 :   void iterate_over_inline_instances (int (* callback)(Dwarf_Die * die, void * arg),
     912          121380 :                                       void * data)
     913                 :   {
     914          121380 :     assert (function);
     915          121380 :     assert (func_is_inline ());
     916                 : 
     917          121380 :     string key = module_name + ":" + cu_name + ":" + function_name;
     918          242760 :     vector<Dwarf_Die>* v = cu_inl_function_cache[key];
     919          121380 :     if (v == 0)
     920                 :       {
     921           60924 :         v = new vector<Dwarf_Die>;
     922          121848 :         cu_inl_function_cache[key] = v;
     923           60924 :         dwarf_func_inline_instances (function, cu_inl_function_caching_callback, v);
     924                 :       }
     925                 : 
     926          508010 :     for (unsigned i=0; i<v->size(); i++)
     927                 :       {
     928          386630 :         Dwarf_Die die = v->at(i);
     929          386630 :         int rc = (*callback)(& die, data);
     930          386630 :         if (rc != DWARF_CB_OK) break;
     931          121380 :       }
     932          121380 :   }
     933                 : 
     934                 : 
     935                 :   // -----------------------------------------------------------------
     936                 : 
     937                 :   typedef map<string, vector<Dwarf_Die>*> cu_function_cache_t;
     938                 :   cu_function_cache_t cu_function_cache;
     939                 : 
     940         5060264 :   static int cu_function_caching_callback (Dwarf_Die* func, void *arg)
     941                 :   {
     942         5060264 :     vector<Dwarf_Die>* v = static_cast<vector<Dwarf_Die>*>(arg);
     943         5060264 :     v->push_back (* func);
     944         5060264 :     return DWARF_CB_OK;
     945                 :   }
     946                 : 
     947                 :   void iterate_over_functions (int (* callback)(Dwarf_Die * func, void * arg),
     948        51310135 :                                void * data)
     949                 :   {
     950        51310135 :     assert (module);
     951        51310135 :     assert (cu);
     952                 : 
     953        51310135 :     string key = module_name + ":" + cu_name;
     954       102620270 :     vector<Dwarf_Die>* v = cu_function_cache[key];
     955        51310135 :     if (v == 0)
     956                 :       {
     957          173157 :         v = new vector<Dwarf_Die>;
     958          346314 :         cu_function_cache[key] = v;
     959          173157 :         dwarf_getfuncs (cu, cu_function_caching_callback, v, 0);
     960                 :       }
     961                 : 
     962      1556745221 :     for (unsigned i=0; i<v->size(); i++)
     963                 :       {
     964      1505482799 :         Dwarf_Die die = v->at(i);
     965      1505482799 :         int rc = (*callback)(& die, data);
     966      1505482799 :         if (rc != DWARF_CB_OK) break;
     967        51310135 :       }
     968        51310135 :   }
     969                 : 
     970                 : 
     971                 :   bool has_single_line_record (dwarf_query * q, char const * srcfile, int lineno);
     972                 : 
     973                 :   void iterate_over_srcfile_lines (char const * srcfile,
     974                 :                                    int lineno,
     975                 :                                    bool need_single_match,
     976                 :                                    void (* callback) (Dwarf_Line * line, void * arg),
     977               9 :                                    void *data)
     978                 :   {
     979               9 :     Dwarf_Line **srcsp = NULL;
     980               9 :     size_t nsrcs = 0;
     981               9 :     dwarf_query * q = static_cast<dwarf_query *>(data);
     982                 : 
     983               9 :     get_module_dwarf();
     984                 : 
     985                 :     dwarf_assert ("dwarf_getsrc_file",
     986                 :                   dwarf_getsrc_file (module_dwarf,
     987                 :                                      srcfile, lineno, 0,
     988               9 :                                      &srcsp, &nsrcs));
     989                 : 
     990                 :     // NB: Formerly, we used to filter, because:
     991                 : 
     992                 :     // dwarf_getsrc_file gets one *near hits* for line numbers, not
     993                 :     // exact matches.  For example, an existing file but a nonexistent
     994                 :     // line number will be rounded up to the next definition in that
     995                 :     // file.  This may be similar to the GDB breakpoint algorithm, but
     996                 :     // we don't want to be so fuzzy in systemtap land.  So we filter.
     997                 : 
     998                 :     // But we now see the error of our ways, and skip this filtering.
     999                 : 
    1000                 :     // XXX: the code also fails to match e.g.  inline function
    1001                 :     // definitions when the srcfile is a header file rather than the
    1002                 :     // CU name.
    1003                 : 
    1004               9 :     size_t remaining_nsrcs = nsrcs;
    1005                 : #if 0
    1006                 :     for (size_t i = 0; i < nsrcs; ++i)
    1007                 :       {
    1008                 :         int l_no;
    1009                 :         Dwarf_Line* l = srcsp[i];
    1010                 :         dwarf_assert ("dwarf_lineno", dwarf_lineno (l, & l_no));
    1011                 :         if (l_no != lineno)
    1012                 :           {
    1013                 :             if (sess.verbose > 3)
    1014                 :               clog << "skipping line number mismatch "
    1015                 :                    << "(" << l_no << " vs " << lineno << ")"
    1016                 :                    << " in file '" << srcfile << "'"
    1017                 :                    << "\n";
    1018                 :             srcsp[i] = 0;
    1019                 :             remaining_nsrcs --;
    1020                 :           }
    1021                 :       }
    1022                 : #endif
    1023                 : 
    1024              18 :     if (need_single_match && remaining_nsrcs > 1)
    1025                 :       {
    1026                 :         // We wanted a single line record (a unique address for the
    1027                 :         // line) and we got a bunch of line records. We're going to
    1028                 :         // skip this probe (throw an exception) but before we throw
    1029                 :         // we're going to look around a bit to see if there's a low or
    1030                 :         // high line number nearby which *doesn't* have this problem,
    1031                 :         // so we can give the user some advice.
    1032                 : 
    1033               1 :         int lo_try = -1;
    1034               1 :         int hi_try = -1;
    1035               6 :         for (size_t i = 1; i < 6; ++i)
    1036                 :           {
    1037               5 :             if (lo_try == -1 && has_single_line_record(q, srcfile, lineno - i))
    1038               1 :               lo_try = lineno - i;
    1039                 : 
    1040               5 :             if (hi_try == -1 && has_single_line_record(q, srcfile, lineno + i))
    1041               1 :               hi_try = lineno + i;
    1042                 :           }
    1043                 : 
    1044               1 :         stringstream advice;
    1045               1 :         advice << "multiple addresses for " << srcfile << ":" << lineno;
    1046               1 :         if (lo_try > 0 || hi_try > 0)
    1047                 :           {
    1048               1 :             advice << " (try ";
    1049               1 :             if (lo_try > 0)
    1050               1 :               advice << srcfile << ":" << lo_try;
    1051               1 :             if (lo_try > 0 && hi_try > 0)
    1052               1 :               advice << " or ";
    1053               1 :             if (hi_try > 0)
    1054               1 :               advice << srcfile << ":" << hi_try;
    1055               1 :             advice << ")";
    1056                 :           }
    1057               1 :         throw semantic_error (advice.str());
    1058                 :       }
    1059                 : 
    1060                 :     try
    1061                 :       {
    1062              16 :         for (size_t i = 0; i < nsrcs; ++i)
    1063                 :           {
    1064               8 :             if (pending_interrupts) return;
    1065               8 :             if (srcsp [i]) // skip over mismatched lines
    1066               8 :               callback (srcsp[i], data);
    1067                 :           }
    1068                 :       }
    1069               0 :     catch (...)
    1070                 :       {
    1071               0 :         free (srcsp);
    1072               0 :         throw;
    1073                 :       }
    1074               8 :     free (srcsp);
    1075                 :   }
    1076                 : 
    1077                 : 
    1078                 :   void collect_srcfiles_matching (string const & pattern,
    1079           34541 :                                   set<char const *> & filtered_srcfiles)
    1080                 :   {
    1081           34541 :     assert (module);
    1082           34541 :     assert (cu);
    1083                 : 
    1084                 :     size_t nfiles;
    1085                 :     Dwarf_Files *srcfiles;
    1086                 : 
    1087                 :     dwarf_assert ("dwarf_getsrcfiles",
    1088           34541 :                   dwarf_getsrcfiles (cu, &srcfiles, &nfiles));
    1089                 :     {
    1090         3175652 :     for (size_t i = 0; i < nfiles; ++i)
    1091                 :       {
    1092         3141111 :         char const * fname = dwarf_filesrc (srcfiles, i, NULL, NULL);
    1093         3141111 :         if (fnmatch (pattern.c_str(), fname, 0) == 0)
    1094                 :           {
    1095              39 :             filtered_srcfiles.insert (fname);
    1096              39 :             if (sess.verbose>2)
    1097               0 :               clog << "selected source file '" << fname << "'\n";
    1098                 :           }
    1099                 :       }
    1100                 :     }
    1101           34541 :   }
    1102                 : 
    1103               2 :   void resolve_prologue_endings (map<Dwarf_Addr, func_info> & funcs)
    1104                 :   {
    1105                 :     // This heuristic attempts to pick the first address that has a
    1106                 :     // source line distinct from the function declaration's.  In a
    1107                 :     // perfect world, this would be the first statement *past* the
    1108                 :     // prologue.
    1109                 : 
    1110               2 :     assert(module);
    1111               2 :     assert(cu);
    1112                 : 
    1113               2 :     size_t nlines = 0;
    1114               2 :     Dwarf_Lines *lines = NULL;
    1115                 : 
    1116                 :     /* trouble cases:
    1117                 :        malloc do_symlink  in init/initramfs.c    tail-recursive/tiny then no-prologue
    1118                 :        sys_get?id         in kernel/timer.c      no-prologue
    1119                 :        sys_exit_group                            tail-recursive
    1120                 :        {do_,}sys_open                            extra-long-prologue (gcc 3.4)
    1121                 :        cpu_to_logical_apicid                     NULL-decl_file
    1122                 :     */
    1123                 : 
    1124                 :     // Fetch all srcline records, sorted by address.
    1125                 :     dwarf_assert ("dwarf_getsrclines",
    1126               2 :                   dwarf_getsrclines(cu, &lines, &nlines));
    1127                 :     // XXX: free lines[] later, but how?
    1128                 : 
    1129               4 :     for(map<Dwarf_Addr,func_info>::iterator it = funcs.begin(); it != funcs.end(); it++)
    1130                 :       {
    1131                 : #if 0 /* someday */
    1132                 :         Dwarf_Addr* bkpts = 0;
    1133                 :         int n = dwarf_entry_breakpoints (& it->second.die, & bkpts);
    1134                 :         // ...
    1135                 :         free (bkpts);
    1136                 : #endif
    1137                 : 
    1138               2 :         Dwarf_Addr entrypc = it->first;
    1139                 :         Dwarf_Addr highpc; // NB: highpc is exclusive: [entrypc,highpc)
    1140               2 :         func_info* func = &it->second;
    1141                 :         dwfl_assert ("dwarf_highpc", dwarf_highpc (& func->die,
    1142               2 :                                                    & highpc));
    1143                 : 
    1144               2 :         if (func->decl_file == 0) func->decl_file = "";
    1145                 : 
    1146               2 :         unsigned entrypc_srcline_idx = 0;
    1147               2 :         Dwarf_Line* entrypc_srcline = 0;
    1148                 :         // open-code binary search for exact match
    1149                 :         {
    1150               2 :           unsigned l = 0, h = nlines;
    1151              20 :           while (l < h)
    1152                 :             {
    1153              18 :               entrypc_srcline_idx = (l + h) / 2;
    1154                 :               Dwarf_Addr addr;
    1155              18 :               Dwarf_Line *lr = dwarf_onesrcline(lines, entrypc_srcline_idx);
    1156              18 :               dwarf_lineaddr (lr, &addr);
    1157              18 :               if (addr == entrypc) { entrypc_srcline = lr; break; }
    1158              16 :               else if (l + 1 == h) { break; } // ran off bottom of tree
    1159              16 :               else if (addr < entrypc) { l = entrypc_srcline_idx; }
    1160              11 :               else { h = entrypc_srcline_idx; }
    1161                 :             }
    1162                 :         }
    1163               2 :         if (entrypc_srcline == 0)
    1164                 :           throw semantic_error ("missing entrypc dwarf line record for function '"
    1165               0 :                                 + func->name + "'");
    1166                 : 
    1167               2 :         if (sess.verbose>2)
    1168                 :           clog << "prologue searching function '" << func->name << "'"
    1169                 :                << " 0x" << hex << entrypc << "-0x" << highpc << dec
    1170                 :                << "@" << func->decl_file << ":" << func->decl_line
    1171               0 :                << "\n";
    1172                 : 
    1173                 :         // Now we go searching for the first line record that has a
    1174                 :         // file/line different from the one in the declaration.
    1175                 :         // Normally, this will be the next one.  BUT:
    1176                 :         //
    1177                 :         // We may have to skip a few because some old compilers plop
    1178                 :         // in dummy line records for longer prologues.  If we go too
    1179                 :         // far (addr >= highpc), we take the previous one.  Or, it may
    1180                 :         // be the first one, if the function had no prologue, and thus
    1181                 :         // the entrypc maps to a statement in the body rather than the
    1182                 :         // declaration.
    1183                 : 
    1184               2 :         unsigned postprologue_srcline_idx = entrypc_srcline_idx;
    1185               2 :         bool ranoff_end = false;
    1186               6 :         while (postprologue_srcline_idx < nlines)
    1187                 :           {
    1188                 :             Dwarf_Addr postprologue_addr;
    1189               4 :             Dwarf_Line *lr = dwarf_onesrcline(lines, postprologue_srcline_idx);
    1190               4 :             dwarf_lineaddr (lr, &postprologue_addr);
    1191               4 :             const char* postprologue_file = dwarf_linesrc (lr, NULL, NULL);
    1192                 :             int postprologue_lineno;
    1193                 :             dwfl_assert ("dwarf_lineno",
    1194               4 :                          dwarf_lineno (lr, & postprologue_lineno));
    1195                 : 
    1196               4 :             if (sess.verbose>2)
    1197                 :               clog << "checking line record 0x" << hex << postprologue_addr << dec
    1198               0 :                    << "@" << postprologue_file << ":" << postprologue_lineno << "\n";
    1199                 : 
    1200               4 :             if (postprologue_addr >= highpc)
    1201                 :               {
    1202               0 :                 ranoff_end = true;
    1203               0 :                 postprologue_srcline_idx --;
    1204               0 :                 continue;
    1205                 :               }
    1206               4 :             if (ranoff_end ||
    1207                 :                 (strcmp (postprologue_file, func->decl_file) || // We have a winner!
    1208                 :                  (postprologue_lineno != func->decl_line)))
    1209                 :               {
    1210               2 :                 func->prologue_end = postprologue_addr;
    1211                 : 
    1212               2 :                 if (sess.verbose>2)
    1213                 :                   {
    1214               0 :                     clog << "prologue found function '" << func->name << "'";
    1215                 :                     // Add a little classification datum
    1216               0 :                     if (postprologue_srcline_idx == entrypc_srcline_idx) clog << " (naked)";
    1217               0 :                     if (ranoff_end) clog << " (tail-call?)";
    1218               0 :                     clog << " = 0x" << hex << postprologue_addr << dec << "\n";
    1219                 :                   }
    1220                 : 
    1221               2 :                 break;
    1222                 :               }
    1223                 : 
    1224                 :             // Let's try the next srcline.
    1225               2 :             postprologue_srcline_idx ++;
    1226                 :           } // loop over srclines
    1227                 : 
    1228                 :         // if (strlen(func->decl_file) == 0) func->decl_file = NULL;
    1229                 : 
    1230                 :       } // loop over functions
    1231                 : 
    1232                 :     // XXX: how to free lines?
    1233               2 :   }
    1234                 : 
    1235                 : 
    1236          211420 :   bool function_entrypc (Dwarf_Addr * addr)
    1237                 :   {
    1238          211420 :     assert (function);
    1239          211420 :     return (dwarf_entrypc (function, addr) == 0);
    1240                 :     // XXX: see also _lowpc ?
    1241                 :   }
    1242                 : 
    1243                 : 
    1244          386630 :   bool die_entrypc (Dwarf_Die * die, Dwarf_Addr * addr)
    1245                 :   {
    1246          386630 :     int rc = 0;
    1247          386630 :     string lookup_method;
    1248                 : 
    1249          386630 :     * addr = 0;
    1250                 : 
    1251          386630 :     lookup_method = "dwarf_entrypc";
    1252          386630 :     rc = dwarf_entrypc (die, addr);
    1253                 : 
    1254          386630 :     if (rc)
    1255                 :       {
    1256           89132 :         lookup_method = "dwarf_lowpc";
    1257           89132 :         rc = dwarf_lowpc (die, addr);
    1258                 :       }
    1259                 : 
    1260          386630 :     if (rc)
    1261                 :       {
    1262           89132 :         lookup_method = "dwarf_ranges";
    1263                 : 
    1264                 :         Dwarf_Addr base;
    1265                 :         Dwarf_Addr begin;
    1266                 :         Dwarf_Addr end;
    1267           89132 :         ptrdiff_t offset = dwarf_ranges (die, 0, &base, &begin, &end);
    1268           89132 :         if (offset < 0) rc = -1;
    1269           89132 :         else if (offset > 0)
    1270                 :           {
    1271           89132 :             * addr = begin;
    1272           89132 :             rc = 0;
    1273                 : 
    1274                 :             // Now we need to check that there are no more ranges
    1275                 :             // associated with this function, which could conceivably
    1276                 :             // happen if a function is inlined, then pieces of it are
    1277                 :             // split amongst different conditional branches.  It's not
    1278                 :             // obvious which of them to favour.  As a heuristic, we
    1279                 :             // pick the beginning of the first range, and ignore the
    1280                 :             // others (but with a warning).
    1281                 : 
    1282           89132 :             unsigned extra = 0;
    1283          300611 :             while ((offset = dwarf_ranges (die, offset, &base, &begin, &end)) > 0)
    1284          122347 :               extra ++;
    1285           89132 :             if (extra)
    1286           89132 :               lookup_method += ", ignored " + lex_cast<string>(extra) + " more";
    1287                 :           }
    1288                 :       }
    1289                 : 
    1290          386630 :     if (sess.verbose > 2)
    1291                 :       clog << "entry-pc lookup (" << lookup_method << ") = 0x" << hex << *addr << dec
    1292                 :            << " (rc " << rc << ")"
    1293               0 :            << endl;
    1294          386630 :     return (rc == 0);
    1295                 :   }
    1296                 : 
    1297          211436 :   void function_die (Dwarf_Die *d)
    1298                 :   {
    1299          211436 :     assert (function);
    1300          211436 :     *d = *function;
    1301          211436 :   }
    1302                 : 
    1303          598051 :   void function_file (char const ** c)
    1304                 :   {
    1305          598051 :     assert (function);
    1306          598051 :     assert (c);
    1307          598051 :     *c = dwarf_decl_file (function);
    1308          598051 :   }
    1309                 : 
    1310          598051 :   void function_line (int *linep)
    1311                 :   {
    1312          598051 :     assert (function);
    1313          598051 :     dwarf_decl_line (function, linep);
    1314          598051 :   }
    1315                 : 
    1316              25 :   bool die_has_pc (Dwarf_Die * die, Dwarf_Addr pc)
    1317                 :   {
    1318              25 :     int res = dwarf_haspc (die, pc);
    1319              25 :     if (res == -1)
    1320               0 :       dwarf_assert ("dwarf_haspc", res);
    1321              25 :     return res == 1;
    1322                 :   }
    1323                 : 
    1324                 : 
    1325               0 :   static void loc2c_error (void *, const char *fmt, ...)
    1326                 :   {
    1327               0 :     const char *msg = "?";
    1328               0 :     char *tmp = NULL;
    1329                 :     int rc;
    1330                 :     va_list ap;
    1331               0 :     va_start (ap, fmt);
    1332               0 :     rc = vasprintf (& tmp, fmt, ap);
    1333               0 :     if (rc < 0)
    1334               0 :       msg = "?";
    1335                 :     else
    1336               0 :       msg = tmp;
    1337               0 :     va_end (ap);
    1338               0 :     throw semantic_error (msg);
    1339                 :   }
    1340                 : 
    1341                 :   // This function generates code used for addressing computations of
    1342                 :   // target variables.
    1343               2 :   void emit_address (struct obstack *pool, Dwarf_Addr address)
    1344                 :   {
    1345                 :     #if 0
    1346                 :     // The easy but incorrect way is to just print a hard-wired
    1347                 :     // constant.
    1348                 :     obstack_printf (pool, "%#" PRIx64 "UL", address);
    1349                 :     #endif
    1350                 : 
    1351                 :     // Turn this address into a section-relative offset if it should be one.
    1352                 :     // We emit a comment approximating the variable+offset expression that
    1353                 :     // relocatable module probing code will need to have.
    1354               2 :     Dwfl_Module *mod = dwfl_addrmodule (dwfl, address);
    1355               2 :     dwfl_assert ("dwfl_addrmodule", mod == NULL);
    1356               2 :     int n = dwfl_module_relocations (mod);
    1357               4 :     dwfl_assert ("dwfl_module_relocations", n < 0);
    1358               2 :     int i = dwfl_module_relocate_address (mod, &address);
    1359               4 :     dwfl_assert ("dwfl_module_relocate_address", i < 0);
    1360                 :     const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
    1361               2 :                                                 NULL, NULL, NULL, NULL);
    1362               4 :     dwfl_assert ("dwfl_module_info", modname == NULL);
    1363               2 :     const char *secname = dwfl_module_relocation_info (mod, i, NULL);
    1364                 : 
    1365               6 :     if (n > 0 && !(n == 1 && secname == NULL))
    1366                 :      {
    1367               2 :         dwfl_assert ("dwfl_module_relocation_info", secname == NULL);
    1368               4 :         if (n > 1 || secname[0] != '\0')
    1369                 :           {
    1370                 :             // This gives us the module name, and section name within the
    1371                 :             // module, for a kernel module (or other ET_REL module object).
    1372               1 :             obstack_printf (pool, "({ static unsigned long addr = 0; ");
    1373                 :             obstack_printf (pool, "if (addr==0) addr = _stp_module_relocate (\"%s\",\"%s\",%#" PRIx64 "); ",
    1374               1 :                             modname, secname, address);
    1375               1 :             obstack_printf (pool, "addr; })");
    1376                 :           }
    1377               1 :         else if (n == 1 && module_name == TOK_KERNEL && secname[0] == '\0')
    1378                 :           {
    1379                 :             // elfutils' way of telling us that this is a relocatable kernel address, which we
    1380                 :             // need to treat the same way here as dwarf_query::add_probe_point does: _stext.
    1381               1 :             address -= sess.sym_stext;
    1382               1 :             secname = "_stext";
    1383               1 :             obstack_printf (pool, "({ static unsigned long addr = 0; ");
    1384                 :             obstack_printf (pool, "if (addr==0) addr = _stp_module_relocate (\"%s\",\"%s\",%#" PRIx64 "); ",
    1385               1 :                             modname, secname, address);
    1386               1 :             obstack_printf (pool, "addr; })");
    1387                 :           }
    1388                 :         else
    1389                 :           {
    1390               0 :             throw semantic_error ("cannot relocate user-space dso (?) address");
    1391                 : #if 0
    1392                 :             // This would happen for a Dwfl_Module that's a user-level DSO.
    1393                 :             obstack_printf (pool, " /* %s+%#" PRIx64 " */",
    1394                 :                             modname, address);
    1395                 : #endif
    1396                 :           }
    1397                 :       }
    1398                 :     else
    1399               0 :       obstack_printf (pool, "%#" PRIx64 "UL", address); // assume as constant
    1400               2 :   }
    1401                 : 
    1402                 :   static void loc2c_emit_address (void *arg, struct obstack *pool,
    1403               2 :                                   Dwarf_Addr address)
    1404                 :   {
    1405               2 :     dwflpp *dwfl = (dwflpp *) arg;
    1406               2 :     dwfl->emit_address (pool, address);
    1407               2 :   }
    1408                 : 
    1409               5 :   void print_locals(Dwarf_Die *die, ostream &o)
    1410                 :   {
    1411                 :     // Try to get the first child of die.
    1412               5 :     bool local_found = false;
    1413                 :     Dwarf_Die child;
    1414               5 :     if (dwarf_child (die, &child) == 0)
    1415                 :       {
    1416              69 :         do
    1417                 :           {
    1418                 :             // Output each sibling's name (that is a variable or
    1419                 :             // parameter) to 'o'.
    1420              69 :             switch (dwarf_tag (&child))
    1421                 :               {
    1422                 :               case DW_TAG_variable:
    1423                 :               case DW_TAG_formal_parameter:
    1424              27 :                 o << " " << dwarf_diename (&child);
    1425              27 :                 local_found = true;
    1426                 :                 break;
    1427                 :               default:
    1428                 :                 break;
    1429                 :               }
    1430                 :           }
    1431                 :         while (dwarf_siblingof (&child, &child) == 0);
    1432                 :       }
    1433                 : 
    1434               5 :     if (! local_found)
    1435               0 :       o << " (none found)";
    1436               5 :   }
    1437                 : 
    1438                 :   Dwarf_Attribute *
    1439                 :   find_variable_and_frame_base (Dwarf_Die *scope_die,
    1440                 :                                 Dwarf_Addr pc,
    1441                 :                                 string const & local,
    1442                 :                                 Dwarf_Die *vardie,
    1443          114979 :                                 Dwarf_Attribute *fb_attr_mem)
    1444                 :   {
    1445                 :     Dwarf_Die *scopes;
    1446          114979 :     int nscopes = 0;
    1447          114979 :     Dwarf_Attribute *fb_attr = NULL;
    1448                 : 
    1449          114979 :     assert (cu);
    1450                 : 
    1451          114979 :     if (scope_die)
    1452          114979 :       nscopes = dwarf_getscopes_die (scope_die, &scopes);
    1453                 :     else
    1454               0 :       nscopes = dwarf_getscopes (cu, pc, &scopes);
    1455                 : 
    1456          114979 :     if (nscopes == 0)
    1457                 :       {
    1458                 :         throw semantic_error ("unable to find any scopes containing "
    1459                 :                               + lex_cast_hex<string>(pc)
    1460               0 :                               + " while searching for local '" + local + "'");
    1461                 :       }
    1462                 : 
    1463                 :     int declaring_scope = dwarf_getscopevar (scopes, nscopes,
    1464                 :                                              local.c_str(),
    1465                 :                                              0, NULL, 0, 0,
    1466          114979 :                                              vardie);
    1467          114979 :     if (declaring_scope < 0)
    1468                 :       {
    1469               5 :         stringstream alternatives;
    1470               5 :         print_locals (scopes, alternatives);
    1471                 :         throw semantic_error ("unable to find local '" + local + "'"
    1472                 :                               + " near pc " + lex_cast_hex<string>(pc)
    1473                 :                               + " (alternatives:" + alternatives.str ()
    1474               5 :                               + ")");
    1475                 :       }
    1476                 : 
    1477          345039 :     for (int inner = 0; inner < nscopes; ++inner)
    1478                 :       {
    1479          230065 :         switch (dwarf_tag (&scopes[inner]))
    1480                 :           {
    1481                 :           default:
    1482          114974 :             continue;
    1483                 :           case DW_TAG_subprogram:
    1484                 :           case DW_TAG_entry_point:
    1485                 :           case DW_TAG_inlined_subroutine:  /* XXX */
    1486          115091 :             if (inner >= declaring_scope)
    1487                 :               fb_attr = dwarf_attr_integrate (&scopes[inner],
    1488                 :                                               DW_AT_frame_base,
    1489          115089 :                                               fb_attr_mem);
    1490                 :             break;
    1491                 :           }
    1492                 :       }
    1493          114974 :     return fb_attr;
    1494                 :   }
    1495                 : 
    1496                 : 
    1497                 :   struct location *
    1498                 :   translate_location(struct obstack *pool,
    1499                 :                      Dwarf_Attribute *attr, Dwarf_Addr pc,
    1500                 :                      Dwarf_Attribute *fb_attr,
    1501          116305 :                      struct location **tail)
    1502                 :   {
    1503                 :     Dwarf_Op *expr;
    1504                 :     size_t len;
    1505                 : 
    1506          116305 :     switch (dwarf_getlocation_addr (attr, pc - module_bias, &expr, &len, 1))
    1507                 :       {
    1508                 :       case 1:                   /* Should always happen.  */
    1509          116305 :         if (len > 0)
    1510          116305 :           break;
    1511                 :         /* Fall through.  */
    1512                 : 
    1513                 :       case 0:                   /* Shouldn't happen.  */
    1514               0 :         throw semantic_error ("not accessible at this address");
    1515                 : 
    1516                 :       default:                  /* Shouldn't happen.  */
    1517                 :       case -1:
    1518                 :         throw semantic_error (string ("dwarf_getlocation_addr failed") +
    1519               0 :                               string (dwarf_errmsg (-1)));
    1520                 :       }
    1521                 : 
    1522                 :     return c_translate_location (pool, &loc2c_error, this,
    1523                 :                                  &loc2c_emit_address,
    1524                 :                                  1, module_bias,
    1525          116305 :                                  pc, expr, len, tail, fb_attr);
    1526                 :   }
    1527                 : 
    1528                 :   void
    1529               2 :   print_members(Dwarf_Die *vardie, ostream &o)
    1530                 :   {
    1531               2 :     const int typetag = dwarf_tag (vardie);
    1532                 : 
    1533               2 :     if (typetag != DW_TAG_structure_type && typetag != DW_TAG_union_type)
    1534                 :       {
    1535                 :         o << " Error: "
    1536                 :           << (dwarf_diename_integrate (vardie) ?: "<anonymous>")
    1537               0 :           << " isn't a struct/union";
    1538               0 :         return;
    1539                 :       }
    1540                 : 
    1541                 :     // Try to get the first child of vardie.
    1542                 :     Dwarf_Die die_mem;
    1543               2 :     Dwarf_Die *die = &die_mem;
    1544               2 :     switch (dwarf_child (vardie, die))
    1545                 :       {
    1546                 :       case 1:                           // No children.
    1547                 :         o << ((typetag == DW_TAG_union_type) ? " union " : " struct ")
    1548                 :           << (dwarf_diename_integrate (die) ?: "<anonymous>")
    1549               0 :           << " is empty";
    1550               0 :         break;
    1551                 : 
    1552                 :       case -1:                          // Error.
    1553                 :       default:                          // Shouldn't happen.
    1554                 :         o << ((typetag == DW_TAG_union_type) ? " union " : " struct ")
    1555                 :           << (dwarf_diename_integrate (die) ?: "<anonymous>")
    1556               0 :           << ": " << dwarf_errmsg (-1);
    1557                 :         break;
    1558                 : 
    1559                 :       case 0:                           // Success.
    1560                 :         break;
    1561                 :       }
    1562                 : 
    1563                 :     // Output each sibling's name to 'o'.
    1564              23 :     while (dwarf_tag (die) == DW_TAG_member)
    1565                 :       {
    1566              21 :         const char *member = (dwarf_diename_integrate (die) ?: "<anonymous>");
    1567                 : 
    1568              21 :         o << " " << member;
    1569                 : 
    1570              21 :         if (dwarf_siblingof (die, &die_mem) != 0)
    1571               2 :           break;
    1572                 :       }
    1573                 :   }
    1574                 : 
    1575                 :   Dwarf_Die *
    1576                 :   translate_components(struct obstack *pool,
    1577                 :                        struct location **tail,
    1578                 :                        Dwarf_Addr pc,
    1579                 :                        vector<pair<target_symbol::component_type,
    1580                 :                        std::string> > const & components,
    1581                 :                        Dwarf_Die *vardie,
    1582                 :                        Dwarf_Die *die_mem,
    1583          115326 :                        Dwarf_Attribute *attr_mem)
    1584                 :   {
    1585          115326 :     Dwarf_Die *die = vardie;
    1586                 :     Dwarf_Die struct_die;
    1587          115326 :     unsigned i = 0;
    1588          233394 :     while (i < components.size())
    1589                 :       {
    1590            2746 :         die = dwarf_formref_die (attr_mem, die_mem);
    1591            2746 :         const int typetag = dwarf_tag (die);
    1592            2746 :         switch (typetag)
    1593                 :           {
    1594                 :           case DW_TAG_typedef:
    1595                 :           case DW_TAG_const_type:
    1596                 :           case DW_TAG_volatile_type:
    1597                 :             /* Just iterate on the referent type.  */
    1598              22 :             break;
    1599                 : 
    1600                 :           case DW_TAG_pointer_type:
    1601            1303 :             if (components[i].first == target_symbol::comp_literal_array_index)
    1602               1 :               throw semantic_error ("cannot index pointer");
    1603                 :             // XXX: of course, we should support this the same way C does,
    1604                 :             // by explicit pointer arithmetic etc.  PR4166.
    1605                 : 
    1606            1302 :             c_translate_pointer (pool, 1, module_bias, die, tail);
    1607            1302 :             break;
    1608                 : 
    1609                 :           case DW_TAG_array_type:
    1610               2 :             if (components[i].first == target_symbol::comp_literal_array_index)
    1611                 :               {
    1612                 :                 c_translate_array (pool, 1, module_bias, die, tail,
    1613               1 :                                    NULL, lex_cast<Dwarf_Word>(components[i].second));
    1614               1 :                 ++i;
    1615                 :               }
    1616                 :             else
    1617                 :               throw semantic_error("bad field '"
    1618                 :                                    + components[i].second
    1619               1 :                                    + "' for array type");
    1620               1 :             break;
    1621                 : 
    1622                 :           case DW_TAG_structure_type:
    1623                 :           case DW_TAG_union_type:
    1624            1419 :             struct_die = *die;
    1625            1419 :             switch (dwarf_child (die, die_mem))
    1626                 :               {
    1627                 :               case 1:           /* No children.  */
    1628                 :                 throw semantic_error ("empty struct "
    1629               0 :                                       + string (dwarf_diename_integrate (die) ?: "<anonymous>"));
    1630                 :                 break;
    1631                 :               case -1:          /* Error.  */
    1632                 :               default:          /* Shouldn't happen */
    1633                 :                 throw semantic_error (string (typetag == DW_TAG_union_type ? "union" : "struct")
    1634                 :                                       + string (dwarf_diename_integrate (die) ?: "<anonymous>")
    1635               0 :                                       + string (dwarf_errmsg (-1)));
    1636                 :                 break;
    1637                 : 
    1638                 :               case 0:
    1639                 :                 break;
    1640                 :               }
    1641                 : 
    1642           25145 :             while (dwarf_tag (die) != DW_TAG_member
    1643           11863 :                    || ({ const char *member = dwarf_diename_integrate (die);
    1644           11863 :                        member == NULL || string(member) != components[i].second; }))
    1645           10446 :               if (dwarf_siblingof (die, die_mem) != 0)
    1646                 :               {
    1647               2 :                   stringstream alternatives;
    1648               2 :                   print_members (&struct_die, alternatives);
    1649                 :                   throw semantic_error ("field '" + components[i].second
    1650                 :                                         + "' not found (alternatives:"
    1651               2 :                                         + alternatives.str () + ")");
    1652                 :               }
    1653                 : 
    1654            1417 :             if (dwarf_attr_integrate (die, DW_AT_data_member_location,
    1655                 :                                       attr_mem) == NULL)
    1656                 :               {
    1657                 :                 /* Union members don't usually have a location,
    1658                 :                    but just use the containing union's location.  */
    1659               0 :                 if (typetag != DW_TAG_union_type)
    1660                 :                   throw semantic_error ("no location for field '"
    1661                 :                                         + components[i].second
    1662               0 :                                         + "' :" + string(dwarf_errmsg (-1)));
    1663                 :               }
    1664                 :             else
    1665            1417 :               translate_location (pool, attr_mem, pc, NULL, tail);
    1666            1417 :             ++i;
    1667            1417 :             break;
    1668                 : 
    1669                 :           case DW_TAG_base_type:
    1670                 :             throw semantic_error ("field '"
    1671                 :                                   + components[i].second
    1672                 :                                   + "' vs. base type "
    1673               0 :                                   + string(dwarf_diename_integrate (die) ?: "<anonymous type>"));
    1674                 :             break;
    1675                 :           case -1:
    1676               0 :             throw semantic_error ("cannot find type: " + string(dwarf_errmsg (-1)));
    1677                 :             break;
    1678                 : 
    1679                 :           default:
    1680                 :             throw semantic_error (string(dwarf_diename_integrate (die) ?: "<anonymous type>")
    1681                 :                                   + ": unexpected type tag "
    1682               0 :                                   + lex_cast<string>(dwarf_tag (die)));
    1683                 :             break;
    1684                 :           }
    1685                 : 
    1686                 :         /* Now iterate on the type in DIE's attribute.  */
    1687            2742 :         if (dwarf_attr_integrate (die, DW_AT_type, attr_mem) == NULL)
    1688               0 :           throw semantic_error ("cannot get type of field: " + string(dwarf_errmsg (-1)));
    1689                 :       }
    1690          115322 :     return die;
    1691                 :   }
    1692                 : 
    1693                 : 
    1694                 :   Dwarf_Die *
    1695                 :   resolve_unqualified_inner_typedie (Dwarf_Die *typedie_mem,
    1696          165193 :                                      Dwarf_Attribute *attr_mem)
    1697                 :   {
    1698                 :     ;
    1699                 :     Dwarf_Die *typedie;
    1700          165193 :     int typetag = 0;
    1701           36044 :     while (1)
    1702                 :       {
    1703          201237 :         typedie = dwarf_formref_die (attr_mem, typedie_mem);
    1704          201237 :         if (typedie == NULL)
    1705               1 :           throw semantic_error ("cannot get type: " + string(dwarf_errmsg (-1)));
    1706          201236 :         typetag = dwarf_tag (typedie);
    1707          201236 :         if (typetag != DW_TAG_typedef &&
    1708                 :             typetag != DW_TAG_const_type &&
    1709                 :             typetag != DW_TAG_volatile_type)
    1710          165192 :           break;
    1711           36044 :         if (dwarf_attr_integrate (typedie, DW_AT_type, attr_mem) == NULL)
    1712               0 :           throw semantic_error ("cannot get type of pointee: " + string(dwarf_errmsg (-1)));
    1713                 :       }
    1714          165192 :     return typedie;
    1715                 :   }
    1716                 : 
    1717                 : 
    1718                 :   void
    1719                 :   translate_final_fetch_or_store (struct obstack *pool,
    1720                 :                                   struct location **tail,
    1721                 :                                   Dwarf_Addr module_bias,
    1722                 :                                   Dwarf_Die *die,
    1723                 :                                   Dwarf_Attribute *attr_mem,
    1724                 :                                   bool lvalue,
    1725                 :                                   string &,
    1726                 :                                   string &,
    1727          115322 :                                   exp_type & ty)
    1728                 :   {
    1729                 :     /* First boil away any qualifiers associated with the type DIE of
    1730                 :        the final location to be accessed.  */
    1731                 : 
    1732                 :     Dwarf_Die typedie_mem;
    1733                 :     Dwarf_Die *typedie;
    1734                 :     int typetag;
    1735                 :     char const *dname;
    1736          115322 :     string diestr;
    1737                 : 
    1738          115322 :     typedie = resolve_unqualified_inner_typedie (&typedie_mem, attr_mem);
    1739          115321 :     typetag = dwarf_tag (typedie);
    1740                 : 
    1741                 :     /* Then switch behavior depending on the type of fetch/store we
    1742                 :        want, and the type and pointer-ness of the final location. */
    1743                 : 
    1744          115321 :     switch (typetag)
    1745                 :       {
    1746                 :       default:
    1747               0 :         dname = dwarf_diename(die);
    1748               0 :         diestr = (dname != NULL) ? dname : "<unknown>";
    1749                 :         throw semantic_error ("unsupported type tag "
    1750                 :                               + lex_cast<string>(typetag)
    1751               0 :                               + " for " + diestr);
    1752                 :         break;
    1753                 : 
    1754                 :       case DW_TAG_structure_type:
    1755                 :       case DW_TAG_union_type:
    1756               1 :         dname = dwarf_diename(die);
    1757               1 :         diestr = (dname != NULL) ? dname : "<unknown>";
    1758                 :         throw semantic_error ("struct/union '" + diestr
    1759               1 :                               + "' is being accessed instead of a member of the struct/union");
    1760                 :         break;
    1761                 : 
    1762                 :       case DW_TAG_enumeration_type:
    1763                 :       case DW_TAG_base_type:
    1764           65449 :         ty = pe_long;
    1765           65449 :         if (lvalue)
    1766                 :           c_translate_store (pool, 1, module_bias, die, typedie, tail,
    1767               3 :                              "THIS->value");
    1768                 :         else
    1769                 :           c_translate_fetch (pool, 1, module_bias, die, typedie, tail,
    1770           65446 :                              "THIS->__retvalue");
    1771           65449 :         break;
    1772                 : 
    1773                 :       case DW_TAG_array_type:
    1774                 :       case DW_TAG_pointer_type:
    1775                 : 
    1776                 :           {
    1777                 :           Dwarf_Die pointee_typedie_mem;
    1778                 :           Dwarf_Die *pointee_typedie;
    1779                 :           Dwarf_Word pointee_encoding;
    1780           49871 :           Dwarf_Word pointee_byte_size = 0;
    1781                 : 
    1782           49871 :           pointee_typedie = resolve_unqualified_inner_typedie (&pointee_typedie_mem, attr_mem);
    1783                 : 
    1784           49871 :           if (dwarf_attr_integrate (pointee_typedie, DW_AT_byte_size, attr_mem))
    1785           49839 :             dwarf_formudata (attr_mem, &pointee_byte_size);
    1786                 : 
    1787                 :           dwarf_formudata (dwarf_attr_integrate (pointee_typedie, DW_AT_encoding, attr_mem),
    1788           49871 :                            &pointee_encoding);
    1789                 : 
    1790           49871 :           if (lvalue)
    1791                 :             {
    1792               1 :               ty = pe_long;
    1793               1 :               if (typetag == DW_TAG_array_type)
    1794               0 :                 throw semantic_error ("cannot write to array address");
    1795               1 :               assert (typetag == DW_TAG_pointer_type);
    1796                 :               c_translate_pointer_store (pool, 1, module_bias, typedie, tail,
    1797               1 :                                          "THIS->value");
    1798                 :             }
    1799                 :           else
    1800                 :             {
    1801                 :               // We have the pointer: cast it to an integral type via &(*(...))
    1802                 :               
    1803                 :               // NB: per bug #1187, at one point char*-like types were
    1804                 :               // automagically converted here to systemtap string values.
    1805                 :               // For several reasons, this was taken back out, leaving
    1806                 :               // pointer-to-string "conversion" (copying) to tapset functions.
    1807                 :               
    1808           49870 :               ty = pe_long;
    1809           49870 :               if (typetag == DW_TAG_array_type)
    1810              32 :                 c_translate_array (pool, 1, module_bias, typedie, tail, NULL, 0);
    1811                 :               else
    1812           49838 :                 c_translate_pointer (pool, 1, module_bias, typedie, tail);
    1813                 :               c_translate_addressof (pool, 1, module_bias, NULL, pointee_typedie, tail,
    1814           49870 :                                      "THIS->__retvalue");
    1815                 :             }
    1816                 :           }
    1817                 :         break;
    1818          115322 :       }
    1819          115320 :   }
    1820                 : 
    1821                 :   string
    1822                 :   express_as_string (string prelude,
    1823                 :                      string postlude,
    1824          115320 :                      struct location *head)
    1825                 :   {
    1826          115320 :     size_t bufsz = 1024;
    1827          115320 :     char *buf = static_cast<char*>(malloc(bufsz));
    1828          115320 :     assert(buf);
    1829                 : 
    1830          115320 :     FILE *memstream = open_memstream (&buf, &bufsz);
    1831          115320 :     assert(memstream);
    1832                 : 
    1833          115320 :     fprintf(memstream, "{\n");
    1834          115320 :     fprintf(memstream, prelude.c_str());
    1835          115320 :     bool deref = c_emit_location (memstream, head, 1);
    1836          115320 :     fprintf(memstream, postlude.c_str());
    1837          115320 :     fprintf(memstream, "  goto out;\n");
    1838                 : 
    1839                 :     // dummy use of deref_fault label, to disable warning if deref() not used
    1840          115320 :     fprintf(memstream, "if (0) goto deref_fault;\n");
    1841                 : 
    1842                 :     // XXX: deref flag not reliable; emit fault label unconditionally
    1843                 :     (void) deref;
    1844                 :     fprintf(memstream,
    1845                 :             "deref_fault:\n"
    1846          115320 :             "  goto out;\n");
    1847          115320 :     fprintf(memstream, "}\n");
    1848                 : 
    1849          115320 :     fclose (memstream);
    1850          115320 :     string result(buf);
    1851          115320 :     free (buf);
    1852                 :     return result;
    1853                 :   }
    1854                 : 
    1855                 :   string
    1856                 :   literal_stmt_for_local (Dwarf_Die *scope_die,
    1857                 :                           Dwarf_Addr pc,
    1858                 :                           string const & local,
    1859                 :                           vector<pair<target_symbol::component_type,
    1860                 :                           std::string> > const & components,
    1861                 :                           bool lvalue,
    1862          114979 :                           exp_type & ty)
    1863                 :   {
    1864                 :     Dwarf_Die vardie;
    1865          114979 :     Dwarf_Attribute fb_attr_mem, *fb_attr = NULL;
    1866                 : 
    1867                 :     fb_attr = find_variable_and_frame_base (scope_die, pc, local,
    1868          114979 :                                             &vardie, &fb_attr_mem);
    1869                 : 
    1870          114974 :     if (sess.verbose>2)
    1871                 :       clog << "finding location for local '" << local
    1872                 :            << "' near address " << hex << pc
    1873                 :            << ", module bias " << module_bias << dec
    1874               0 :            << "\n";
    1875                 : 
    1876                 :     Dwarf_Attribute attr_mem;
    1877          114974 :     if (dwarf_attr_integrate (&vardie, DW_AT_location, &attr_mem) == NULL)
    1878                 :       {
    1879                 :         throw semantic_error("failed to retrieve location "
    1880                 :                              "attribute for local '" + local
    1881                 :                              + "' (dieoffset: "
    1882                 :                              + lex_cast_hex<string>(dwarf_dieoffset (&vardie))
    1883              86 :                              + ")");
    1884                 :       }
    1885                 : 
    1886                 : #define obstack_chunk_alloc malloc
    1887                 : #define obstack_chunk_free free
    1888                 : 
    1889                 :     struct obstack pool;
    1890          114888 :     obstack_init (&pool);
    1891          114888 :     struct location *tail = NULL;
    1892                 : 
    1893                 :     /* Given $foo->bar->baz[NN], translate the location of foo. */
    1894                 : 
    1895                 :     struct location *head = translate_location (&pool,
    1896          114888 :                                                 &attr_mem, pc, fb_attr, &tail);
    1897                 : 
    1898          114888 :     if (dwarf_attr_integrate (&vardie, DW_AT_type, &attr_mem) == NULL)
    1899                 :       throw semantic_error("failed to retrieve type "
    1900               0 :                            "attribute for local '" + local + "'");
    1901                 : 
    1902                 : 
    1903                 :     /* Translate the ->bar->baz[NN] parts. */
    1904                 : 
    1905          114888 :     Dwarf_Die die_mem, *die = NULL;
    1906                 :     die = translate_components (&pool, &tail, pc, components,
    1907          114888 :                                 &vardie, &die_mem, &attr_mem);
    1908                 : 
    1909                 :     /* Translate the assignment part, either
    1910                 :        x = $foo->bar->baz[NN]
    1911                 :        or
    1912                 :        $foo->bar->baz[NN] = x
    1913                 :     */
    1914                 : 
    1915          114884 :     string prelude, postlude;
    1916                 :     translate_final_fetch_or_store (&pool, &tail, module_bias,
    1917                 :                                     die, &attr_mem, lvalue,
    1918          114884 :                                     prelude, postlude, ty);
    1919                 : 
    1920                 :     /* Write the translation to a string. */
    1921          114883 :     return express_as_string(prelude, postlude, head);
    1922                 :   }
    1923                 : 
    1924                 : 
    1925                 :   string
    1926                 :   literal_stmt_for_return (Dwarf_Die *scope_die,
    1927                 :                            Dwarf_Addr pc,
    1928                 :                            vector<pair<target_symbol::component_type,
    1929                 :                            std::string> > const & components,
    1930                 :                            bool lvalue,
    1931             438 :                            exp_type & ty)
    1932                 :   {
    1933             438 :     if (sess.verbose>2)
    1934                 :         clog << "literal_stmt_for_return: finding return value for "
    1935                 :              << dwarf_diename (scope_die)
    1936                 :              << "("
    1937                 :              << dwarf_diename (cu)
    1938               0 :              << ")\n";
    1939                 : 
    1940                 :     struct obstack pool;
    1941             438 :     obstack_init (&pool);
    1942             438 :     struct location *tail = NULL;
    1943                 : 
    1944                 :     /* Given $return->bar->baz[NN], translate the location of return. */
    1945                 :     const Dwarf_Op *locops;
    1946                 :     int nlocops = dwfl_module_return_value_location (module, scope_die,
    1947             438 :                                                      &locops);
    1948             438 :     if (nlocops < 0)
    1949                 :       {
    1950               0 :         throw semantic_error("failed to retrieve return value location");
    1951                 :       }
    1952                 :     // the function has no return value (e.g. "void" in C)
    1953             438 :     else if (nlocops == 0)
    1954                 :       {
    1955               0 :         throw semantic_error("function has no return value");
    1956                 :       }
    1957                 : 
    1958                 :     struct location  *head = c_translate_location (&pool, &loc2c_error, this,
    1959                 :                                                    &loc2c_emit_address,
    1960                 :                                                    1, module_bias,
    1961                 :                                                    pc, locops, nlocops,
    1962             438 :                                                    &tail, NULL);
    1963                 : 
    1964                 :     /* Translate the ->bar->baz[NN] parts. */
    1965                 : 
    1966                 :     Dwarf_Attribute attr_mem;
    1967             438 :     Dwarf_Attribute *attr = dwarf_attr (scope_die, DW_AT_type, &attr_mem);
    1968                 : 
    1969                 :     Dwarf_Die vardie_mem;
    1970             438 :     Dwarf_Die *vardie = dwarf_formref_die (attr, &vardie_mem);
    1971                 : 
    1972             438 :     Dwarf_Die die_mem, *die = NULL;
    1973                 :     die = translate_components (&pool, &tail, pc, components,
    1974             438 :                                 vardie, &die_mem, &attr_mem);
    1975                 : 
    1976                 :     /* Translate the assignment part, either
    1977                 :        x = $return->bar->baz[NN]
    1978                 :        or
    1979                 :        $return->bar->baz[NN] = x
    1980                 :     */
    1981                 : 
    1982             438 :     string prelude, postlude;
    1983                 :     translate_final_fetch_or_store (&pool, &tail, module_bias,
    1984                 :                                     die, &attr_mem, lvalue,
    1985             438 :                                     prelude, postlude, ty);
    1986                 : 
    1987                 :     /* Write the translation to a string. */
    1988             437 :     return express_as_string(prelude, postlude, head);
    1989                 :   }
    1990                 : 
    1991                 : 
    1992             207 :   ~dwflpp()
    1993                 :   {
    1994             207 :     if (dwfl)
    1995             207 :       dwfl_end(dwfl);
    1996             207 :   }
    1997                 : };
    1998                 : 
    1999                 : 
    2000                 : enum
    2001                 : function_spec_type
    2002                 :   {
    2003                 :     function_alone,
    2004                 :     function_and_file,
    2005                 :     function_file_and_line
    2006                 :   };
    2007                 : 
    2008                 : 
    2009                 : struct dwarf_builder;
    2010                 : struct dwarf_query;
    2011                 : 
    2012                 : 
    2013                 : // XXX: This class is a candidate for subclassing to separate
    2014                 : // the relocation vs non-relocation variants.  Likewise for
    2015                 : // kprobe vs kretprobe variants.
    2016                 : 
    2017                 : struct dwarf_derived_probe: public derived_probe
    2018               0 : {
    2019                 :   dwarf_derived_probe (const string& function,
    2020                 :                        const string& filename,
    2021                 :                        int line,
    2022                 :                        const string& module,
    2023                 :                        const string& section,
    2024                 :                        Dwarf_Addr dwfl_addr,
    2025                 :                        Dwarf_Addr addr,
    2026                 :                        dwarf_query & q,
    2027                 :                        Dwarf_Die* scope_die);
    2028                 : 
    2029                 :   string module;
    2030                 :   string section;
    2031                 :   Dwarf_Addr addr;
    2032                 :   bool has_return;
    2033                 :   bool has_maxactive;
    2034                 :   long maxactive_val;
    2035                 : 
    2036                 :   void printsig (std::ostream &o) const;
    2037                 : 
    2038                 :   void join_group (systemtap_session& s);
    2039                 : 
    2040                 :   // Pattern registration helpers.
    2041                 :   static void register_statement_variants(match_node * root,
    2042                 :                                           dwarf_builder * dw);
    2043                 :   static void register_function_variants(match_node * root,
    2044                 :                                           dwarf_builder * dw);
    2045                 :   static void register_function_and_statement_variants(match_node * root,
    2046                 :                                                        dwarf_builder * dw);
    2047                 :   static void register_patterns(match_node * root);
    2048                 : };
    2049                 : 
    2050                 : 
    2051                 : struct dwarf_derived_probe_group: public derived_probe_group
    2052             192 : {
    2053                 : private:
    2054                 :   multimap<string,dwarf_derived_probe*> probes_by_module;
    2055                 :   typedef multimap<string,dwarf_derived_probe*>::iterator p_b_m_iterator;
    2056                 : 
    2057                 : public:
    2058                 :   void enroll (dwarf_derived_probe* probe);
    2059                 :   void emit_module_decls (systemtap_session& s);
    2060                 :   void emit_module_init (systemtap_session& s);
    2061                 :   void emit_module_exit (systemtap_session& s);
    2062                 : };
    2063                 : 
    2064                 : 
    2065                 : // Helper struct to thread through the dwfl callbacks.
    2066                 : struct base_query
    2067                 : {
    2068                 :   base_query(systemtap_session & sess,
    2069                 :              probe * base_probe,
    2070                 :              probe_point * base_loc,
    2071                 :              dwflpp & dw,
    2072                 :              map<string, literal *> const & params,
    2073                 :              vector<derived_probe *> & results);
    2074           54599 :   virtual ~base_query() {}
    2075                 : 
    2076                 :   systemtap_session & sess;
    2077                 :   probe * base_probe;
    2078                 :   probe_point * base_loc;
    2079                 :   dwflpp & dw;
    2080                 :   vector<derived_probe *> & results;
    2081                 : 
    2082                 :   // Parameter extractors.
    2083                 :   static bool has_null_param(map<string, literal *> const & params,
    2084                 :                              string const & k);
    2085                 :   static bool get_string_param(map<string, literal *> const & params,
    2086                 :                                string const & k, string & v);
    2087                 :   static bool get_number_param(map<string, literal *> const & params,
    2088                 :                                string const & k, long & v);
    2089                 :   static bool get_number_param(map<string, literal *> const & params,
    2090                 :                                string const & k, Dwarf_Addr & v);
    2091                 : 
    2092                 :   // Extracted parameters.
    2093                 :   bool has_kernel;
    2094                 :   string module_val; // has_kernel => module_val = "kernel"
    2095                 : 
    2096                 :   virtual void handle_query_module() = 0;
    2097                 : };
    2098                 : 
    2099                 : 
    2100                 : base_query::base_query(systemtap_session & sess,
    2101                 :                        probe * base_probe,
    2102                 :                        probe_point * base_loc,
    2103                 :                        dwflpp & dw,
    2104                 :                        map<string, literal *> const & params,
    2105           54599 :                        vector<derived_probe *> & results)
    2106                 :   : sess(sess), base_probe(base_probe), base_loc(base_loc), dw(dw),
    2107           54599 :     results(results)
    2108                 : {
    2109           54599 :   has_kernel = has_null_param(params, TOK_KERNEL);
    2110           54599 :   if (has_kernel)
    2111           54016 :     module_val = "kernel";
    2112                 :   else
    2113                 :     {
    2114             583 :       bool has_module = get_string_param(params, TOK_MODULE, module_val);
    2115             583 :       assert (has_module); // no other options are possible by construction
    2116                 :     }
    2117           54599 : }
    2118                 : 
    2119                 : bool
    2120                 : base_query::has_null_param(map<string, literal *> const & params,
    2121          272995 :                            string const & k)
    2122                 : {
    2123          272995 :   return derived_probe_builder::has_null_param(params, k);
    2124                 : }
    2125                 : 
    2126                 : 
    2127                 : bool
    2128                 : base_query::get_string_param(map<string, literal *> const & params,
    2129          109781 :                              string const & k, string & v)
    2130                 : {
    2131          109781 :   return derived_probe_builder::get_param (params, k, v);
    2132                 : }
    2133                 : 
    2134                 : 
    2135                 : bool
    2136                 : base_query::get_number_param(map<string, literal *> const & params,
    2137           54599 :                              string const & k, long & v)
    2138                 : {
    2139                 :   int64_t value;
    2140           54599 :   bool present = derived_probe_builder::get_param (params, k, value);
    2141           54599 :   v = (long) value;
    2142           54599 :   return present;
    2143                 : }
    2144                 : 
    2145                 : 
    2146                 : bool
    2147                 : base_query::get_number_param(map<string, literal *> const & params,
    2148          109198 :                              string const & k, Dwarf_Addr & v)
    2149                 : {
    2150                 :   int64_t value;
    2151          109198 :   bool present = derived_probe_builder::get_param (params, k, value);
    2152          109198 :   v = (Dwarf_Addr) value;
    2153          109198 :   return present;
    2154                 : }
    2155                 : 
    2156                 : 
    2157                 : struct dwarf_query : public base_query
    2158           54599 : {
    2159                 :   dwarf_query(systemtap_session & sess,
    2160                 :               probe * base_probe,
    2161                 :               probe_point * base_loc,
    2162                 :               dwflpp & dw,
    2163                 :               map<string, literal *> const & params,
    2164                 :               vector<derived_probe *> & results);
    2165                 : 
    2166                 :   virtual void handle_query_module();
    2167                 : 
    2168                 :   void add_probe_point(string const & funcname,
    2169                 :                        char const * filename,
    2170                 :                        int line,
    2171                 :                        Dwarf_Die *scope_die,
    2172                 :                        Dwarf_Addr addr);
    2173                 :   string get_blacklist_section(Dwarf_Addr addr);
    2174                 : 
    2175                 :   regex_t blacklist_func; // function/statement probes
    2176                 :   regex_t blacklist_func_ret; // only for .return probes
    2177                 :   regex_t blacklist_file; // file name
    2178                 :   void build_blacklist();
    2179                 : 
    2180                 :   bool blacklisted_p(const string& funcname,
    2181                 :                      const string& filename,
    2182                 :                      int line,
    2183                 :                      const string& module,
    2184                 :                      const string& section,
    2185                 :                      Dwarf_Addr addr);
    2186                 : 
    2187                 :   // Extracted parameters.
    2188                 :   string function_val;
    2189                 : 
    2190                 :   bool has_function_str;
    2191                 :   bool has_statement_str;
    2192                 :   bool has_function_num;
    2193                 :   bool has_statement_num;
    2194                 :   string statement_str_val;
    2195                 :   string function_str_val;
    2196                 :   Dwarf_Addr statement_num_val;
    2197                 :   Dwarf_Addr function_num_val;
    2198                 : 
    2199                 :   bool has_call;
    2200                 :   bool has_inline;
    2201                 :   bool has_return;
    2202                 : 
    2203                 :   bool has_maxactive;
    2204                 :   long maxactive_val;
    2205                 : 
    2206                 :   bool has_label;
    2207                 :   string label_val;
    2208                 : 
    2209                 :   bool has_relative;
    2210                 :   long relative_val;
    2211                 : 
    2212                 :   bool has_absolute;
    2213                 : 
    2214                 :   function_spec_type parse_function_spec(string & spec);
    2215                 :   function_spec_type spec_type;
    2216                 :   string function;
    2217                 :   string file;
    2218                 :   int line;
    2219                 : 
    2220                 :   set<char const *> filtered_srcfiles;
    2221                 : 
    2222                 :   // Map official entrypc -> func_info object
    2223                 :   map<Dwarf_Addr, inline_instance_info> filtered_inlines;
    2224                 :   map<Dwarf_Addr, func_info> filtered_functions;
    2225                 :   bool choose_next_line;
    2226                 :   Dwarf_Addr entrypc_for_next_line;
    2227                 : };
    2228                 : 
    2229                 : 
    2230                 : // This little test routine represents an unfortunate breakdown in
    2231                 : // abstraction between dwflpp (putatively, a layer right on top of
    2232                 : // elfutils), and dwarf_query (interpreting a systemtap probe point).
    2233                 : // It arises because we sometimes try to fix up slightly-off
    2234                 : // .statement() probes (something we find out in fairly low-level).
    2235                 : //
    2236                 : // An alternative would be to put some more intellgence into query_cu(),
    2237                 : // and have it print additional suggestions after finding that
    2238                 : // q->dw.iterate_over_srcfile_lines resulted in no new finished_results.
    2239                 : 
    2240                 : bool
    2241               2 : dwflpp::has_single_line_record (dwarf_query * q, char const * srcfile, int lineno)
    2242                 : {
    2243               2 :   if (lineno < 0)
    2244               0 :     return false;
    2245                 : 
    2246               2 :     Dwarf_Line **srcsp = NULL;
    2247               2 :     size_t nsrcs = 0;
    2248                 : 
    2249                 :     dwarf_assert ("dwarf_getsrc_file",
    2250                 :                   dwarf_getsrc_file (module_dwarf,
    2251                 :                                      srcfile, lineno, 0,
    2252               2 :                                      &srcsp, &nsrcs));
    2253                 : 
    2254               2 :     if (nsrcs != 1)
    2255                 :       {
    2256               0 :         if (sess.verbose>4)
    2257               0 :           clog << "alternative line " << lineno << " rejected: nsrcs=" << nsrcs << endl;
    2258               0 :         return false;
    2259                 :       }
    2260                 : 
    2261                 :     // We also try to filter out lines that leave the selected
    2262                 :     // functions (if any).
    2263                 : 
    2264               2 :     Dwarf_Line *line = srcsp[0];
    2265                 :     Dwarf_Addr addr;
    2266               2 :     dwarf_lineaddr (line, &addr);
    2267                 : 
    2268               2 :     for (map<Dwarf_Addr, func_info>::iterator i = q->filtered_functions.begin();
    2269                 :          i != q->filtered_functions.end(); ++i)
    2270                 :       {
    2271               2 :         if (q->dw.die_has_pc (&(i->second.die), addr))
    2272                 :           {
    2273               2 :             if (q->sess.verbose>4)
    2274               0 :               clog << "alternative line " << lineno << " accepted: fn=" << i->second.name << endl;
    2275               2 :             return true;
    2276                 :           }
    2277                 :       }
    2278                 : 
    2279               0 :     for (map<Dwarf_Addr, inline_instance_info>::iterator i = q->filtered_inlines.begin();
    2280                 :          i != q->filtered_inlines.end(); ++i)
    2281                 :       {
    2282               0 :         if (q->dw.die_has_pc (&(i->second.die), addr))
    2283                 :           {
    2284               0 :             if (sess.verbose>4)
    2285               0 :               clog << "alternative line " << lineno << " accepted: ifn=" << i->second.name << endl;
    2286               0 :             return true;
    2287                 :           }
    2288                 :       }
    2289                 : 
    2290               0 :     if (sess.verbose>4)
    2291               0 :       clog << "alternative line " << lineno << " rejected: leaves selected fns" << endl;
    2292               0 :     return false;
    2293                 :   }
    2294                 : 
    2295                 : 
    2296                 : 
    2297                 : struct dwarf_builder: public derived_probe_builder
    2298                 : {
    2299                 :   dwflpp *kern_dw;
    2300             485 :   dwarf_builder(): kern_dw(0) {}
    2301                 : 
    2302           12100 :   void build_no_more (systemtap_session &s)
    2303                 :   {
    2304           12100 :     if (kern_dw)
    2305                 :       {
    2306             207 :         if (s.verbose > 3)
    2307               0 :           clog << "dwarf_builder releasing dwflpp" << endl;
    2308             207 :         delete kern_dw;
    2309             207 :         kern_dw = 0;
    2310                 :       }
    2311           12100 :   }
    2312                 : 
    2313               0 :   ~dwarf_builder()
    2314               0 :   {
    2315                 :     // XXX: in practice, NOTREACHED
    2316               0 :     delete kern_dw;
    2317               0 :   }
    2318                 : 
    2319                 :   virtual void build(systemtap_session & sess,
    2320                 :                      probe * base,
    2321                 :                      probe_point * location,
    2322                 :                      std::map<std::string, literal *> const & parameters,
    2323                 :                      vector<derived_probe *> & finished_results);
    2324                 : };
    2325                 : 
    2326                 : 
    2327                 : dwarf_query::dwarf_query(systemtap_session & sess,
    2328                 :                          probe * base_probe,
    2329                 :                          probe_point * base_loc,
    2330                 :                          dwflpp & dw,
    2331                 :                          map<string, literal *> const & params,
    2332           54599 :                          vector<derived_probe *> & results)
    2333           54599 :   : base_query(sess, base_probe, base_loc, dw, params, results)
    2334                 : {
    2335                 :   // Reduce the query to more reasonable semantic values (booleans,
    2336                 :   // extracted strings, numbers, etc).
    2337           54599 :   has_function_str = get_string_param(params, TOK_FUNCTION, function_str_val);
    2338           54599 :   has_function_num = get_number_param(params, TOK_FUNCTION, function_num_val);
    2339                 : 
    2340           54599 :   has_statement_str = get_string_param(params, TOK_STATEMENT, statement_str_val);
    2341           54599 :   has_statement_num = get_number_param(params, TOK_STATEMENT, statement_num_val);
    2342                 : 
    2343           54599 :   has_call = has_null_param(params, TOK_CALL);
    2344           54599 :   has_inline = has_null_param(params, TOK_INLINE);
    2345           54599 :   has_return = has_null_param(params, TOK_RETURN);
    2346           54599 :   has_maxactive = get_number_param(params, TOK_MAXACTIVE, maxactive_val);
    2347           54599 :   has_absolute = has_null_param(params, TOK_ABSOLUTE);
    2348                 : 
    2349           54599 :   if (has_function_str)
    2350           54584 :     spec_type = parse_function_spec(function_str_val);
    2351              15 :   else if (has_statement_str)
    2352              10 :     spec_type = parse_function_spec(statement_str_val);
    2353                 : 
    2354           54599 :   build_blacklist(); // XXX: why not reuse amongst dwarf_query instances?
    2355           54599 : }
    2356                 : 
    2357                 : 
    2358                 : void
    2359           61193 : dwarf_query::handle_query_module()
    2360                 : {
    2361           61194 :   if (has_function_num || has_statement_num)
    2362                 :     {
    2363                 :       // If we have module("foo").function(0xbeef) or
    2364                 :       // module("foo").statement(0xbeef), the address is relative
    2365                 :       // to the start of the module, so we seek the function
    2366                 :       // number plus the module's bias.
    2367                 : 
    2368                 :       Dwarf_Addr addr;
    2369               1 :       if (has_function_num)
    2370               0 :         addr = function_num_val;
    2371                 :       else
    2372               1 :         addr = statement_num_val;
    2373                 : 
    2374                 :       // NB: we don't need to add the module base address or bias
    2375                 :       // value here (for reasons that may be coincidental).
    2376               1 :       dw.query_cu_containing_module_address(addr, this);
    2377                 :     }
    2378                 :   else
    2379                 :     {
    2380                 :       // Otherwise if we have a function("foo") or statement("foo")
    2381                 :       // specifier, we have to scan over all the CUs looking for
    2382                 :       // the function(s) in question
    2383           61192 :       assert(has_function_str || has_statement_str);
    2384           61192 :       dw.iterate_over_cus(&query_cu, this);
    2385                 :     }
    2386           61193 : }
    2387                 : 
    2388                 : 
    2389                 : void
    2390           54599 : dwarf_query::build_blacklist()
    2391                 : {
    2392                 :   // We build up the regexps in these strings
    2393                 : 
    2394                 :   // Add ^ anchors at the front; $ will be added just before regcomp.
    2395                 : 
    2396           54599 :   string blfn = "^(";
    2397          109198 :   string blfn_ret = "^(";
    2398          109198 :   string blfile = "^(";
    2399                 : 
    2400           54599 :   blfile += "kernel/kprobes.c"; // first alternative, no "|"
    2401           54599 :   blfile += "|arch/.*/kernel/kprobes.c";
    2402                 : 
    2403                 :   // XXX: it would be nice if these blacklisted functions were pulled
    2404                 :   // in dynamically, instead of being statically defined here.
    2405                 :   // Perhaps it could be populated from script files.  A "noprobe
    2406                 :   // kernel.function("...")"  construct might do the trick.
    2407                 : 
    2408                 :   // Most of these are marked __kprobes in newer kernels.  We list
    2409                 :   // them here (anyway) so the translator can block them on older
    2410                 :   // kernels that don't have the __kprobes function decorator.  This
    2411                 :   // also allows detection of problems at translate- rather than
    2412                 :   // run-time.
    2413                 : 
    2414           54599 :   blfn += "atomic_notifier_call_chain"; // first blfn; no "|"
    2415           54599 :   blfn += "|default_do_nmi";
    2416           54599 :   blfn += "|__die";
    2417           54599 :   blfn += "|die_nmi";
    2418           54599 :   blfn += "|do_debug";
    2419           54599 :   blfn += "|do_general_protection";
    2420           54599 :   blfn += "|do_int3";
    2421           54599 :   blfn += "|do_IRQ";
    2422           54599 :   blfn += "|do_page_fault";
    2423           54599 :   blfn += "|do_sparc64_fault";
    2424           54599 :   blfn += "|do_trap";
    2425           54599 :   blfn += "|dummy_nmi_callback";
    2426           54599 :   blfn += "|flush_icache_range";
    2427           54599 :   blfn += "|ia64_bad_break";
    2428           54599 :   blfn += "|ia64_do_page_fault";
    2429           54599 :   blfn += "|ia64_fault";
    2430           54599 :   blfn += "|io_check_error";
    2431           54599 :   blfn += "|mem_parity_error";
    2432           54599 :   blfn += "|nmi_watchdog_tick";
    2433           54599 :   blfn += "|notifier_call_chain";
    2434           54599 :   blfn += "|oops_begin";
    2435           54599 :   blfn += "|oops_end";
    2436           54599 :   blfn += "|program_check_exception";
    2437           54599 :   blfn += "|single_step_exception";
    2438           54599 :   blfn += "|sync_regs";
    2439           54599 :   blfn += "|unhandled_fault";
    2440           54599 :   blfn += "|unknown_nmi_error";
    2441                 : 
    2442                 :   // Lots of locks
    2443           54599 :   blfn += "|.*raw_.*lock.*";
    2444           54599 :   blfn += "|.*read_.*lock.*";
    2445           54599 :   blfn += "|.*write_.*lock.*";
    2446           54599 :   blfn += "|.*spin_.*lock.*";
    2447           54599 :   blfn += "|.*rwlock_.*lock.*";
    2448           54599 :   blfn += "|.*rwsem_.*lock.*";
    2449           54599 :   blfn += "|.*mutex_.*lock.*";
    2450           54599 :   blfn += "|raw_.*";
    2451           54599 :   blfn += "|.*seq_.*lock.*";
    2452                 : 
    2453                 :   // Experimental
    2454           54599 :   blfn += "|.*apic.*|.*APIC.*";
    2455           54599 :   blfn += "|.*softirq.*";
    2456           54599 :   blfn += "|.*IRQ.*";
    2457           54599 :   blfn += "|.*_intr.*";
    2458           54599 :   blfn += "|__delay";
    2459           54599 :   blfn += "|.*kernel_text.*";
    2460           54599 :   blfn += "|get_current";
    2461           54599 :   blfn += "|current_.*";
    2462           54599 :   blfn += "|.*exception_tables.*";
    2463           54599 :   blfn += "|.*setup_rt_frame.*";
    2464                 : 
    2465                 :   // PR 5759, CONFIG_PREEMPT kernels
    2466           54599 :   blfn += "|.*preempt_count.*";
    2467           54599 :   blfn += "|preempt_schedule";
    2468                 : 
    2469                 :   // These functions don't return, so return probes would never be recovered
    2470           54599 :   blfn_ret += "do_exit"; // no "|"
    2471           54599 :   blfn_ret += "|sys_exit";
    2472           54599 :   blfn_ret += "|sys_exit_group";
    2473                 : 
    2474                 :   // __switch_to changes "current" on x86_64 and i686, so return probes
    2475                 :   // would cause kernel panic, and it is marked as "__kprobes" on x86_64
    2476           54599 :   if (sess.architecture == "x86_64")
    2477           54599 :     blfn += "|__switch_to";
    2478           54599 :   if (sess.architecture == "i686")
    2479               0 :     blfn_ret += "|__switch_to";
    2480                 : 
    2481           54599 :   blfn += ")$";
    2482           54599 :   blfn_ret += ")$";
    2483           54599 :   blfile += ")$";
    2484                 : 
    2485           54599 :   if (sess.verbose > 2) 
    2486                 :     {
    2487               0 :       clog << "blacklist regexps:" << endl;
    2488               0 :       clog << "blfn: " << blfn << endl;
    2489               0 :       clog << "blfn_ret: " << blfn_ret << endl;
    2490               0 :       clog << "blfile: " << blfile << endl;
    2491                 :     }
    2492                 : 
    2493           54599 :   int rc = regcomp (& blacklist_func, blfn.c_str(), REG_NOSUB|REG_EXTENDED);
    2494           54599 :   if (rc) throw semantic_error ("blacklist_func regcomp failed");
    2495           54599 :   rc = regcomp (& blacklist_func_ret, blfn_ret.c_str(), REG_NOSUB|REG_EXTENDED);
    2496           54599 :   if (rc) throw semantic_error ("blacklist_func_ret regcomp failed");
    2497           54599 :   rc = regcomp (& blacklist_file, blfile.c_str(), REG_NOSUB|REG_EXTENDED);
    2498           54599 :   if (rc) throw semantic_error ("blacklist_file regcomp failed");
    2499           54599 : }
    2500                 : 
    2501                 : 
    2502                 : function_spec_type
    2503           54594 : dwarf_query::parse_function_spec(string & spec)
    2504                 : {
    2505           54594 :   string::const_iterator i = spec.begin(), e = spec.end();
    2506                 : 
    2507           54594 :   function.clear();
    2508           54594 :   file.clear();
    2509           54594 :   line = 0;
    2510                 : 
    2511          863449 :   while (i != e && *i != '@')
    2512                 :     {
    2513          754261 :       if (*i == ':')
    2514               0 :         goto bad;
    2515          754261 :       function += *i++;
    2516                 :     }
    2517                 : 
    2518           54594 :   if (i == e)
    2519                 :     {
    2520           54548 :       if (sess.verbose>2)
    2521                 :         clog << "parsed '" << spec
    2522                 :              << "' -> func '" << function
    2523               0 :              << "'\n";
    2524           54548 :       return function_alone;
    2525                 :     }
    2526                 : 
    2527              46 :   if (i++ == e)
    2528               0 :     goto bad;
    2529                 : 
    2530             820 :   while (i != e && *i != ':')
    2531             728 :     file += *i++;
    2532                 : 
    2533              46 :   if (i == e)
    2534                 :     {
    2535              37 :       if (sess.verbose>2)
    2536                 :         clog << "parsed '" << spec
    2537                 :              << "' -> func '"<< function
    2538                 :              << "', file '" << file
    2539               0 :              << "'\n";
    2540              37 :       return function_and_file;
    2541                 :     }
    2542                 : 
    2543               9 :   if (i++ == e)
    2544               0 :     goto bad;
    2545                 : 
    2546                 :   try
    2547                 :     {
    2548               9 :       line = lex_cast<int>(string(i, e));
    2549               9 :       if (sess.verbose>2)
    2550                 :         clog << "parsed '" << spec
    2551                 :              << "' -> func '"<< function
    2552                 :              << "', file '" << file
    2553               0 :              << "', line " << line << "\n";
    2554               9 :       return function_file_and_line;
    2555                 :     }
    2556               0 :   catch (runtime_error & exn)
    2557                 :     {
    2558               0 :       goto bad;
    2559                 :     }
    2560                 : 
    2561               0 :  bad:
    2562                 :     throw semantic_error("malformed specification '" + spec + "'",
    2563               0 :                          base_probe->tok);
    2564                 : }
    2565                 : 
    2566                 : 
    2567                 : // Forward declaration.
    2568                 : static int query_kernel_module (Dwfl_Module *, void **, const char *,
    2569                 :                                 Dwarf_Addr, void *);
    2570                 : 
    2571                 : 
    2572                 : // XXX: pull this into dwflpp
    2573                 : static bool
    2574          146184 : in_kprobes_function(systemtap_session& sess, Dwarf_Addr addr)
    2575                 : {
    2576          146184 :   if (sess.sym_kprobes_text_start != 0 && sess.sym_kprobes_text_end != 0)
    2577                 :     {
    2578                 :       // If the probe point address is anywhere in the __kprobes
    2579                 :       // address range, we can't use this probe point.
    2580          146184 :       if (addr >= sess.sym_kprobes_text_start && addr < sess.sym_kprobes_text_end)
    2581             667 :         return true;
    2582                 :     }
    2583          145517 :   return false;
    2584                 : }
    2585                 : 
    2586                 : 
    2587                 : bool
    2588                 : dwarf_query::blacklisted_p(const string& funcname,
    2589                 :                            const string& filename,
    2590                 :                            int,
    2591                 :                            const string& module,
    2592                 :                            const string& section,
    2593          535201 :                            Dwarf_Addr addr)
    2594                 : {
    2595          535201 :   if (section.substr(0, 6) == string(".init.") ||
    2596                 :       section.substr(0, 6) == string(".exit."))
    2597                 :     {
    2598                 :       // NB: module .exit. routines could be probed in theory:
    2599                 :       // if the exit handler in "struct module" is diverted,
    2600                 :       // first inserting the kprobes
    2601                 :       // then allowing the exit code to run
    2602                 :       // then removing these kprobes
    2603           14091 :       if (sess.verbose>1)
    2604               0 :         clog << " skipping - init/exit";
    2605           14091 :       return true;
    2606                 :     }
    2607                 : 
    2608                 :   // Check for function marked '__kprobes'.
    2609          521110 :   if (module == TOK_KERNEL && in_kprobes_function(sess, addr))
    2610                 :     {
    2611             667 :       if (sess.verbose>1)
    2612               0 :         clog << " skipping - __kprobes";
    2613             667 :       return true;
    2614                 :     }
    2615                 : 
    2616                 :   // Check probe point against blacklist.
    2617          520443 :   int goodfn = regexec (&blacklist_func, funcname.c_str(), 0, NULL, 0);
    2618          520443 :   if (has_return)
    2619           74543 :     goodfn = goodfn && regexec (&blacklist_func_ret, funcname.c_str(), 0, NULL, 0);
    2620          520443 :   int goodfile = regexec (&blacklist_file, filename.c_str(), 0, NULL, 0);
    2621                 : 
    2622          520443 :   if (! (goodfn && goodfile))
    2623                 :     {
    2624           33068 :       if (sess.verbose>1)
    2625               0 :         clog << " skipping - blacklisted";
    2626           33068 :       return true;
    2627                 :     }
    2628                 : 
    2629                 :   // This probe point is not blacklisted.
    2630          487375 :   return false;
    2631                 : }
    2632                 : 
    2633          150845 : string dwarf_query::get_blacklist_section(Dwarf_Addr addr)
    2634                 : {
    2635          150845 :        string blacklist_section;
    2636                 :        Dwarf_Addr bias;
    2637                 :        // We prefer dwfl_module_getdwarf to dwfl_module_getelf here,
    2638                 :        // because dwfl_module_getelf can force costly section relocations
    2639                 :        // we don't really need, while either will do for this purpose.
    2640                 :        Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (dw.module, &bias))
    2641          150845 :                    ?: dwfl_module_getelf (dw.module, &bias));
    2642                 : 
    2643          150845 :        Dwarf_Addr offset = addr - bias;
    2644          150845 :        if (elf)
    2645                 :         {
    2646          150845 :           Elf_Scn* scn = 0;
    2647                 :           size_t shstrndx;
    2648          150845 :           dw.dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx));
    2649          150845 :           while ((scn = elf_nextscn (elf, scn)) != NULL)
    2650                 :             {
    2651                 :               GElf_Shdr shdr_mem;
    2652       563833820 :               GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
    2653       563833820 :               if (! shdr) continue; // XXX error?
    2654                 : 
    2655       563833820 :               if (!(shdr->sh_flags & SHF_ALLOC))
    2656               0 :                 continue;
    2657                 : 
    2658       563833820 :               GElf_Addr start = shdr->sh_addr;
    2659       563833820 :               GElf_Addr end = start + shdr->sh_size;
    2660       563833820 :               if (! (offset >= start && offset < end))
    2661       563682975 :                 continue;
    2662                 : 
    2663          150845 :               blacklist_section =  elf_strptr (elf, shstrndx, shdr->sh_name);
    2664          150845 :               break;
    2665                 :             }
    2666                 :          }
    2667               0 :         return blacklist_section;
    2668                 : }
    2669                 : 
    2670                 : 
    2671                 : void
    2672                 : dwarf_query::add_probe_point(const string& funcname,
    2673                 :                              const char* filename,
    2674                 :                              int line,
    2675                 :                              Dwarf_Die* scope_die,
    2676          535201 :                              Dwarf_Addr addr)
    2677                 : {
    2678          535201 :   dwarf_derived_probe *probe = NULL;
    2679          535201 :   string reloc_section; // base section for relocation purposes
    2680          535201 :   Dwarf_Addr reloc_addr = addr; // relocated
    2681          535201 :   string blacklist_section; // linking section for blacklist purposes
    2682          535201 :   const string& module = dw.module_name; // "kernel" or other
    2683                 : 
    2684          535201 :   assert (! has_absolute); // already handled in dwarf_builder::build()
    2685                 : 
    2686          535201 :   if (dwfl_module_relocations (dw.module) > 0)
    2687                 :     {
    2688                 :       // This is arelocatable module; libdwfl already knows its
    2689                 :       // sections, so we can relativize addr.
    2690          535201 :       int idx = dwfl_module_relocate_address (dw.module, &reloc_addr);
    2691          535201 :       const char* r_s = dwfl_module_relocation_info (dw.module, idx, NULL);
    2692          535201 :       if (r_s)
    2693          535201 :         reloc_section = r_s;
    2694          535201 :       blacklist_section = reloc_section;
    2695                 : 
    2696          535201 :      if(reloc_section == "" && dwfl_module_relocations (dw.module) == 1)
    2697          150845 :         blacklist_section = this->get_blacklist_section(addr);
    2698                 :     }
    2699                 :   else
    2700                 :     {
    2701               0 :       blacklist_section = this->get_blacklist_section(addr);
    2702               0 :       reloc_section = "";
    2703                 :     }
    2704                 : 
    2705          535201 :   if (sess.verbose > 1)
    2706                 :     {
    2707               2 :       clog << "probe " << funcname << "@" << filename << ":" << line;
    2708               2 :       if (string(module) == TOK_KERNEL)
    2709               2 :         clog << " kernel";
    2710                 :       else
    2711               0 :         clog << " module=" << module;
    2712               2 :       if (reloc_section != "") clog << " reloc=" << reloc_section;
    2713               2 :       if (blacklist_section != "") clog << " section=" << blacklist_section;
    2714               2 :       clog << " pc=0x" << hex << addr << dec;
    2715                 :     }
    2716                 : 
    2717          535201 :   bool bad = blacklisted_p (funcname, filename, line, module, blacklist_section, addr);
    2718          535201 :   if (sess.verbose > 1)
    2719               2 :     clog << endl;
    2720                 : 
    2721          535201 :   if (module == TOK_KERNEL)
    2722                 :     {
    2723                 :       // PR 4224: adapt to relocatable kernel by subtracting the _stext address here.
    2724          150845 :       reloc_addr = addr - sess.sym_stext;
    2725          150845 :       reloc_section = "_stext"; // a message to runtime's _stp_module_relocate
    2726                 :     }
    2727                 : 
    2728          535201 :   if (! bad)
    2729                 :     {
    2730                 :       probe = new dwarf_derived_probe(funcname, filename, line,
    2731          487378 :                                       module, reloc_section, addr, reloc_addr, *this, scope_die);
    2732          487372 :       results.push_back(probe);
    2733          535201 :     }
    2734          535198 : }
    2735                 : 
    2736                 : 
    2737                 : 
    2738                 : 
    2739                 : // The critical determining factor when interpreting a pattern
    2740                 : // string is, perhaps surprisingly: "presence of a lineno". The
    2741                 : // presence of a lineno changes the search strategy completely.
    2742                 : //
    2743                 : // Compare the two cases:
    2744                 : //
    2745                 : //   1. {statement,function}(foo@file.c:lineno)
    2746                 : //      - find the files matching file.c
    2747                 : //      - in each file, find the functions matching foo
    2748                 : //      - query the file for line records matching lineno
    2749                 : //      - iterate over the line records,
    2750                 : //        - and iterate over the functions,
    2751                 : //          - if(haspc(function.DIE, line.addr))
    2752                 : //            - if looking for statements: probe(lineno.addr)
    2753                 : //            - if looking for functions: probe(function.{entrypc,return,etc.})
    2754                 : //
    2755                 : //   2. {statement,function}(foo@file.c)
    2756                 : //      - find the files matching file.c
    2757                 : //      - in each file, find the functions matching foo
    2758                 : //        - probe(function.{entrypc,return,etc.})
    2759                 : //
    2760                 : // Thus the first decision we make is based on the presence of a
    2761                 : // lineno, and we enter entirely different sets of callbacks
    2762                 : // depending on that decision.
    2763                 : //
    2764                 : // Note that the first case is a generalization fo the second, in that
    2765                 : // we could theoretically search through line records for matching
    2766                 : // file names (a "table scan" in rdbms lingo).  Luckily, file names
    2767                 : // are already cached elsewhere, so we can do an "index scan" as an
    2768                 : // optimization.
    2769                 : 
    2770                 : static void
    2771                 : query_statement (string const & func,
    2772                 :                  char const * file,
    2773                 :                  int line,
    2774                 :                  Dwarf_Die *scope_die,
    2775                 :                  Dwarf_Addr stmt_addr,
    2776          535201 :                  dwarf_query * q)
    2777                 : {
    2778                 :   try
    2779                 :     {
    2780                 :       q->add_probe_point(func, file ? file : "?",
    2781          535201 :                          line, scope_die, stmt_addr);
    2782                 :     }
    2783               6 :   catch (const semantic_error& e)
    2784                 :     {
    2785               3 :       q->sess.print_error (e);
    2786                 :     }
    2787          535201 : }
    2788                 : 
    2789                 : static void
    2790                 : query_inline_instance_info (Dwarf_Addr entrypc,
    2791                 :                             inline_instance_info & ii,
    2792          323781 :                             dwarf_query * q)
    2793                 : {
    2794                 :   try
    2795                 :     {
    2796          323781 :       if (q->has_return)
    2797                 :         {
    2798               0 :           throw semantic_error ("cannot probe .return of inline function '" + ii.name + "'");
    2799                 :         }
    2800                 :       else
    2801                 :         {
    2802          323781 :           if (q->sess.verbose>2)
    2803                 :             clog << "querying entrypc "
    2804                 :                  << hex << entrypc << dec
    2805               0 :                  << " of instance of inline '" << ii.name << "'\n";
    2806                 :           query_statement (ii.name, ii.decl_file, ii.decl_line,
    2807          323781 :                            &ii.die, entrypc, q);
    2808                 :         }
    2809                 :     }
    2810               0 :   catch (semantic_error &e)
    2811                 :     {
    2812               0 :       q->sess.print_error (e);
    2813                 :     }
    2814          323781 : }
    2815                 : 
    2816                 : static void
    2817                 : query_func_info (Dwarf_Addr entrypc,
    2818                 :                  func_info & fi,
    2819          211412 :                  dwarf_query * q)
    2820                 : {
    2821                 :   try
    2822                 :     {
    2823          211412 :       if (q->has_return)
    2824                 :         {
    2825                 :           // NB. dwarf_derived_probe::emit_registrations will emit a
    2826                 :           // kretprobe based on the entrypc in this case.
    2827                 :           query_statement (fi.name, fi.decl_file, fi.decl_line,
    2828           77682 :                            &fi.die, entrypc, q);
    2829                 :         }
    2830                 :       else
    2831                 :         {
    2832          133732 :           if (q->sess.prologue_searching
    2833                 :               && !q->has_statement_str && !q->has_statement_num) // PR 2608
    2834                 :             {
    2835               2 :               if (fi.prologue_end == 0)
    2836                 :                 throw semantic_error("could not find prologue-end "
    2837               0 :                                      "for probed function '" + fi.name + "'");
    2838                 :               query_statement (fi.name, fi.decl_file, fi.decl_line,
    2839               2 :                                &fi.die, fi.prologue_end, q);
    2840                 :             }
    2841                 :           else
    2842                 :             {
    2843                 :               query_statement (fi.name, fi.decl_file, fi.decl_line,
    2844          133728 :                                &fi.die, entrypc, q);
    2845                 :             }
    2846                 :         }
    2847                 :     }
    2848               0 :   catch (semantic_error &e)
    2849                 :     {
    2850               0 :       q->sess.print_error (e);
    2851                 :     }
    2852          211412 : }
    2853                 : 
    2854                 : 
    2855                 : static void
    2856               8 : query_srcfile_line (Dwarf_Line * line, void * arg)
    2857                 : {
    2858               8 :   dwarf_query * q = static_cast<dwarf_query *>(arg);
    2859                 : 
    2860                 :   Dwarf_Addr addr;
    2861               8 :   dwarf_lineaddr(line, &addr);
    2862                 : 
    2863                 :   int lineno;
    2864               8 :   dwarf_lineno (line, &lineno);
    2865                 : 
    2866              16 :   for (map<Dwarf_Addr, func_info>::iterator i = q->filtered_functions.begin();
    2867                 :        i != q->filtered_functions.end(); ++i)
    2868                 :     {
    2869               8 :       if (q->dw.die_has_pc (&(i->second.die), addr))
    2870                 :         {
    2871               8 :           if (q->sess.verbose>3)
    2872               0 :             clog << "function DIE lands on srcfile\n";
    2873               8 :           if (q->has_statement_str)
    2874                 :             query_statement (i->second.name, i->second.decl_file,
    2875                 :                              lineno, // NB: not q->line !
    2876               8 :                              &(i->second.die), addr, q);
    2877                 :           else
    2878               0 :             query_func_info (i->first, i->second, q);
    2879                 :         }
    2880                 :     }
    2881                 : 
    2882               8 :   for (map<Dwarf_Addr, inline_instance_info>::iterator i
    2883               8 :          = q->filtered_inlines.begin();
    2884                 :        i != q->filtered_inlines.end(); ++i)
    2885                 :     {
    2886               0 :       if (q->dw.die_has_pc (&(i->second.die), addr))
    2887                 :         {
    2888               0 :           if (q->sess.verbose>3)
    2889               0 :             clog << "inline instance DIE lands on srcfile\n";
    2890               0 :           if (q->has_statement_str)
    2891                 :             query_statement (i->second.name, i->second.decl_file,
    2892               0 :                              q->line, &(i->second.die), addr, q);
    2893                 :           else
    2894               0 :             query_inline_instance_info (i->first, i->second, q);
    2895                 :         }
    2896                 :     }
    2897               8 : }
    2898                 : 
    2899                 : 
    2900                 : static int
    2901          386630 : query_dwarf_inline_instance (Dwarf_Die * die, void * arg)
    2902                 : {
    2903          386630 :   dwarf_query * q = static_cast<dwarf_query *>(arg);
    2904          386630 :   assert (!q->has_statement_num);
    2905                 : 
    2906                 :   try
    2907                 :     {
    2908          386630 :       if (q->sess.verbose>2)
    2909               0 :         clog << "examining inline instance of " << q->dw.function_name << "\n";
    2910                 : 
    2911          386630 :       if ((q->has_function_str && ! q->has_call)
    2912                 :           || q->has_statement_str)
    2913                 :         {
    2914          386630 :           if (q->sess.verbose>2)
    2915                 :             clog << "selected inline instance of " << q->dw.function_name
    2916               0 :                  << "\n";
    2917                 : 
    2918                 :           Dwarf_Addr entrypc;
    2919          386630 :           if (q->dw.die_entrypc (die, &entrypc))
    2920                 :             {
    2921          386630 :               inline_instance_info inl;
    2922          386630 :               inl.die = *die;
    2923          386630 :               inl.name = q->dw.function_name;
    2924          386630 :               q->dw.function_file (&inl.decl_file);
    2925          386630 :               q->dw.function_line (&inl.decl_line);
    2926          386630 :               q->filtered_inlines[entrypc] = inl;
    2927                 :             }
    2928                 :         }
    2929          386630 :       return DWARF_CB_OK;
    2930                 :     }
    2931               0 :   catch (const semantic_error& e)
    2932                 :     {
    2933               0 :       q->sess.print_error (e);
    2934               0 :       return DWARF_CB_ABORT;
    2935                 :     }
    2936                 : }
    2937                 : 
    2938                 : static int
    2939      1505482799 : query_dwarf_func (Dwarf_Die * func, void * arg)
    2940                 : {
    2941      1505482799 :   dwarf_query * q = static_cast<dwarf_query *>(arg);
    2942                 : 
    2943                 :   try
    2944                 :     {
    2945      1505482799 :       q->dw.focus_on_function (func);
    2946                 : 
    2947      1505482799 :       if (q->dw.func_is_inline ()
    2948                 :           && (! q->has_call) && (! q->has_return)
    2949                 :           && (((q->has_statement_str || q->has_function_str)
    2950                 :                && q->dw.function_name_matches(q->function))))
    2951                 :         {
    2952          121380 :           if (q->sess.verbose>3)
    2953                 :             clog << "checking instances of inline " << q->dw.function_name
    2954               0 :                  << "\n";
    2955          121380 :           q->dw.iterate_over_inline_instances (query_dwarf_inline_instance, arg);
    2956                 : 
    2957          121380 :           if (q->dw.function_name_final_match (q->function))
    2958              30 :             return DWARF_CB_ABORT;
    2959                 :         }
    2960      1505361419 :       else if (!q->dw.func_is_inline () && (! q->has_inline))
    2961                 :         {
    2962       696707848 :           bool record_this_function = false;
    2963                 : 
    2964       696707848 :           if ((q->has_statement_str || q->has_function_str)
    2965                 :               && q->dw.function_name_matches(q->function))
    2966                 :             {
    2967          211420 :               record_this_function = true;
    2968                 :             }
    2969       696496428 :           else if (q->has_function_num || q->has_statement_num)
    2970                 :             {
    2971                 :               Dwarf_Addr query_addr =
    2972                 :                 q->dw.module_address_to_global(q->has_function_num ? q->function_num_val :
    2973                 :                                                q->has_statement_num ? q->statement_num_val :
    2974              15 :                                                (assert(0) , 0));
    2975                 :               Dwarf_Die d;
    2976              15 :               q->dw.function_die (&d);
    2977                 : 
    2978              15 :               if (q->dw.die_has_pc (&d, query_addr))
    2979               1 :                 record_this_function = true;
    2980                 :             }
    2981                 : 
    2982       696707848 :           if (record_this_function)
    2983                 :             {
    2984          211421 :               if (q->sess.verbose>2)
    2985               0 :                 clog << "selected function " << q->dw.function_name << "\n";
    2986                 : 
    2987          211421 :               func_info func;
    2988          211421 :               q->dw.function_die (&func.die);
    2989          211421 :               func.name = q->dw.function_name;
    2990          211421 :               q->dw.function_file (&func.decl_file);
    2991          211421 :               q->dw.function_line (&func.decl_line);
    2992                 : 
    2993          422841 :               if (q->has_function_num || q->has_function_str || q->has_statement_str)
    2994                 :                 {
    2995                 :                   Dwarf_Addr entrypc;
    2996          211420 :                   if (q->dw.function_entrypc (&entrypc))
    2997          211420 :                     q->filtered_functions[entrypc] = func;
    2998                 :                   else
    2999                 :                     throw semantic_error("no entrypc found for function '"
    3000               0 :                                          + q->dw.function_name + "'");
    3001                 :                 }
    3002               1 :               else if (q->has_statement_num)
    3003                 :                 {
    3004               1 :                   Dwarf_Addr probepc = q->statement_num_val;
    3005               1 :                   q->filtered_functions[probepc] = func;
    3006               1 :                   if (q->dw.function_name_final_match (q->function))
    3007           47684 :                     return DWARF_CB_ABORT;
    3008                 :                 }
    3009                 :               else
    3010               0 :                 assert(0);
    3011                 : 
    3012          211420 :               if (q->dw.function_name_final_match (q->function))
    3013           47682 :                 return DWARF_CB_ABORT;
    3014                 :             }
    3015                 :         }
    3016      1505435086 :       return DWARF_CB_OK;
    3017                 :     }
    3018               0 :   catch (const semantic_error& e)
    3019                 :     {
    3020               0 :       q->sess.print_error (e);
    3021               0 :       return DWARF_CB_ABORT;
    3022                 :     }
    3023                 : }
    3024                 : 
    3025                 : static int
    3026        51344637 : query_cu (Dwarf_Die * cudie, void * arg)
    3027                 : {
    3028        51344637 :   dwarf_query * q = static_cast<dwarf_query *>(arg);
    3029        51344637 :   if (pending_interrupts) return DWARF_CB_ABORT;
    3030                 : 
    3031                 :   try
    3032                 :     {
    3033        51344637 :       q->dw.focus_on_cu (cudie);
    3034                 : 
    3035                 :       if (false && q->sess.verbose>2)
    3036                 :         clog << "focused on CU '" << q->dw.cu_name
    3037                 :              << "', in module '" << q->dw.module_name << "'\n";
    3038                 : 
    3039        51344637 :       if (q->has_statement_str || q->has_statement_num
    3040                 :           || q->has_function_str || q->has_function_num)
    3041                 :         {
    3042        51344637 :           q->filtered_srcfiles.clear();
    3043        51344637 :           q->filtered_functions.clear();
    3044        51344637 :           q->filtered_inlines.clear();
    3045                 : 
    3046                 :           // In this path, we find "abstract functions", record
    3047                 :           // information about them, and then (depending on lineno
    3048                 :           // matching) possibly emit one or more of the function's
    3049                 :           // associated addresses. Unfortunately the control of this
    3050                 :           // cannot easily be turned inside out.
    3051                 : 
    3052        51344637 :           if ((q->has_statement_str || q->has_function_str)
    3053                 :               && (q->spec_type != function_alone))
    3054                 :             {
    3055                 :               // If we have a pattern string with a filename, we need
    3056                 :               // to elaborate the srcfile mask in question first.
    3057           34541 :               q->dw.collect_srcfiles_matching (q->file, q->filtered_srcfiles);
    3058                 : 
    3059                 :               // If we have a file pattern and *no* srcfile matches, there's
    3060                 :               // no need to look further into this CU, so skip.
    3061           34541 :               if (q->filtered_srcfiles.empty())
    3062           34502 :                 return DWARF_CB_OK;
    3063                 :             }
    3064                 : 
    3065                 :           // Pick up [entrypc, name, DIE] tuples for all the functions
    3066                 :           // matching the query, and fill in the prologue endings of them
    3067                 :           // all in a single pass.
    3068        51310135 :           q->dw.iterate_over_functions (query_dwarf_func, q);
    3069                 : 
    3070        51310135 :           if (q->sess.prologue_searching 
    3071                 :               && !q->has_statement_str && !q->has_statement_num) // PR 2608
    3072            1900 :             if (! q->filtered_functions.empty())
    3073               2 :               q->dw.resolve_prologue_endings (q->filtered_functions);
    3074                 : 
    3075        51310143 :           if ((q->has_statement_str || q->has_function_str)
    3076                 :               && (q->spec_type == function_file_and_line))
    3077                 :             {
    3078                 :               // If we have a pattern string with target *line*, we
    3079                 :               // have to look at lines in all the matched srcfiles.
    3080              17 :               for (set<char const *>::const_iterator i = q->filtered_srcfiles.begin();
    3081                 :                    i != q->filtered_srcfiles.end(); ++i)
    3082                 :                 q->dw.iterate_over_srcfile_lines (*i, q->line, q->has_statement_str,
    3083               9 :                                                   query_srcfile_line, q);
    3084                 :             }
    3085                 :           else
    3086                 :             {
    3087                 :               // Otherwise, simply probe all resolved functions.
    3088        51521538 :               for (map<Dwarf_Addr, func_info>::iterator i = q->filtered_functions.begin();
    3089                 :                    i != q->filtered_functions.end(); ++i)
    3090          211412 :                 query_func_info (i->first, i->second, q);
    3091                 : 
    3092                 :               // And all inline instances (if we're not excluding inlines with ".call")
    3093        51310126 :               if (! q->has_call)
    3094        51619592 :                 for (map<Dwarf_Addr, inline_instance_info>::iterator i
    3095        51295811 :                        = q->filtered_inlines.begin(); i != q->filtered_inlines.end(); ++i)
    3096          323781 :                   query_inline_instance_info (i->first, i->second, q);
    3097                 :             }
    3098                 :         }
    3099                 :       else
    3100                 :         {
    3101                 :           // Before PR 5787, we used to have this:
    3102                 : #if 0
    3103                 :           // Otherwise we have a statement number, and we can just
    3104                 :           // query it directly within this module.
    3105                 :           assert (q->has_statement_num);
    3106                 :           Dwarf_Addr query_addr = q->statement_num_val;
    3107                 :           query_addr = q->dw.module_address_to_global(query_addr);
    3108                 : 
    3109                 :           query_statement ("", "", -1, NULL, query_addr, q);
    3110                 : #endif
    3111                 :           // But now, we traverse CUs/functions even for
    3112                 :           // statement_num's, for blacklist sensitivity and $var
    3113                 :           // resolution purposes.
    3114                 : 
    3115               0 :           assert (0); // NOTREACHED
    3116                 :         }
    3117        51310134 :       return DWARF_CB_OK;
    3118                 :     }
    3119               2 :   catch (const semantic_error& e)
    3120                 :     {
    3121               1 :       q->sess.print_error (e);
    3122               2 :       return DWARF_CB_ABORT;
    3123                 :     }
    3124                 : }
    3125                 : 
    3126                 : 
    3127                 : static int
    3128                 : query_kernel_module (Dwfl_Module *mod,
    3129                 :                      void **,
    3130                 :                      const char *name,
    3131                 :                      Dwarf_Addr,
    3132        60004331 :                      void *arg)
    3133                 : {
    3134        60004331 :   if (TOK_KERNEL == name)
    3135                 :   {
    3136           54599 :     Dwfl_Module **m = (Dwfl_Module **)arg;
    3137                 : 
    3138           54599 :     *m = mod;
    3139           54599 :     return DWARF_CB_ABORT;
    3140                 :   }
    3141        59949732 :   return DWARF_CB_OK;
    3142                 : }
    3143                 : 
    3144                 : 
    3145                 : static int
    3146                 : query_module (Dwfl_Module *mod,
    3147                 :               void **,
    3148                 :               const char *name,
    3149                 :               Dwarf_Addr,
    3150        59557156 :               void *arg)
    3151                 : {
    3152        59557156 :   base_query * q = static_cast<base_query *>(arg);
    3153                 : 
    3154                 :   try
    3155                 :     {
    3156        59557156 :       q->dw.focus_on_module(mod);
    3157                 : 
    3158                 :       // If we have enough information in the pattern to skip a module and
    3159                 :       // the module does not match that information, return early.
    3160        59557156 :       if (!q->dw.module_name_matches(q->module_val))
    3161        59495957 :         return DWARF_CB_OK;
    3162                 : 
    3163                 :       // Don't allow module("*kernel*") type expressions to match the
    3164                 :       // elfutils module "kernel", which we refer to in the probe
    3165                 :       // point syntax exclusively as "kernel.*".
    3166           61199 :       if (q->dw.module_name == TOK_KERNEL && ! q->has_kernel)
    3167               6 :         return DWARF_CB_OK;
    3168                 : 
    3169                 :       // Validate the machine code in this elf file against the
    3170                 :       // session machine.  This is important, in case the wrong kind
    3171                 :       // of debuginfo is being automagically processed by elfutils.
    3172                 :       // While we can tell i686 apart from x86-64, unfortunately
    3173                 :       // we can't help confusing i586 vs i686 (both EM_386).
    3174                 : 
    3175                 :       Dwarf_Addr bias;
    3176                 :       // We prefer dwfl_module_getdwarf to dwfl_module_getelf here,
    3177                 :       // because dwfl_module_getelf can force costly section relocations
    3178                 :       // we don't really need, while either will do for this purpose.
    3179                 :       Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (mod, &bias))
    3180           61193 :                   ?: dwfl_module_getelf (mod, &bias));
    3181                 : 
    3182                 :       GElf_Ehdr ehdr_mem;
    3183           61193 :       GElf_Ehdr* em = gelf_getehdr (elf, &ehdr_mem);
    3184           61193 :       if (em == 0) { q->dw.dwfl_assert ("dwfl_getehdr", dwfl_errno()); }
    3185           61193 :       int elf_machine = em->e_machine;
    3186           61193 :       const char* debug_filename = "";
    3187           61193 :       const char* main_filename = "";
    3188                 :       (void) dwfl_module_info (mod, NULL, NULL,
    3189                 :                                NULL, NULL, NULL,
    3190                 :                                & main_filename,
    3191           61193 :                                & debug_filename);
    3192           61193 :       const string& sess_machine = q->sess.architecture;
    3193           61193 :       string expect_machine;
    3194                 : 
    3195           61193 :       switch (elf_machine)
    3196                 :         {
    3197               0 :         case EM_386: expect_machine = "i?86"; break; // accept e.g. i586
    3198           61193 :         case EM_X86_64: expect_machine = "x86_64"; break;
    3199               0 :         case EM_PPC: expect_machine = "ppc"; break;
    3200               0 :         case EM_PPC64: expect_machine = "ppc64"; break;
    3201               0 :         case EM_S390: expect_machine = "s390x"; break;
    3202               0 :         case EM_IA_64: expect_machine = "ia64"; break;
    3203               0 :         case EM_ARM: expect_machine = "armv*"; break;
    3204                 :           // XXX: fill in some more of these
    3205               0 :         default: expect_machine = "?"; break;
    3206                 :         }
    3207                 : 
    3208           61193 :       if (! debug_filename) debug_filename = main_filename;
    3209           61193 :       if (! debug_filename) debug_filename = name;
    3210                 : 
    3211           61193 :       if (fnmatch (expect_machine.c_str(), sess_machine.c_str(), 0) != 0)
    3212                 :         {
    3213               0 :           stringstream msg;
    3214                 :           msg << "ELF machine " << expect_machine << " (code " << elf_machine
    3215                 :               << ") mismatch with target " << sess_machine
    3216               0 :               << " in '" << debug_filename << "'";
    3217               0 :           throw semantic_error(msg.str ());
    3218                 :         }
    3219                 : 
    3220           61193 :       if (q->sess.verbose>2)
    3221                 :         clog << "focused on module '" << q->dw.module_name
    3222                 :              << " = [0x" << hex << q->dw.module_start
    3223                 :              << "-0x" << q->dw.module_end
    3224                 :              << ", bias 0x" << q->dw.module_bias << "]" << dec
    3225                 :              << " file " << debug_filename
    3226                 :              << " ELF machine " << expect_machine
    3227                 :              << " (code " << elf_machine << ")"
    3228               0 :              << "\n";
    3229                 : 
    3230           61193 :       q->handle_query_module();
    3231                 : 
    3232                 :       // If we know that there will be no more matches, abort early.
    3233           61193 :       if (q->dw.module_name_final_match(q->module_val))
    3234          115778 :         return DWARF_CB_ABORT;
    3235                 :       else
    3236            6608 :         return DWARF_CB_OK;
    3237                 :     }
    3238               0 :   catch (const semantic_error& e)
    3239                 :     {
    3240               0 :       q->sess.print_error (e);
    3241               0 :       return DWARF_CB_ABORT;
    3242                 :     }
    3243                 : }
    3244                 : 
    3245                 : 
    3246                 : struct var_expanding_copy_visitor: public deep_copy_visitor
    3247          487383 : {
    3248                 :   static unsigned tick;
    3249                 :   stack<functioncall**> target_symbol_setter_functioncalls;
    3250                 : 
    3251          487383 :   var_expanding_copy_visitor() {}
    3252                 :   void visit_assignment (assignment* e);
    3253                 : };
    3254                 : 
    3255                 : 
    3256                 : struct dwarf_var_expanding_copy_visitor: public var_expanding_copy_visitor
    3257          487373 : {
    3258                 :   dwarf_query & q;
    3259                 :   Dwarf_Die *scope_die;
    3260                 :   Dwarf_Addr addr;
    3261                 :   block *add_block;
    3262                 :   probe *add_probe;
    3263                 :   std::map<std::string, symbol *> return_ts_map;
    3264                 : 
    3265          487373 :   dwarf_var_expanding_copy_visitor(dwarf_query & q, Dwarf_Die *sd, Dwarf_Addr a):
    3266          487373 :     q(q), scope_die(sd), addr(a), add_block(NULL), add_probe(NULL) {}
    3267                 :   void visit_target_symbol (target_symbol* e);
    3268                 : };
    3269                 : 
    3270                 : 
    3271                 : 
    3272                 : unsigned var_expanding_copy_visitor::tick = 0;
    3273                 : 
    3274                 : void
    3275          206312 : var_expanding_copy_visitor::visit_assignment (assignment* e)
    3276                 : {
    3277                 :   // Our job would normally be to require() the left and right sides
    3278                 :   // into a new assignment. What we're doing is slightly trickier:
    3279                 :   // we're pushing a functioncall** onto a stack, and if our left
    3280                 :   // child sets the functioncall* for that value, we're going to
    3281                 :   // assume our left child was a target symbol -- transformed into a
    3282                 :   // set_target_foo(value) call, and it wants to take our right child
    3283                 :   // as the argument "value".
    3284                 :   //
    3285                 :   // This is why some people claim that languages with
    3286                 :   // constructor-decomposing case expressions have a leg up on
    3287                 :   // visitors.
    3288                 : 
    3289          206312 :   functioncall *fcall = NULL;
    3290                 :   expression *new_left, *new_right;
    3291                 : 
    3292          206312 :   target_symbol_setter_functioncalls.push (&fcall);
    3293          206312 :   require<expression*> (this, &new_left, e->left);
    3294          206310 :   target_symbol_setter_functioncalls.pop ();
    3295          206310 :   require<expression*> (this, &new_right, e->right);
    3296                 : 
    3297          206309 :   if (fcall != NULL)
    3298                 :     {
    3299                 :       // Our left child is informing us that it was a target variable
    3300                 :       // and it has been replaced with a set_target_foo() function
    3301                 :       // call; we are going to provide that function call -- with the
    3302                 :       // right child spliced in as sole argument -- in place of
    3303                 :       // ourselves, in the deep copy we're in the middle of making.
    3304                 : 
    3305                 :       // FIXME: for the time being, we only support plan $foo = bar,
    3306                 :       // not += or any other op= variant. This is fixable, but a bit
    3307                 :       // ugly.
    3308               6 :       if (e->op != "=")
    3309                 :         throw semantic_error ("Operator-assign expressions on target "
    3310               0 :                              "variables not implemented", e->tok);
    3311                 : 
    3312               6 :       assert (new_left == fcall);
    3313               6 :       fcall->args.push_back (new_right);
    3314               6 :       provide <expression*> (this, fcall);
    3315                 :     }
    3316                 :   else
    3317                 :     {
    3318          206303 :       assignment* n = new assignment;
    3319          206303 :       n->op = e->op;
    3320          206303 :       n->tok = e->tok;
    3321          206303 :       n->left = new_left;
    3322          206303 :       n->right = new_right;
    3323          206303 :       provide <assignment*> (this, n);
    3324                 :     }
    3325          206309 : }
    3326                 : 
    3327                 : 
    3328                 : void
    3329          115484 : dwarf_var_expanding_copy_visitor::visit_target_symbol (target_symbol *e)
    3330                 : {
    3331          115484 :   assert(e->base_name.size() > 0 && e->base_name[0] == '$');
    3332                 : 
    3333          115484 :   bool lvalue = is_active_lvalue(e);
    3334          115484 :   if (lvalue && !q.sess.guru_mode)
    3335               1 :     throw semantic_error("write to target variable not permitted", e->tok);
    3336                 : 
    3337          115483 :   if (q.has_return && e->base_name != "$return")
    3338                 :     {
    3339              66 :       if (lvalue)
    3340               0 :         throw semantic_error("write to target variable not permitted in .return probes", e->tok);
    3341                 : 
    3342                 :       // Get the full name of the target symbol.
    3343              66 :       stringstream ts_name_stream;
    3344              66 :       e->print(ts_name_stream);
    3345              66 :       string ts_name = ts_name_stream.str();
    3346                 : 
    3347                 :       // Check and make sure we haven't already seen this target
    3348                 :       // variable in this return probe.  If we have, just return our
    3349                 :       // last replacement.
    3350              66 :       map<string, symbol *>::iterator i = return_ts_map.find(ts_name);
    3351              66 :       if (i != return_ts_map.end())
    3352                 :         {
    3353               0 :           provide <symbol*> (this, i->second);
    3354                 :           return;
    3355                 :         }
    3356                 : 
    3357                 :       // We've got to do several things here to handle target
    3358                 :       // variables in return probes.
    3359                 : 
    3360                 :       // (1) Synthesize two global arrays.  One is the cache of the
    3361                 :       // target variable and the other contains a thread specific
    3362                 :       // nesting level counter.  The arrays will look like
    3363                 :       // this:
    3364                 :       //
    3365                 :       //   _dwarf_tvar_{name}_{num}
    3366                 :       //   _dwarf_tvar_{name}_{num}_ctr
    3367                 : 
    3368                 :       string aname = (string("_dwarf_tvar_")
    3369                 :                       + e->base_name.substr(1)
    3370              66 :                       + "_" + lex_cast<string>(tick++));
    3371              66 :       vardecl* vd = new vardecl;
    3372              66 :       vd->name = aname;
    3373              66 :       vd->tok = e->tok;
    3374              66 :       q.sess.globals.push_back (vd);
    3375                 : 
    3376              66 :       string ctrname = aname + "_ctr";
    3377              66 :       vd = new vardecl;
    3378              66 :       vd->name = ctrname;
    3379              66 :       vd->tok = e->tok;
    3380              66 :       q.sess.globals.push_back (vd);
    3381                 : 
    3382                 :       // (2) Create a new code block we're going to insert at the
    3383                 :       // beginning of this probe to get the cached value into a
    3384                 :       // temporary variable.  We'll replace the target variable
    3385                 :       // reference with the temporary variable reference.  The code
    3386                 :       // will look like this:
    3387                 :       //
    3388                 :       //   _dwarf_tvar_tid = tid()
    3389                 :       //   _dwarf_tvar_{name}_{num}_tmp
    3390                 :       //       = _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
    3391                 :       //                    _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]]
    3392                 :       //   delete _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
    3393                 :       //                    _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]--]
    3394                 :       //   if (! _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid])
    3395                 :       //       delete _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]
    3396                 : 
    3397                 :       // (2a) Synthesize the tid temporary expression, which will look
    3398                 :       // like this:
    3399                 :       //
    3400                 :       //   _dwarf_tvar_tid = tid()
    3401              66 :       symbol* tidsym = new symbol;
    3402             132 :       tidsym->name = string("_dwarf_tvar_tid");
    3403              66 :       tidsym->tok = e->tok;
    3404                 : 
    3405              66 :       if (add_block == NULL)
    3406                 :         {
    3407              28 :            add_block = new block;
    3408              28 :            add_block->tok = e->tok;
    3409                 : 
    3410                 :            // Synthesize a functioncall to grab the thread id.
    3411              56 :            functioncall* fc = new functioncall;
    3412              28 :            fc->tok = e->tok;
    3413              56 :            fc->function = string("tid");
    3414                 : 
    3415                 :            // Assign the tid to '_dwarf_tvar_tid'.
    3416              56 :            assignment* a = new assignment;
    3417              28 :            a->tok = e->tok;
    3418              28 :            a->op = "=";
    3419              28 :            a->left = tidsym;
    3420              28 :            a->right = fc;
    3421                 : 
    3422              28 :            expr_statement* es = new expr_statement;
    3423              28 :            es->tok = e->tok;
    3424              28 :            es->value = a;
    3425              28 :            add_block->statements.push_back (es);
    3426                 :         }
    3427                 : 
    3428                 :       // (2b) Synthesize an array reference and assign it to a
    3429                 :       // temporary variable (that we'll use as replacement for the
    3430                 :       // target variable reference).  It will look like this:
    3431                 :       //
    3432                 :       //   _dwarf_tvar_{name}_{num}_tmp
    3433                 :       //       = _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
    3434                 :       //                    _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]]
    3435                 : 
    3436              66 :       arrayindex* ai_tvar_base = new arrayindex;
    3437              66 :       ai_tvar_base->tok = e->tok;
    3438                 : 
    3439             132 :       symbol* sym = new symbol;
    3440              66 :       sym->name = aname;
    3441              66 :       sym->tok = e->tok;
    3442              66 :       ai_tvar_base->base = sym;
    3443                 : 
    3444              66 :       ai_tvar_base->indexes.push_back(tidsym);
    3445                 : 
    3446                 :       // We need to create a copy of the array index in its current
    3447                 :       // state so we can have 2 variants of it (the original and one
    3448                 :       // that post-decrements the second index).
    3449              66 :       arrayindex* ai_tvar = new arrayindex;
    3450             132 :       arrayindex* ai_tvar_postdec = new arrayindex;
    3451              66 :       *ai_tvar = *ai_tvar_base;
    3452              66 :       *ai_tvar_postdec = *ai_tvar_base;
    3453                 : 
    3454                 :       // Synthesize the
    3455                 :       // "_dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]" used as the
    3456                 :       // second index into the array.
    3457              66 :       arrayindex* ai_ctr = new arrayindex;
    3458              66 :       ai_ctr->tok = e->tok;
    3459                 : 
    3460             132 :       sym = new symbol;
    3461              66 :       sym->name = ctrname;
    3462              66 :       sym->tok = e->tok;
    3463              66 :       ai_ctr->base = sym;
    3464              66 :       ai_ctr->indexes.push_back(tidsym);
    3465              66 :       ai_tvar->indexes.push_back(ai_ctr);
    3466                 : 
    3467              66 :       symbol* tmpsym = new symbol;
    3468             132 :       tmpsym->name = aname + "_tmp";
    3469              66 :       tmpsym->tok = e->tok;
    3470                 : 
    3471              66 :       assignment* a = new assignment;
    3472              66 :       a->tok = e->tok;
    3473              66 :       a->op = "=";
    3474              66 :       a->left = tmpsym;
    3475              66 :       a->right = ai_tvar;
    3476                 : 
    3477              66 :       expr_statement* es = new expr_statement;
    3478              66 :       es->tok = e->tok;
    3479              66 :       es->value = a;
    3480                 : 
    3481              66 :       add_block->statements.push_back (es);
    3482                 : 
    3483                 :       // (2c) Add a post-decrement to the second array index and
    3484                 :       // delete the array value.  It will look like this:
    3485                 :       //
    3486                 :       //   delete _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
    3487                 :       //                    _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]--]
    3488                 : 
    3489              66 :       post_crement* pc = new post_crement;
    3490              66 :       pc->tok = e->tok;
    3491              66 :       pc->op = "--";
    3492              66 :       pc->operand = ai_ctr;
    3493              66 :       ai_tvar_postdec->indexes.push_back(pc);
    3494                 : 
    3495              66 :       delete_statement* ds = new delete_statement;
    3496              66 :       ds->tok = e->tok;
    3497              66 :       ds->value = ai_tvar_postdec;
    3498                 : 
    3499              66 :       add_block->statements.push_back (ds);
    3500                 : 
    3501                 :       // (2d) Delete the counter value if it is 0.  It will look like
    3502                 :       // this:
    3503                 :       //   if (! _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid])
    3504                 :       //       delete _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]
    3505                 : 
    3506              66 :       ds = new delete_statement;
    3507              66 :       ds->tok = e->tok;
    3508              66 :       ds->value = ai_ctr;
    3509                 : 
    3510             132 :       unary_expression *ue = new unary_expression;
    3511              66 :       ue->tok = e->tok;
    3512              66 :       ue->op = "!";
    3513              66 :       ue->operand = ai_ctr;
    3514                 : 
    3515              66 :       if_statement *ifs = new if_statement;
    3516              66 :       ifs->tok = e->tok;
    3517              66 :       ifs->condition = ue;
    3518              66 :       ifs->thenblock = ds;
    3519              66 :       ifs->elseblock = NULL;
    3520                 : 
    3521              66 :       add_block->statements.push_back (ifs);
    3522                 : 
    3523                 :       // (3) We need an entry probe that saves the value for us in the
    3524                 :       // global array we created.  Create the entry probe, which will
    3525                 :       // look like this:
    3526                 :       //
    3527                 :       //   probe kernel.function("{function}") {
    3528                 :       //     _dwarf_tvar_tid = tid()
    3529                 :       //     _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
    3530                 :       //                       ++_dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]]
    3531                 :       //       = ${param}
    3532                 :       //   }
    3533                 : 
    3534              66 :       if (add_probe == NULL)
    3535                 :         {
    3536              28 :            add_probe = new probe;
    3537              28 :            add_probe->tok = e->tok;
    3538                 : 
    3539                 :            // We need the name of the current probe point, minus the
    3540                 :            // ".return" (or anything after it, such as ".maxactive(N)").
    3541                 :            // Create a new probe point, copying all the components,
    3542                 :            // stopping when we see the ".return" component.
    3543              56 :            probe_point* pp = new probe_point;
    3544              84 :            for (unsigned c = 0; c < q.base_loc->components.size(); c++)
    3545                 :              {
    3546              84 :                 if (q.base_loc->components[c]->functor == "return")
    3547              28 :                   break;
    3548                 :                 else
    3549              56 :                   pp->components.push_back(q.base_loc->components[c]);
    3550                 :              }
    3551              28 :            pp->tok = e->tok;
    3552              28 :            pp->optional = q.base_loc->optional;
    3553              28 :            add_probe->locations.push_back(pp);
    3554                 : 
    3555              28 :            add_probe->body = new block;
    3556              28 :            add_probe->body->tok = e->tok;
    3557                 : 
    3558                 :            // Synthesize a functioncall to grab the thread id.
    3559              56 :            functioncall* fc = new functioncall;
    3560              28 :            fc->tok = e->tok;
    3561              56 :            fc->function = string("tid");
    3562                 : 
    3563                 :            // Assign the tid to '_dwarf_tvar_tid'.
    3564              56 :            assignment* a = new assignment;
    3565              28 :            a->tok = e->tok;
    3566              28 :            a->op = "=";
    3567              28 :            a->left = tidsym;
    3568              28 :            a->right = fc;
    3569                 : 
    3570              28 :            expr_statement* es = new expr_statement;
    3571              28 :            es->tok = e->tok;
    3572              28 :            es->value = a;
    3573              28 :            add_probe->body->statements.push_back (es);
    3574                 : 
    3575              28 :            vardecl* vd = new vardecl;
    3576              28 :            vd->tok = e->tok;
    3577              28 :            vd->name = tidsym->name;
    3578              28 :            vd->type = pe_long;
    3579              28 :            vd->set_arity(0);
    3580              28 :            add_probe->locals.push_back(vd);
    3581                 :         }
    3582                 : 
    3583                 :       // Save the value, like this:
    3584                 :       //     _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
    3585                 :       //                       ++_dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]]
    3586                 :       //       = ${param}
    3587              66 :       arrayindex* ai_tvar_preinc = new arrayindex;
    3588              66 :       *ai_tvar_preinc = *ai_tvar_base;
    3589                 : 
    3590              66 :       pre_crement* preinc = new pre_crement;
    3591              66 :       preinc->tok = e->tok;
    3592              66 :       preinc->op = "++";
    3593              66 :       preinc->operand = ai_ctr;
    3594              66 :       ai_tvar_preinc->indexes.push_back(preinc);
    3595                 : 
    3596              66 :       a = new assignment;
    3597              66 :       a->tok = e->tok;
    3598              66 :       a->op = "=";
    3599              66 :       a->left = ai_tvar_preinc;
    3600              66 :       a->right = e;
    3601                 : 
    3602              66 :       es = new expr_statement;
    3603              66 :       es->tok = e->tok;
    3604              66 :       es->value = a;
    3605                 : 
    3606              66 :       add_probe->body->statements.push_back (es);
    3607                 : 
    3608                 :       // (4) Provide the '_dwarf_tvar_{name}_{num}_tmp' variable to
    3609                 :       // our parent so it can be used as a substitute for the target
    3610                 :       // symbol.
    3611              66 :       provide <symbol*> (this, tmpsym);
    3612                 : 
    3613                 :       // (5) Remember this replacement since we might be able to reuse
    3614                 :       // it later if the same return probe references this target
    3615                 :       // symbol again.
    3616              66 :       return_ts_map[ts_name] = tmpsym;
    3617              66 :       return;
    3618                 :     }
    3619                 : 
    3620                 :   // Synthesize a function.
    3621          115417 :   functiondecl *fdecl = new functiondecl;
    3622          115417 :   fdecl->tok = e->tok;
    3623          230834 :   embeddedcode *ec = new embeddedcode;
    3624          115417 :   ec->tok = e->tok;
    3625                 : 
    3626                 :   string fname = (string(lvalue ? "_dwarf_tvar_set" : "_dwarf_tvar_get")
    3627                 :                   + "_" + e->base_name.substr(1)
    3628          230834 :                   + "_" + lex_cast<string>(tick++));
    3629                 : 
    3630                 :   try
    3631                 :     {
    3632          115855 :       if (q.has_return && e->base_name == "$return")
    3633                 :         {
    3634                 :           ec->code = q.dw.literal_stmt_for_return (scope_die,
    3635                 :                                                    addr,
    3636                 :                                                    e->components,
    3637                 :                                                    lvalue,
    3638             438 :                                                    fdecl->type);
    3639                 :         }
    3640                 :       else
    3641                 :         {
    3642                 :           ec->code = q.dw.literal_stmt_for_local (scope_die,
    3643                 :                                                   addr,
    3644                 :                                                   e->base_name.substr(1),
    3645                 :                                                   e->components,
    3646                 :                                                   lvalue,
    3647          114979 :                                                   fdecl->type);
    3648                 :         }
    3649                 : 
    3650          115320 :       if (! lvalue)
    3651          115316 :         ec->code += "/* pure */";
    3652                 :     }
    3653             194 :   catch (const semantic_error& er)
    3654                 :     {
    3655                 :       // We suppress this error message, and pass the unresolved
    3656                 :       // target_symbol to the next pass.  We hope that this value ends
    3657                 :       // up not being referenced after all, so it can be optimized out
    3658                 :       // quietly.
    3659              97 :       provide <target_symbol*> (this, e);
    3660              97 :       semantic_error* saveme = new semantic_error (er); // copy it
    3661              97 :       saveme->tok1 = e->tok; // XXX: token not passed to q.dw code generation routines
    3662                 :       // NB: we can have multiple errors, since a $target variable
    3663                 :       // may be expanded in several different contexts:
    3664                 :       //     function ("*") { $var }
    3665              97 :       saveme->chain = e->saved_conversion_error;
    3666              97 :       e->saved_conversion_error = saveme;
    3667             194 :       delete fdecl;
    3668              97 :       delete ec;
    3669              97 :       return;
    3670                 :     }
    3671                 : 
    3672          115320 :   fdecl->name = fname;
    3673          115320 :   fdecl->body = ec;
    3674          115320 :   if (lvalue)
    3675                 :     {
    3676                 :       // Modify the fdecl so it carries a single pe_long formal
    3677                 :       // argument called "value".
    3678                 : 
    3679                 :       // FIXME: For the time being we only support setting target
    3680                 :       // variables which have base types; these are 'pe_long' in
    3681                 :       // stap's type vocabulary.  Strings and pointers might be
    3682                 :       // reasonable, some day, but not today.
    3683                 : 
    3684               4 :       vardecl *v = new vardecl;
    3685               4 :       v->type = pe_long;
    3686               4 :       v->name = "value";
    3687               4 :       v->tok = e->tok;
    3688               4 :       fdecl->formal_args.push_back(v);
    3689                 :     }
    3690          115320 :   q.sess.functions.push_back(fdecl);
    3691                 : 
    3692                 :   // Synthesize a functioncall.
    3693          115320 :   functioncall* n = new functioncall;
    3694          115320 :   n->tok = e->tok;
    3695          115320 :   n->function = fname;
    3696          115320 :   n->referent = 0;  // NB: must not resolve yet, to ensure inclusion in session
    3697                 : 
    3698          115320 :   if (lvalue)
    3699                 :     {
    3700                 :       // Provide the functioncall to our parent, so that it can be
    3701                 :       // used to substitute for the assignment node immediately above
    3702                 :       // us.
    3703               4 :       assert(!target_symbol_setter_functioncalls.empty());
    3704               4 :       *(target_symbol_setter_functioncalls.top()) = n;
    3705                 :     }
    3706                 : 
    3707          115320 :   provide <functioncall*> (this, n);
    3708                 : }
    3709                 : 
    3710                 : 
    3711                 : void
    3712          487164 : dwarf_derived_probe::printsig (ostream& o) const
    3713                 : {
    3714                 :   // Instead of just printing the plain locations, we add a PC value
    3715                 :   // as a comment as a way of telling e.g. apart multiple inlined
    3716                 :   // function instances.  This is distinct from the verbose/clog
    3717                 :   // output, since this part goes into the cache hash calculations.
    3718          487164 :   sole_location()->print (o);
    3719          487164 :   o << " /* pc=0x" << hex << addr << dec << " */";
    3720          487164 :   printsig_nested (o);
    3721          487164 : }
    3722                 : 
    3723                 : 
    3724                 : 
    3725                 : void
    3726          487375 : dwarf_derived_probe::join_group (systemtap_session& s)
    3727                 : {
    3728          487375 :   if (! s.dwarf_derived_probes)
    3729             192 :     s.dwarf_derived_probes = new dwarf_derived_probe_group ();
    3730          487375 :   s.dwarf_derived_probes->enroll (this);
    3731          487375 : }
    3732                 : 
    3733                 : 
    3734                 : dwarf_derived_probe::dwarf_derived_probe(const string& funcname,
    3735                 :                                          const string& filename,
    3736                 :                                          int line,
    3737                 :                                          // module & section speficy a relocation
    3738                 :                                          // base for <addr>, unless section==""
    3739                 :                                          // (equivalently module=="kernel")
    3740                 :                                          const string& module,
    3741                 :                                          const string& section,
    3742                 :                                          // NB: dwfl_addr is the virtualized
    3743                 :                                          // address for this symbol.
    3744                 :                                          Dwarf_Addr dwfl_addr,
    3745                 :                                          // addr is the section-offset for
    3746                 :                                          // actual relocation.
    3747                 :                                          Dwarf_Addr addr,
    3748                 :                                          dwarf_query& q,
    3749          487378 :                                          Dwarf_Die* scope_die /* may be null */)
    3750                 :   : derived_probe (q.base_probe, new probe_point(*q.base_loc) /* .components soon rewritten */ ),
    3751                 :     module (module), section (section), addr (addr),
    3752                 :     has_return (q.has_return),
    3753                 :     has_maxactive (q.has_maxactive),
    3754          487378 :     maxactive_val (q.maxactive_val)
    3755                 : {
    3756                 :   // Assert relocation invariants
    3757          487378 :   if (section == "" && dwfl_addr != addr) // addr should be absolute
    3758               0 :     throw semantic_error ("missing relocation base against", q.base_loc->tok);
    3759          487378 :   if (section != "" && dwfl_addr == addr) // addr should be an offset
    3760               0 :     throw semantic_error ("inconsistent relocation address", q.base_loc->tok);
    3761                 : 
    3762          487378 :   this->tok = q.base_probe->tok;
    3763                 : 
    3764                 :   // XXX: hack for strange g++/gcc's
    3765                 : #ifndef USHRT_MAX
    3766                 : #define USHRT_MAX 32767
    3767                 : #endif
    3768                 : 
    3769                 :   // Range limit maxactive() value
    3770          487378 :   if (q.has_maxactive && (q.maxactive_val < 0 || q.maxactive_val > USHRT_MAX))
    3771                 :     throw semantic_error ("maxactive value out of range [0,"
    3772                 :                           + lex_cast<string>(USHRT_MAX) + "]",
    3773               2 :                           q.base_loc->tok);
    3774                 : 
    3775                 :   // Make a target-variable-expanded copy of the probe body
    3776          487376 :   if (scope_die)
    3777                 :     {
    3778          487373 :       dwarf_var_expanding_copy_visitor v (q, scope_die, dwfl_addr);
    3779          487373 :       require <block*> (&v, &(this->body), this->body);
    3780                 : 
    3781                 :       // If during target-variable-expanding the probe, we added a new block
    3782                 :       // of code, add it to the start of the probe.
    3783          487372 :       if (v.add_block)
    3784              28 :         this->body->statements.insert(this->body->statements.begin(), v.add_block);
    3785                 : 
    3786                 :       // If when target-variable-expanding the probe, we added a new
    3787                 :       // probe, add it in a new file to the list of files to be processed.
    3788          487372 :       if (v.add_probe)
    3789                 :         {
    3790              28 :           stapfile *f = new stapfile;
    3791              28 :           f->probes.push_back(v.add_probe);
    3792              28 :           q.sess.files.push_back(f);
    3793          487372 :         }
    3794                 :     }
    3795                 :   // else - null scope_die - $target variables will produce an error during translate phase
    3796                 : 
    3797                 :   // Reset the sole element of the "locations" vector as a
    3798                 :   // "reverse-engineered" form of the incoming (q.base_loc) probe
    3799                 :   // point.  This allows a user to see what function / file / line
    3800                 :   // number any particular match of the wildcards.
    3801                 : 
    3802          487375 :   vector<probe_point::component*> comps;
    3803                 :   comps.push_back
    3804                 :     (module == TOK_KERNEL
    3805                 :      ? new probe_point::component(TOK_KERNEL)
    3806          974750 :      : new probe_point::component(TOK_MODULE, new literal_string(module)));
    3807                 : 
    3808          487375 :   string fn_or_stmt;
    3809          974737 :   if (q.has_function_str || q.has_function_num)
    3810          487362 :     fn_or_stmt = "function";
    3811                 :   else
    3812              13 :     fn_or_stmt = "statement";
    3813                 : 
    3814          974746 :   if (q.has_function_str || q.has_statement_str)
    3815                 :       {
    3816          487371 :         string retro_name = funcname;
    3817          487371 :         if (filename != "")
    3818          487371 :           retro_name += ("@" + string (filename));
    3819          487371 :         if (line != -1)
    3820          486658 :           retro_name += (":" + lex_cast<string> (line));
    3821                 :         comps.push_back
    3822                 :           (new probe_point::component
    3823          487371 :            (fn_or_stmt, new literal_string (retro_name)));
    3824                 :       }
    3825               4 :   else if (q.has_function_num || q.has_statement_num)
    3826                 :     {
    3827                 :       Dwarf_Addr retro_addr;
    3828               4 :       if (q.has_function_num)
    3829               0 :         retro_addr = q.function_num_val;
    3830                 :       else
    3831               4 :         retro_addr = q.statement_num_val;
    3832                 :       comps.push_back (new probe_point::component
    3833                 :                        (fn_or_stmt,
    3834               4 :                         new literal_number(retro_addr))); // XXX: should be hex if possible
    3835                 : 
    3836               4 :       if (q.has_absolute)
    3837               3 :         comps.push_back (new probe_point::component (TOK_ABSOLUTE));
    3838                 :     }
    3839                 : 
    3840          487375 :   if (q.has_call)
    3841           51896 :       comps.push_back (new probe_point::component(TOK_CALL));
    3842          487375 :   if (q.has_inline)
    3843          142928 :       comps.push_back (new probe_point::component(TOK_INLINE));
    3844          487375 :   if (has_return)
    3845           74082 :     comps.push_back (new probe_point::component(TOK_RETURN));
    3846          487375 :   if (has_maxactive)
    3847                 :     comps.push_back (new probe_point::component
    3848               3 :                      (TOK_MAXACTIVE, new literal_number(maxactive_val)));
    3849                 : 
    3850                 :   // Overwrite it.
    3851          487375 :   this->sole_location()->components = comps;
    3852          487375 : }
    3853                 : 
    3854                 : 
    3855                 : void
    3856                 : dwarf_derived_probe::register_statement_variants(match_node * root,
    3857            1940 :                                                  dwarf_builder * dw)
    3858                 : {
    3859            1940 :   root->bind(dw);
    3860            1940 : }
    3861                 : 
    3862                 : void
    3863                 : dwarf_derived_probe::register_function_variants(match_node * root,
    3864            1940 :                                                 dwarf_builder * dw)
    3865                 : {
    3866            1940 :   root->bind(dw);
    3867            1940 :   root->bind(TOK_INLINE)->bind(dw);
    3868            1940 :   root->bind(TOK_CALL)->bind(dw);
    3869            1940 :   root->bind(TOK_RETURN)->bind(dw);
    3870            1940 :   root->bind(TOK_RETURN)->bind_num(TOK_MAXACTIVE)->bind(dw);
    3871            1940 : }
    3872                 : 
    3873                 : void
    3874                 : dwarf_derived_probe::register_function_and_statement_variants(match_node * root,
    3875             970 :                                                               dwarf_builder * dw)
    3876                 : {
    3877                 :   // Here we match 4 forms:
    3878                 :   //
    3879                 :   // .function("foo")
    3880                 :   // .function(0xdeadbeef)
    3881                 :   // .statement("foo")
    3882                 :   // .statement(0xdeadbeef)
    3883                 : 
    3884             970 :   register_function_variants(root->bind_str(TOK_FUNCTION), dw);
    3885             970 :   register_function_variants(root->bind_num(TOK_FUNCTION), dw);
    3886             970 :   register_statement_variants(root->bind_str(TOK_STATEMENT), dw);
    3887             970 :   register_statement_variants(root->bind_num(TOK_STATEMENT), dw);
    3888             970 : }
    3889                 : 
    3890                 : void
    3891             485 : dwarf_derived_probe::register_patterns(match_node * root)
    3892                 : {
    3893             485 :   dwarf_builder *dw = new dwarf_builder();
    3894                 : 
    3895             485 :   register_function_and_statement_variants(root->bind(TOK_KERNEL), dw);
    3896             485 :   register_function_and_statement_variants(root->bind_str(TOK_MODULE), dw);
    3897             485 :   root->bind(TOK_KERNEL)->bind_num(TOK_STATEMENT)->bind(TOK_ABSOLUTE)->bind(dw);
    3898                 : 
    3899                 :   // register_function_and_statement_variants(root->bind_str(TOK_PROCESS), dw);
    3900             485 : }
    3901                 : 
    3902                 : 
    3903                 : // ------------------------------------------------------------------------
    3904                 : 
    3905                 : void
    3906          487375 : dwarf_derived_probe_group::enroll (dwarf_derived_probe* p)
    3907                 : {
    3908          487375 :   probes_by_module.insert (make_pair (p->module, p));
    3909                 : 
    3910                 :   // XXX: probes put at the same address should all share a
    3911                 :   // single kprobe/kretprobe, and have their handlers executed
    3912                 :   // sequentially.
    3913          487375 : }
    3914                 : 
    3915                 : 
    3916                 : void
    3917             100 : dwarf_derived_probe_group::emit_module_decls (systemtap_session& s)
    3918                 : {
    3919             100 :   if (probes_by_module.empty()) return;
    3920                 : 
    3921             100 :   s.op->newline() << "/* ---- dwarf probes ---- */";
    3922                 : 
    3923                 :   // Warn of misconfigured kernels
    3924             100 :   s.op->newline() << "#if ! defined(CONFIG_KPROBES)";
    3925             100 :   s.op->newline() << "#error \"Need CONFIG_KPROBES!\"";
    3926             100 :   s.op->newline() << "#endif";
    3927             100 :   s.op->newline();
    3928                 : 
    3929                 :   // Forward declare the master entry functions
    3930             100 :   s.op->newline() << "static int enter_kprobe_probe (struct kprobe *inst,";
    3931             100 :   s.op->line() << " struct pt_regs *regs);";
    3932             100 :   s.op->newline() << "static int enter_kretprobe_probe (struct kretprobe_instance *inst,";
    3933             100 :   s.op->line() << " struct pt_regs *regs);";
    3934                 : 
    3935                 :   // Emit the actual probe list.
    3936                 : 
    3937                 :   // NB: we used to plop a union { struct kprobe; struct kretprobe } into
    3938                 :   // struct stap_dwarf_probe, but it being initialized data makes it add
    3939                 :   // hundreds of bytes of padding per stap_dwarf_probe.  (PR5673)
    3940             100 :   s.op->newline() << "struct stap_dwarf_kprobe {";
    3941             100 :   s.op->newline(1) << "union { struct kprobe kp; struct kretprobe krp; } u;";
    3942             100 :   s.op->newline(-1) << "} stap_dwarf_kprobes[" << probes_by_module.size() << "];";
    3943                 :   // NB: bss!
    3944                 : 
    3945             100 :   s.op->newline() << "struct stap_dwarf_probe {";
    3946             100 :   s.op->newline(1) << "const unsigned return_p:1;";
    3947             100 :   s.op->newline() << "const unsigned maxactive_p:1;";
    3948             100 :   s.op->newline() << "unsigned registered_p:1;";
    3949             100 :   s.op->newline() << "const unsigned short maxactive_val;";
    3950                 : 
    3951                 :   // Let's find some stats for the three embedded strings.  Maybe they
    3952                 :   // are small and uniform enough to justify putting char[MAX]'s into
    3953                 :   // the array instead of relocated char*'s.
    3954             100 :   size_t module_name_max = 0, section_name_max = 0, pp_name_max = 0;
    3955             100 :   size_t module_name_tot = 0, section_name_tot = 0, pp_name_tot = 0;
    3956             100 :   size_t all_name_cnt = probes_by_module.size(); // for average
    3957           16600 :   for (p_b_m_iterator it = probes_by_module.begin(); it != probes_by_module.end(); it++)
    3958                 :     {
    3959            8200 :       dwarf_derived_probe* p = it->second;
    3960                 : #define DOIT(var,expr) do {                             \
    3961                 :         size_t var##_size = (expr) + 1;                 \
    3962                 :         var##_max = max (var##_max, var##_size);        \
    3963                 :         var##_tot += var##_size; } while (0)
    3964            8200 :       DOIT(module_name, p->module.size());
    3965            8200 :       DOIT(section_name, p->section.size());
    3966            8200 :       DOIT(pp_name, lex_cast_qstring(*p->sole_location()).size());
    3967                 : #undef DOIT
    3968                 :     }
    3969                 : 
    3970                 :   // Decide whether it's worthwhile to use char[] or char* by comparing
    3971                 :   // the amount of average waste (max - avg) to the relocation data size
    3972                 :   // (3 native long words).
    3973                 : #define CALCIT(var)                                                     \
    3974                 :   if ((var##_name_max-(var##_name_tot/all_name_cnt)) < (3 * sizeof(void*))) \
    3975                 :     {                                                                   \
    3976                 :       s.op->newline() << "const char " << #var << "[" << var##_name_max << "];"; \
    3977                 :       if (s.verbose > 2) clog << "stap_dwarf_probe " << #var            \
    3978                 :                               << "[" << var##_name_max << "]" << endl;  \
    3979                 :     }                                                                   \
    3980                 :   else                                                                  \
    3981                 :     {                                                                   \
    3982                 :       s.op->newline() << "const char * const " << #var << ";";                 \
    3983                 :       if (s.verbose > 2) clog << "stap_dwarf_probe *" << #var << endl;  \
    3984                 :     }
    3985                 : 
    3986             100 :   CALCIT(module);
    3987             100 :   CALCIT(section);
    3988             100 :   CALCIT(pp);
    3989                 : 
    3990             100 :   s.op->newline() << "const unsigned long address;";
    3991             100 :   s.op->newline() << "void (* const ph) (struct context*);";
    3992             100 :   s.op->newline(-1) << "} stap_dwarf_probes[] = {";
    3993             100 :   s.op->indent(1);
    3994                 : 
    3995           16600 :   for (p_b_m_iterator it = probes_by_module.begin(); it != probes_by_module.end(); it++)
    3996                 :     {
    3997            8200 :       dwarf_derived_probe* p = it->second;
    3998            8200 :       s.op->newline() << "{";
    3999            8200 :       if (p->has_return)
    4000            2593 :         s.op->line() << " .return_p=1,";
    4001            8200 :       if (p->has_maxactive)
    4002                 :         {
    4003               3 :           s.op->line() << " .maxactive_p=1,";
    4004               3 :           assert (p->maxactive_val >= 0 && p->maxactive_val <= USHRT_MAX);
    4005               3 :           s.op->line() << " .maxactive_val=" << p->maxactive_val << ",";
    4006                 :         }
    4007            8200 :       s.op->line() << " .address=0x" << hex << p->addr << dec << "UL,";
    4008            8200 :       s.op->line() << " .module=\"" << p->module << "\",";
    4009            8200 :       s.op->line() << " .section=\"" << p->section << "\",";
    4010            8200 :       s.op->line() << " .pp=" << lex_cast_qstring (*p->sole_location()) << ",";
    4011            8200 :       s.op->line() << " .ph=&" << p->name;
    4012            8200 :       s.op->line() << " },";
    4013                 :     }
    4014                 : 
    4015             100 :   s.op->newline(-1) << "};";
    4016                 : 
    4017                 :   // Emit the kprobes callback function
    4018             100 :   s.op->newline();
    4019             100 :   s.op->newline() << "static int enter_kprobe_probe (struct kprobe *inst,";
    4020             100 :   s.op->line() << " struct pt_regs *regs) {";
    4021                 :   // NB: as of PR5673, the kprobe|kretprobe union struct is in BSS
    4022             100 :   s.op->newline(1) << "int kprobe_idx = ((uintptr_t)inst-(uintptr_t)stap_dwarf_kprobes)/sizeof(struct stap_dwarf_kprobe);";
    4023                 :   // Check that the index is plausible
    4024             100 :   s.op->newline() << "struct stap_dwarf_probe *sdp = &stap_dwarf_probes[";
    4025             100 :   s.op->line() << "((kprobe_idx >= 0 && kprobe_idx < " << probes_by_module.size() << ")?";
    4026             100 :   s.op->line() << "kprobe_idx:0)"; // NB: at least we avoid memory corruption
    4027                 :   // XXX: it would be nice to give a more verbose error though; BUG_ON later?
    4028             100 :   s.op->line() << "];";
    4029             100 :   common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
    4030             100 :   s.op->newline() << "c->probe_point = sdp->pp;";
    4031             100 :   s.op->newline() << "c->regs = regs;";
    4032             100 :   s.op->newline() << "(*sdp->ph) (c);";
    4033             100 :   common_probe_entryfn_epilogue (s.op);
    4034             100 :   s.op->newline() << "return 0;";
    4035             100 :   s.op->newline(-1) << "}";
    4036                 : 
    4037                 :   // Same for kretprobes
    4038             100 :   s.op->newline();
    4039             100 :   s.op->newline() << "static int enter_kretprobe_probe (struct kretprobe_instance *inst,";
    4040             100 :   s.op->line() << " struct pt_regs *regs) {";
    4041             100 :   s.op->newline(1) << "struct kretprobe *krp = inst->rp;";
    4042                 : 
    4043                 :   // NB: as of PR5673, the kprobe|kretprobe union struct is in BSS
    4044             100 :   s.op->newline() << "int kprobe_idx = ((uintptr_t)krp-(uintptr_t)stap_dwarf_kprobes)/sizeof(struct stap_dwarf_kprobe);";
    4045                 :   // Check that the index is plausible
    4046             100 :   s.op->newline() << "struct stap_dwarf_probe *sdp = &stap_dwarf_probes[";
    4047             100 :   s.op->line() << "((kprobe_idx >= 0 && kprobe_idx < " << probes_by_module.size() << ")?";
    4048             100 :   s.op->line() << "kprobe_idx:0)"; // NB: at least we avoid memory corruption
    4049                 :   // XXX: it would be nice to give a more verbose error though; BUG_ON later?
    4050             100 :   s.op->line() << "];";
    4051                 : 
    4052             200 :   common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
    4053             100 :   s.op->newline() << "c->probe_point = sdp->pp;";
    4054             100 :   s.op->newline() << "c->regs = regs;";
    4055             100 :   s.op->newline() << "c->pi = inst;"; // for assisting runtime's backtrace logic
    4056             100 :   s.op->newline() << "(*sdp->ph) (c);";
    4057             100 :   common_probe_entryfn_epilogue (s.op);
    4058             100 :   s.op->newline() << "return 0;";
    4059             100 :   s.op->newline(-1) << "}";
    4060                 : }
    4061                 : 
    4062                 : 
    4063                 : void
    4064             100 : dwarf_derived_probe_group::emit_module_init (systemtap_session& s)
    4065                 : {
    4066             100 :   s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
    4067             100 :   s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
    4068             100 :   s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
    4069             100 :   s.op->newline() << "unsigned long relocated_addr = _stp_module_relocate (sdp->module, sdp->section, sdp->address);";
    4070             100 :   s.op->newline() << "if (relocated_addr == 0) continue;"; // quietly; assume module is absent
    4071             100 :   s.op->newline() << "probe_point = sdp->pp;";
    4072             100 :   s.op->newline() << "if (sdp->return_p) {";
    4073             100 :   s.op->newline(1) << "kp->u.krp.kp.addr = (void *) relocated_addr;";
    4074             100 :   s.op->newline() << "if (sdp->maxactive_p) {";
    4075             100 :   s.op->newline(1) << "kp->u.krp.maxactive = sdp->maxactive_val;";
    4076             100 :   s.op->newline(-1) << "} else {";
    4077             100 :   s.op->newline(1) << "kp->u.krp.maxactive = max(10, 4*NR_CPUS);";
    4078             100 :   s.op->newline(-1) << "}";
    4079             100 :   s.op->newline() << "kp->u.krp.handler = &enter_kretprobe_probe;";
    4080             100 :   s.op->newline() << "rc = register_kretprobe (& kp->u.krp);";
    4081             100 :   s.op->newline(-1) << "} else {";
    4082             100 :   s.op->newline(1) << "kp->u.kp.addr = (void *) relocated_addr;";
    4083             100 :   s.op->newline() << "kp->u.kp.pre_handler = &enter_kprobe_probe;";
    4084             100 :   s.op->newline() << "rc = register_kprobe (& kp->u.kp);";
    4085             100 :   s.op->newline(-1) << "}";
    4086             100 :   s.op->newline() << "if (rc) {";
    4087             100 :   s.op->newline(1) << "for (j=i-1; j>=0; j--) {"; // partial rollback
    4088             100 :   s.op->newline(1) << "struct stap_dwarf_probe *sdp2 = & stap_dwarf_probes[j];";
    4089             100 :   s.op->newline() << "struct stap_dwarf_kprobe *kp2 = & stap_dwarf_kprobes[j];";
    4090             100 :   s.op->newline() << "if (sdp2->return_p) unregister_kretprobe (&kp2->u.krp);";
    4091             100 :   s.op->newline() << "else unregister_kprobe (&kp2->u.kp);";
    4092                 :   // NB: we don't have to clear sdp2->registered_p, since the module_exit code is
    4093                 :   // not run for this early-abort case.
    4094             100 :   s.op->newline(-1) << "}";
    4095             100 :   s.op->newline() << "break;"; // don't attempt to register any more probes
    4096             100 :   s.op->newline(-1) << "}";
    4097             100 :   s.op->newline() << "else sdp->registered_p = 1;";
    4098             100 :   s.op->newline(-1) << "}"; // for loop
    4099             100 : }
    4100                 : 
    4101                 : 
    4102                 : void
    4103             119 : dwarf_derived_probe_group::emit_module_exit (systemtap_session& s)
    4104                 : {
    4105             119 :   s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
    4106             119 :   s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];";
    4107             119 :   s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];";
    4108             119 :   s.op->newline() << "if (! sdp->registered_p) continue;";
    4109             119 :   s.op->newline() << "if (sdp->return_p) {";
    4110             119 :   s.op->newline(1) << "unregister_kretprobe (&kp->u.krp);";
    4111             119 :   s.op->newline() << "atomic_add (kp->u.krp.nmissed, & skipped_count);";
    4112             119 :   s.op->newline() << "atomic_add (kp->u.krp.kp.nmissed, & skipped_count);";
    4113             119 :   s.op->newline(-1) << "} else {";
    4114             119 :   s.op->newline(1) << "unregister_kprobe (&kp->u.kp);";
    4115             119 :   s.op->newline() << "atomic_add (kp->u.kp.nmissed, & skipped_count);";
    4116             119 :   s.op->newline(-1) << "}";
    4117             119 :   s.op->newline() << "sdp->registered_p = 0;";
    4118             119 :   s.op->newline(-1) << "}";
    4119             119 : }
    4120                 : 
    4121                 : 
    4122                 : 
    4123                 : static Dwarf_Addr
    4124          163797 : lookup_symbol_address (Dwfl_Module *m, const char* wanted)
    4125                 : {
    4126          163797 :   int syments = dwfl_module_getsymtab(m);
    4127          163797 :   assert(syments);
    4128      6100182473 :   for (int i = 1; i < syments; ++i)
    4129                 :     {
    4130                 :       GElf_Sym sym;
    4131      6100182473 :       const char *name = dwfl_module_getsym(m, i, &sym, NULL);
    4132      6100182473 :       if (name != NULL && strcmp(name, wanted) == 0)
    4133          163797 :         return sym.st_value;
    4134                 :     }
    4135                 : 
    4136               0 :   return 0;
    4137                 : }
    4138                 : 
    4139                 : 
    4140                 : 
    4141                 : 
    4142                 : void
    4143                 : dwarf_builder::build(systemtap_session & sess,
    4144                 :                      probe * base,
    4145                 :                      probe_point * location,
    4146                 :                      std::map<std::string, literal *> const & parameters,
    4147           54600 :                      vector<derived_probe *> & finished_results)
    4148                 : {
    4149                 :   // NB: the kernel/user dwlfpp objects are long-lived.
    4150                 :   // XXX: but they should be per-session, as this builder object
    4151                 :   // may be reused if we try to cross-instrument multiple targets.
    4152                 : 
    4153           54600 :   if (!kern_dw)
    4154                 :     {
    4155             207 :       kern_dw = new dwflpp(sess);
    4156             207 :       assert(kern_dw);
    4157             207 :       kern_dw->setup(true);
    4158                 :     }
    4159                 : 
    4160           54599 :   Dwfl_Module* km = 0;
    4161           54599 :   kern_dw->iterate_over_modules(&query_kernel_module, &km);
    4162           54599 :   if (km)
    4163                 :     {
    4164           54599 :       sess.sym_kprobes_text_start = lookup_symbol_address (km, "__kprobes_text_start");
    4165           54599 :       sess.sym_kprobes_text_end = lookup_symbol_address (km, "__kprobes_text_end");
    4166           54599 :       sess.sym_stext = lookup_symbol_address (km, "_stext");
    4167                 : 
    4168           54599 :       if (sess.verbose > 2)
    4169                 :         {
    4170                 :           clog << "control symbols:"
    4171                 :             // abbreviate the names - they're for our debugging only anyway
    4172                 :                << " kts: 0x" << hex << sess.sym_kprobes_text_start
    4173                 :                << " kte: 0x" << sess.sym_kprobes_text_end
    4174                 :                << " stext: 0x" << sess.sym_stext
    4175               0 :                << dec << endl;
    4176                 :         }
    4177                 :     }
    4178                 : 
    4179           54599 :   dwflpp* dw = kern_dw;
    4180           54599 :   dwarf_query q(sess, base, location, *dw, parameters, finished_results);
    4181                 : 
    4182           54599 :   if (q.has_absolute)
    4183                 :     {
    4184                 :       // assert guru mode for absolute probes
    4185               4 :       if (! q.base_probe->privileged)
    4186                 :         {
    4187               1 :           throw semantic_error ("absolute statement probe in unprivileged script", q.base_probe->tok);
    4188                 :         }
    4189                 : 
    4190                 :       // For kernel.statement(NUM).absolute probe points, we bypass
    4191                 :       // all the debuginfo stuff: We just wire up a
    4192                 :       // dwarf_derived_probe right here and now.
    4193                 :       dwarf_derived_probe* p =
    4194                 :         new dwarf_derived_probe ("", "", 0, "kernel", "",
    4195                 :                                  q.statement_num_val, q.statement_num_val,
    4196               3 :                                  q, 0);
    4197               3 :       finished_results.push_back (p);
    4198               3 :       return;
    4199                 :     }
    4200                 : 
    4201           54595 :   dw->iterate_over_modules(&query_module, &q);
    4202                 : }
    4203                 : 
    4204                 : 
    4205                 : 
    4206                 : // ------------------------------------------------------------------------
    4207                 : // user-space probes
    4208                 : // ------------------------------------------------------------------------
    4209                 : 
    4210                 : struct uprobe_derived_probe: public derived_probe
    4211               0 : {
    4212                 :   uint64_t process, address;
    4213                 :   bool return_p;
    4214                 :   uprobe_derived_probe (systemtap_session &s, probe* p, probe_point* l,
    4215                 :                         uint64_t, uint64_t, bool);
    4216                 :   void join_group (systemtap_session& s);
    4217                 : };
    4218                 : 
    4219                 : 
    4220                 : struct uprobe_derived_probe_group: public generic_dpg<uprobe_derived_probe>
    4221               0 : {
    4222                 : public:
    4223                 :   void emit_module_decls (systemtap_session& s);
    4224                 :   void emit_module_init (systemtap_session& s);
    4225                 :   void emit_module_exit (systemtap_session& s);
    4226                 : };
    4227                 : 
    4228                 : 
    4229                 : uprobe_derived_probe::uprobe_derived_probe (systemtap_session &s,
    4230                 :                                             probe* p, probe_point* l,
    4231               0 :                                             uint64_t pp, uint64_t aa, bool rr):
    4232               0 :   derived_probe(p, l), process(pp), address(aa), return_p (rr)
    4233                 : {
    4234               0 :   s.need_uprobes = true;
    4235               0 : }
    4236                 : 
    4237                 : 
    4238                 : void
    4239               0 : uprobe_derived_probe::join_group (systemtap_session& s)
    4240                 : {
    4241               0 :   if (! s.uprobe_derived_probes)
    4242               0 :     s.uprobe_derived_probes = new uprobe_derived_probe_group ();
    4243               0 :   s.uprobe_derived_probes->enroll (this);
    4244               0 : }
    4245                 : 
    4246                 : 
    4247                 : struct uprobe_builder: public derived_probe_builder
    4248               0 : {
    4249             970 :   uprobe_builder() {}
    4250                 :   virtual void build(systemtap_session & sess,
    4251                 :                      probe * base,
    4252                 :                      probe_point * location,
    4253                 :                      std::map<std::string, literal *> const & parameters,
    4254               0 :                      vector<derived_probe *> & finished_results)
    4255                 :   {
    4256                 :     int64_t process, address;
    4257                 : 
    4258               0 :     bool b1 = get_param (parameters, TOK_PROCESS, process);
    4259               0 :     bool b2 = get_param (parameters, TOK_STATEMENT, address);
    4260               0 :     bool rr = has_null_param (parameters, TOK_RETURN);
    4261               0 :     assert (b1 && b2); // by pattern_root construction
    4262                 : 
    4263                 :     finished_results.push_back(new uprobe_derived_probe(sess, base, location,
    4264               0 :                                                         process, address, rr));
    4265               0 :   }
    4266                 : };
    4267                 : 
    4268                 : 
    4269                 : void
    4270               0 : uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
    4271                 : {
    4272               0 :   if (probes.empty()) return;
    4273               0 :   s.op->newline() << "/* ---- user probes ---- */";
    4274                 : 
    4275                 :   // If uprobes isn't in the kernel, pull it in from the runtime.
    4276               0 :   s.op->newline() << "#if defined(CONFIG_UPROBES) || defined(CONFIG_UPROBES_MODULE)";
    4277               0 :   s.op->newline() << "#include <linux/uprobes.h>";
    4278               0 :   s.op->newline() << "#else";
    4279               0 :   s.op->newline() << "#include \"uprobes/uprobes.h\"";
    4280               0 :   s.op->newline() << "#endif";
    4281                 : 
    4282               0 :   s.op->newline() << "struct stap_uprobe {";
    4283               0 :   s.op->newline(1) << "union { struct uprobe up; struct uretprobe urp; };";
    4284               0 :   s.op->newline() << "unsigned registered_p:1;";
    4285               0 :   s.op->newline() << "unsigned return_p:1;";
    4286               0 :   s.op->newline() << "unsigned long process;";
    4287               0 :   s.op->newline() << "unsigned long address;";
    4288               0 :   s.op->newline() << "const char *pp;";
    4289               0 :   s.op->newline() << "void (*ph) (struct context*);";
    4290               0 :   s.op->newline(-1) << "} stap_uprobes [] = {";
    4291               0 :   s.op->indent(1);
    4292               0 :   for (unsigned i =0; i<probes.size(); i++)
    4293                 :     {
    4294               0 :       uprobe_derived_probe* p = probes[i];
    4295               0 :       s.op->newline() << "{";
    4296               0 :       s.op->line() << " .address=0x" << hex << p->address << dec << "UL,";
    4297               0 :       s.op->line() << " .process=" << p->process << ",";
    4298               0 :       s.op->line() << " .pp=" << lex_cast_qstring (*p->sole_location()) << ",";
    4299               0 :       s.op->line() << " .ph=&" << p->name << ",";
    4300               0 :       if (p->return_p) s.op->line() << " .return_p=1,";
    4301               0 :       s.op->line() << " },";
    4302                 :     }
    4303               0 :   s.op->newline(-1) << "};";
    4304                 : 
    4305               0 :   s.op->newline();
    4306               0 :   s.op->newline() << "void enter_uprobe_probe (struct uprobe *inst, struct pt_regs *regs) {";
    4307               0 :   s.op->newline(1) << "struct stap_uprobe *sup = container_of(inst, struct stap_uprobe, up);";
    4308               0 :   common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
    4309               0 :   s.op->newline() << "c->probe_point = sup->pp;";
    4310               0 :   s.op->newline() << "c->regs = regs;";
    4311               0 :   s.op->newline() << "(*sup->ph) (c);";
    4312               0 :   common_probe_entryfn_epilogue (s.op);
    4313               0 :   s.op->newline(-1) << "}";
    4314                 : 
    4315               0 :   s.op->newline() << "void enter_uretprobe_probe (struct uretprobe_instance *inst, struct pt_regs *regs) {";
    4316               0 :   s.op->newline(1) << "struct stap_uprobe *sup = container_of(inst->rp, struct stap_uprobe, urp);";
    4317               0 :   common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
    4318               0 :   s.op->newline() << "c->probe_point = sup->pp;";
    4319                 :   // XXX: kretprobes saves "c->pi = inst;" too
    4320               0 :   s.op->newline() << "c->regs = regs;";
    4321               0 :   s.op->newline() << "(*sup->ph) (c);";
    4322               0 :   common_probe_entryfn_epilogue (s.op);
    4323               0 :   s.op->newline(-1) << "}";
    4324                 : }
    4325                 : 
    4326                 : 
    4327                 : void
    4328               0 : uprobe_derived_probe_group::emit_module_init (systemtap_session& s)
    4329                 : {
    4330               0 :   if (probes.empty()) return;
    4331               0 :   s.op->newline() << "/* ---- user probes ---- */";
    4332                 : 
    4333               0 :   s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
    4334               0 :   s.op->newline(1) << "struct stap_uprobe *sup = & stap_uprobes[i];";
    4335               0 :   s.op->newline() << "probe_point = sup->pp;";
    4336               0 :   s.op->newline() << "if (sup->return_p) {";
    4337               0 :   s.op->newline(1) << "sup->urp.u.pid = sup->process;";
    4338               0 :   s.op->newline() << "sup->urp.u.vaddr = sup->address;";
    4339               0 :   s.op->newline() << "sup->urp.handler = &enter_uretprobe_probe;";
    4340               0 :   s.op->newline() << "rc = register_uretprobe (& sup->urp);";
    4341               0 :   s.op->newline(-1) << "} else {";
    4342               0 :   s.op->newline(1) << "sup->up.pid = sup->process;";
    4343               0 :   s.op->newline() << "sup->up.vaddr = sup->address;";
    4344               0 :   s.op->newline() << "sup->up.handler = &enter_uprobe_probe;";
    4345               0 :   s.op->newline() << "rc = register_uprobe (& sup->up);";
    4346               0 :   s.op->newline(-1) << "}";
    4347               0 :   s.op->newline() << "if (rc) {";
    4348               0 :   s.op->newline(1) << "for (j=i-1; j>=0; j--) {"; // partial rollback
    4349               0 :   s.op->newline(1) << "struct stap_uprobe *sup2 = & stap_uprobes[j];";
    4350               0 :   s.op->newline() << "if (sup2->return_p) unregister_uretprobe (&sup2->urp);";
    4351               0 :   s.op->newline() << "else unregister_uprobe (&sup2->up);";
    4352                 :   // NB: we don't have to clear sup2->registered_p, since the module_exit code is
    4353                 :   // not run for this early-abort case.
    4354               0 :   s.op->newline(-1) << "}";
    4355               0 :   s.op->newline() << "break;"; // don't attempt to register any more probes
    4356               0 :   s.op->newline(-1) << "}";
    4357               0 :   s.op->newline() << "else sup->registered_p = 1;";
    4358               0 :   s.op->newline(-1) << "}";
    4359                 : }
    4360                 : 
    4361                 : 
    4362                 : void
    4363               0 : uprobe_derived_probe_group::emit_module_exit (systemtap_session& s)
    4364                 : {
    4365               0 :   if (probes.empty()) return;
    4366               0 :   s.op->newline() << "/* ---- user probes ---- */";
    4367                 : 
    4368               0 :   s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
    4369               0 :   s.op->newline(1) << "struct stap_uprobe *sup = & stap_uprobes[i];";
    4370               0 :   s.op->newline() << "if (! sup->registered_p) continue;";
    4371                 :   // s.op->newline() << "atomic_add (sdp->u.krp.nmissed, & skipped_count);";
    4372                 :   // s.op->newline() << "atomic_add (sdp->u.krp.kp.nmissed, & skipped_count);";
    4373               0 :   s.op->newline() << "if (sup->return_p) unregister_uretprobe (&sup->urp);";
    4374               0 :   s.op->newline() << "else unregister_uprobe (&sup->up);";
    4375               0 :   s.op->newline() << "sup->registered_p = 0;";
    4376               0 :   s.op->newline(-1) << "}";
    4377                 : }
    4378                 : 
    4379                 : 
    4380                 : 
    4381                 : // ------------------------------------------------------------------------
    4382                 : // timer derived probes
    4383                 : // ------------------------------------------------------------------------
    4384                 : 
    4385                 : 
    4386                 : struct timer_derived_probe: public derived_probe
    4387               0 : {
    4388                 :   int64_t interval, randomize;
    4389                 :   bool time_is_msecs; // NB: hrtimers get ms-based probes on modern kernels instead
    4390                 :   timer_derived_probe (probe* p, probe_point* l, int64_t i, int64_t r, bool ms=false);
    4391                 :   virtual void join_group (systemtap_session& s);
    4392                 : };
    4393                 : 
    4394                 : 
    4395                 : struct timer_derived_probe_group: public generic_dpg<timer_derived_probe>
    4396               8 : {
    4397                 :   void emit_interval (translator_output* o);
    4398                 : public:
    4399                 :   void emit_module_decls (systemtap_session& s);
    4400                 :   void emit_module_init (systemtap_session& s);
    4401                 :   void emit_module_exit (systemtap_session& s);
    4402                 : };
    4403                 : 
    4404                 : 
    4405              12 : timer_derived_probe::timer_derived_probe (probe* p, probe_point* l, int64_t i, int64_t r, bool ms):
    4406              12 :   derived_probe (p, l), interval (i), randomize (r), time_is_msecs(ms)
    4407                 : {
    4408              12 :   if (interval <= 0 || interval > 1000000) // make i and r fit into plain ints
    4409               0 :     throw semantic_error ("invalid interval for jiffies timer");
    4410                 :   // randomize = 0 means no randomization
    4411              12 :   if (randomize < 0 || randomize > interval)
    4412               0 :     throw semantic_error ("invalid randomize for jiffies timer");
    4413                 : 
    4414              12 :   if (locations.size() != 1)
    4415               0 :     throw semantic_error ("expect single probe point");
    4416                 :   // so we don't have to loop over them in the other functions
    4417              12 : }
    4418                 : 
    4419                 : 
    4420                 : void
    4421              12 : timer_derived_probe::join_group (systemtap_session& s)
    4422                 : {
    4423              12 :   if (! s.timer_derived_probes)
    4424               8 :     s.timer_derived_probes = new timer_derived_probe_group ();
    4425              12 :   s.timer_derived_probes->enroll (this);
    4426              12 : }
    4427                 : 
    4428                 : 
    4429                 : void
    4430              16 : timer_derived_probe_group::emit_interval (translator_output* o)
    4431                 : {
    4432              16 :   o->line() << "({";
    4433              16 :   o->newline(1) << "unsigned i = stp->intrv;";
    4434              16 :   o->newline() << "if (stp->rnd != 0)";
    4435              16 :   o->newline(1) << "i += _stp_random_pm(stp->rnd);";
    4436              16 :   o->newline(-1) << "stp->ms ? msecs_to_jiffies(i) : i;";
    4437              16 :   o->newline(-1) << "})";
    4438              16 : }
    4439                 : 
    4440                 : 
    4441                 : void
    4442               8 : timer_derived_probe_group::emit_module_decls (systemtap_session& s)
    4443                 : {
    4444               8 :   if (probes.empty()) return;
    4445                 : 
    4446               8 :   s.op->newline() << "/* ---- timer probes ---- */";
    4447                 : 
    4448               8 :   s.op->newline() << "struct stap_timer_probe {";
    4449               8 :   s.op->newline(1) << "struct timer_list timer_list;";
    4450               8 :   s.op->newline() << "const char *pp;";
    4451               8 :   s.op->newline() << "void (*ph) (struct context*);";
    4452               8 :   s.op->newline() << "unsigned intrv, ms, rnd;";
    4453               8 :   s.op->newline(-1) << "} stap_timer_probes [" << probes.size() << "] = {";
    4454               8 :   s.op->indent(1);
    4455              40 :   for (unsigned i=0; i < probes.size(); i++)
    4456                 :     {
    4457              12 :       s.op->newline () << "{";
    4458                 :       s.op->line() << " .pp="
    4459              12 :                    << lex_cast_qstring (*probes[i]->sole_location()) << ",";
    4460              12 :       s.op->line() << " .ph=&" << probes[i]->name << ",";
    4461              12 :       s.op->line() << " .intrv=" << probes[i]->interval << ",";
    4462              12 :       s.op->line() << " .ms=" << probes[i]->time_is_msecs << ",";
    4463              12 :       s.op->line() << " .rnd=" << probes[i]->randomize;
    4464              12 :       s.op->line() << " },";
    4465                 :     }
    4466               8 :   s.op->newline(-1) << "};";
    4467               8 :   s.op->newline();
    4468                 : 
    4469               8 :   s.op->newline() << "static void enter_timer_probe (unsigned long val) {";
    4470               8 :   s.op->newline(1) << "struct stap_timer_probe* stp = & stap_timer_probes [val];";
    4471               8 :   s.op->newline() << "if ((atomic_read (&session_state) == STAP_SESSION_STARTING) ||";
    4472               8 :   s.op->newline() << "    (atomic_read (&session_state) == STAP_SESSION_RUNNING))";
    4473               8 :   s.op->newline(1) << "mod_timer (& stp->timer_list, jiffies + ";
    4474               8 :   emit_interval (s.op);
    4475               8 :   s.op->line() << ");";
    4476               8 :   s.op->newline(-1) << "{";
    4477               8 :   s.op->indent(1);
    4478               8 :   common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
    4479               8 :   s.op->newline() << "c->probe_point = stp->pp;";
    4480               8 :   s.op->newline() << "(*stp->ph) (c);";
    4481               8 :   common_probe_entryfn_epilogue (s.op);
    4482               8 :   s.op->newline(-1) << "}";
    4483               8 :   s.op->newline(-1) << "}";
    4484                 : }
    4485                 : 
    4486                 : 
    4487                 : void
    4488               8 : timer_derived_probe_group::emit_module_init (systemtap_session& s)
    4489                 : {
    4490               8 :   if (probes.empty()) return;
    4491                 : 
    4492               8 :   s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
    4493               8 :   s.op->newline(1) << "struct stap_timer_probe* stp = & stap_timer_probes [i];";
    4494               8 :   s.op->newline() << "probe_point = stp->pp;";
    4495               8 :   s.op->newline() << "init_timer (& stp->timer_list);";
    4496               8 :   s.op->newline() << "stp->timer_list.function = & enter_timer_probe;";
    4497               8 :   s.op->newline() << "stp->timer_list.data = i;"; // NB: important!
    4498                 :   // copy timer renew calculations from above :-(
    4499               8 :   s.op->newline() << "stp->timer_list.expires = jiffies + ";
    4500               8 :   emit_interval (s.op);
    4501               8 :   s.op->line() << ";";
    4502               8 :   s.op->newline() << "add_timer (& stp->timer_list);";
    4503                 :   // note: no partial failure rollback is needed: add_timer cannot fail.
    4504               8 :   s.op->newline(-1) << "}"; // for loop
    4505                 : }
    4506                 : 
    4507                 : 
    4508                 : void
    4509              14 : timer_derived_probe_group::emit_module_exit (systemtap_session& s)
    4510                 : {
    4511              14 :   if (probes.empty()) return;
    4512                 : 
    4513              14 :   s.op->newline() << "for (i=0; i<" << probes.size() << "; i++)";
    4514              14 :   s.op->newline(1) << "del_timer_sync (& stap_timer_probes[i].timer_list);";
    4515              14 :   s.op->indent(-1);
    4516                 : }
    4517                 : 
    4518                 : 
    4519                 : 
    4520                 : // ------------------------------------------------------------------------
    4521                 : // profile derived probes
    4522                 : // ------------------------------------------------------------------------
    4523                 : //   On kernels < 2.6.10, this uses the register_profile_notifier API to
    4524                 : //   generate the timed events for profiling; on kernels >= 2.6.10 this
    4525                 : //   uses the register_timer_hook API.  The latter doesn't currently allow
    4526                 : //   simultaneous users, so insertion will fail if the profiler is busy.
    4527                 : //   (Conflicting users may include OProfile, other SystemTap probes, etc.)
    4528                 : 
    4529                 : 
    4530                 : struct profile_derived_probe: public derived_probe
    4531               0 : {
    4532                 :   profile_derived_probe (systemtap_session &s, probe* p, probe_point* l);
    4533                 :   void join_group (systemtap_session& s);
    4534                 : };
    4535                 : 
    4536                 : 
    4537                 : struct profile_derived_probe_group: public generic_dpg<profile_derived_probe>
    4538               7 : {
    4539                 : public:
    4540                 :   void emit_module_decls (systemtap_session& s);
    4541                 :   void emit_module_init (systemtap_session& s);
    4542                 :   void emit_module_exit (systemtap_session& s);
    4543                 : };
    4544                 : 
    4545                 : 
    4546               7 : profile_derived_probe::profile_derived_probe (systemtap_session &, probe* p, probe_point* l):
    4547               7 :   derived_probe(p, l)
    4548                 : {
    4549               7 : }
    4550                 : 
    4551                 : 
    4552                 : void
    4553               7 : profile_derived_probe::join_group (systemtap_session& s)
    4554                 : {
    4555               7 :   if (! s.profile_derived_probes)
    4556               7 :     s.profile_derived_probes = new profile_derived_probe_group ();
    4557               7 :   s.profile_derived_probes->enroll (this);
    4558               7 : }
    4559                 : 
    4560                 : 
    4561                 : struct profile_builder: public derived_probe_builder
    4562               0 : {
    4563             485 :   profile_builder() {}
    4564                 :   virtual void build(systemtap_session & sess,
    4565                 :                      probe * base,
    4566                 :                      probe_point * location,
    4567                 :                      std::map<std::string, literal *> const &,
    4568               7 :                      vector<derived_probe *> & finished_results)
    4569                 :   {
    4570               7 :     finished_results.push_back(new profile_derived_probe(sess, base, location));
    4571               7 :   }
    4572                 : };
    4573                 : 
    4574                 : 
    4575                 : // timer.profile probe handlers are hooked up in an entertaining way
    4576                 : // to the underlying kernel facility.  The fact that 2.6.11+ era
    4577                 : // "register_timer_hook" API allows only one consumer *system-wide*
    4578                 : // will give a hint.  We will have a single entry function (and thus
    4579                 : // trivial registration / unregistration), and it will call all probe
    4580                 : // handler functions in sequence.
    4581                 : 
    4582                 : void
    4583               7 : profile_derived_probe_group::emit_module_decls (systemtap_session& s)
    4584                 : {
    4585               7 :   if (probes.empty()) return;
    4586                 : 
    4587                 :   // kernels < 2.6.10: use register_profile_notifier API
    4588                 :   // kernels >= 2.6.10: use register_timer_hook API
    4589               7 :   s.op->newline() << "/* ---- profile probes ---- */";
    4590                 : 
    4591                 :   // This function calls all the profiling probe handlers in sequence.
    4592                 :   // The only tricky thing is that the context will be reused amongst
    4593                 :   // them.  While a simple sequence of calls to the individual probe
    4594                 :   // handlers is unlikely to go terribly wrong (with c->last_error
    4595                 :   // being set causing an early return), but for extra assurance, we
    4596                 :   // open-code the same logic here.
    4597                 : 
    4598               7 :   s.op->newline() << "static void enter_all_profile_probes (struct pt_regs *regs) {";
    4599               7 :   s.op->indent(1);
    4600               7 :   common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
    4601               7 :   s.op->newline() << "c->probe_point = \"timer.profile\";"; // NB: hard-coded for convenience
    4602               7 :   s.op->newline() << "c->regs = regs;";
    4603                 : 
    4604              14 :   for (unsigned i=0; i<probes.size(); i++)
    4605                 :     {
    4606               7 :       if (i > 0)
    4607                 :         {
    4608                 :           // Some lightweight inter-probe context resetting
    4609                 :           // XXX: not quite right: MAXERRORS not respected
    4610               0 :           s.op->newline() << "c->actionremaining = MAXACTION;";
    4611                 :         }
    4612               7 :       s.op->newline() << "if (c->last_error == NULL) " << probes[i]->name << " (c);";
    4613                 :     }
    4614               7 :   common_probe_entryfn_epilogue (s.op);
    4615               7 :   s.op->newline(-1) << "}";
    4616                 : 
    4617               7 :   s.op->newline() << "#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)"; // == using_rpn of yore
    4618                 : 
    4619                 :   s.op->newline() << "int enter_profile_probes (struct notifier_block *self,"
    4620               7 :                   << " unsigned long val, void *data) {";
    4621               7 :   s.op->newline(1) << "(void) self; (void) val;";
    4622               7 :   s.op->newline() << "enter_all_profile_probes ((struct pt_regs *) data);";
    4623               7 :   s.op->newline() << "return 0;";
    4624               7 :   s.op->newline(-1) << "}";
    4625                 :   s.op->newline() << "struct notifier_block stap_profile_notifier = {"
    4626               7 :                   << " .notifier_call = & enter_profile_probes };";
    4627                 : 
    4628               7 :   s.op->newline() << "#else";
    4629                 : 
    4630               7 :   s.op->newline() << "int enter_profile_probes (struct pt_regs *regs) {";
    4631               7 :   s.op->newline(1) << "enter_all_profile_probes (regs);";
    4632               7 :   s.op->newline() << "return 0;";
    4633               7 :   s.op->newline(-1) << "}";
    4634                 : 
    4635               7 :   s.op->newline() << "#endif";
    4636                 : }
    4637                 : 
    4638                 : 
    4639                 : void
    4640               7 : profile_derived_probe_group::emit_module_init (systemtap_session& s)
    4641                 : {
    4642               7 :   if (probes.empty()) return;
    4643                 : 
    4644               7 :   s.op->newline() << "probe_point = \"timer.profile\";"; // NB: hard-coded for convenience
    4645               7 :   s.op->newline() << "#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)"; // == using_rpn of yore
    4646               7 :   s.op->newline() << "rc = register_profile_notifier (& stap_profile_notifier);";
    4647               7 :   s.op->newline() << "#else";
    4648               7 :   s.op->newline() << "rc = register_timer_hook (& enter_profile_probes);";
    4649               7 :   s.op->newline() << "#endif";
    4650                 : }
    4651                 : 
    4652                 : 
    4653                 : void
    4654              13 : profile_derived_probe_group::emit_module_exit (systemtap_session& s)
    4655                 : {
    4656              13 :   if (probes.empty()) return;
    4657                 : 
    4658              13 :   s.op->newline() << "for (i=0; i<" << probes.size() << "; i++)";
    4659              13 :   s.op->newline(1) << "#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)"; // == using_rpn of yore
    4660              13 :   s.op->newline() << "unregister_profile_notifier (& stap_profile_notifier);";
    4661              13 :   s.op->newline() << "#else";
    4662              13 :   s.op->newline() << "unregister_timer_hook (& enter_profile_probes);";
    4663              13 :   s.op->newline() << "#endif";
    4664              13 :   s.op->indent(-1);
    4665                 : }
    4666                 : 
    4667                 : 
    4668                 : // ------------------------------------------------------------------------
    4669                 : // procfs file derived probes
    4670                 : // ------------------------------------------------------------------------
    4671                 : 
    4672                 : 
    4673                 : struct procfs_derived_probe: public derived_probe
    4674               0 : {
    4675                 :   string path;
    4676                 :   bool write;
    4677                 :   bool target_symbol_seen;
    4678                 : 
    4679                 :   procfs_derived_probe (systemtap_session &, probe* p, probe_point* l, string ps, bool w);
    4680                 :   void join_group (systemtap_session& s);
    4681                 : };
    4682                 : 
    4683                 : 
    4684                 : struct procfs_probe_set
    4685                 : {
    4686                 :   procfs_derived_probe* read_probe;
    4687                 :   procfs_derived_probe* write_probe;
    4688                 : 
    4689               3 :   procfs_probe_set () : read_probe (NULL), write_probe (NULL) {}
    4690                 : };
    4691                 : 
    4692                 : 
    4693                 : struct procfs_derived_probe_group: public generic_dpg<procfs_derived_probe>
    4694               0 : {
    4695                 : private:
    4696                 :   map<string, procfs_probe_set*> probes_by_path;
    4697                 :   typedef map<string, procfs_probe_set*>::iterator p_b_p_iterator;
    4698                 :   bool has_read_probes;
    4699                 :   bool has_write_probes;
    4700                 : 
    4701                 : public:
    4702               3 :   procfs_derived_probe_group () :
    4703               3 :     has_read_probes(false), has_write_probes(false) {}
    4704                 : 
    4705                 :   void enroll (procfs_derived_probe* probe);
    4706                 :   void emit_module_decls (systemtap_session& s);
    4707                 :   void emit_module_init (systemtap_session& s);
    4708                 :   void emit_module_exit (systemtap_session& s);
    4709                 : };
    4710                 : 
    4711                 : 
    4712                 : struct procfs_var_expanding_copy_visitor: public var_expanding_copy_visitor
    4713               9 : {
    4714                 :   procfs_var_expanding_copy_visitor(systemtap_session& s, const string& pn,
    4715               9 :                                     string path, bool write_probe):
    4716                 :     sess (s), probe_name (pn), path (path), write_probe (write_probe),
    4717               9 :     target_symbol_seen (false) {}
    4718                 : 
    4719                 :   systemtap_session& sess;
    4720                 :   string probe_name;
    4721                 :   string path;
    4722                 :   bool write_probe;
    4723                 :   bool target_symbol_seen;
    4724                 : 
    4725                 :   void visit_target_symbol (target_symbol* e);
    4726                 : };
    4727                 : 
    4728                 : 
    4729                 : procfs_derived_probe::procfs_derived_probe (systemtap_session &s, probe* p,
    4730               9 :                                             probe_point* l, string ps, bool w):
    4731               9 :   derived_probe(p, l), path(ps), write(w), target_symbol_seen(false)
    4732                 : {
    4733                 :   // Make a local-variable-expanded copy of the probe body
    4734               9 :   procfs_var_expanding_copy_visitor v (s, name, path, write);
    4735               9 :   require <block*> (&v, &(this->body), base->body);
    4736               5 :   target_symbol_seen = v.target_symbol_seen;
    4737               5 : }
    4738                 : 
    4739                 : 
    4740                 : void
    4741               5 : procfs_derived_probe::join_group (systemtap_session& s)
    4742                 : {
    4743               5 :   if (! s.procfs_derived_probes)
    4744               3 :     s.procfs_derived_probes = new procfs_derived_probe_group ();
    4745               5 :   s.procfs_derived_probes->enroll (this);
    4746               5 : }
    4747                 : 
    4748                 : 
    4749                 : void
    4750               5 : procfs_derived_probe_group::enroll (procfs_derived_probe* p)
    4751                 : {
    4752                 :   procfs_probe_set *pset;
    4753                 : 
    4754               5 :   if (probes_by_path.count(p->path) == 0)
    4755                 :     {
    4756               3 :       pset = new procfs_probe_set;
    4757               3 :       probes_by_path[p->path] = pset;
    4758                 :     }
    4759                 :   else
    4760                 :     {
    4761               2 :       pset = probes_by_path[p->path];
    4762                 : 
    4763                 :       // You can only specify 1 read and 1 write probe.
    4764               2 :       if (p->write && pset->write_probe != NULL)
    4765               0 :         throw semantic_error("only one write procfs probe can exist for procfs path \"" + p->path + "\"");
    4766               2 :       else if (! p->write && pset->read_probe != NULL)
    4767               0 :         throw semantic_error("only one read procfs probe can exist for procfs path \"" + p->path + "\"");
    4768                 : 
    4769                 :       // XXX: multiple writes should be acceptable
    4770                 :     }
    4771                 : 
    4772               5 :   if (p->write)
    4773                 :   {
    4774               3 :     pset->write_probe = p;
    4775               3 :     has_write_probes = true;
    4776                 :   }
    4777                 :   else
    4778                 :   {
    4779               2 :     pset->read_probe = p;
    4780               2 :     has_read_probes = true;
    4781                 :   }
    4782               5 : }
    4783                 : 
    4784                 : 
    4785                 : void
    4786               3 : procfs_derived_probe_group::emit_module_decls (systemtap_session& s)
    4787                 : {
    4788               3 :   if (probes_by_path.empty())
    4789               0 :     return;
    4790                 : 
    4791               3 :   s.op->newline() << "/* ---- procfs probes ---- */";
    4792                 : 
    4793                 :   // Emit the procfs probe data list
    4794               3 :   s.op->newline() << "struct stap_procfs_probe {";
    4795               3 :   s.op->newline(1)<< "const char *path;";
    4796               3 :   s.op->newline() << "const char *read_pp;";
    4797               3 :   s.op->newline() << "void (*read_ph) (struct context*);";
    4798               3 :   s.op->newline() << "const char *write_pp;";
    4799               3 :   s.op->newline() << "void (*write_ph) (struct context*);";
    4800               3 :   s.op->newline(-1) << "} stap_procfs_probes[] = {";
    4801               3 :   s.op->indent(1);
    4802                 : 
    4803               6 :   for (p_b_p_iterator it = probes_by_path.begin(); it != probes_by_path.end();
    4804                 :        it++)
    4805                 :   {
    4806               3 :       procfs_probe_set *pset = it->second;
    4807                 : 
    4808               3 :       s.op->newline() << "{";
    4809               3 :       s.op->line() << " .path=" << lex_cast_qstring (it->first) << ",";
    4810                 : 
    4811               3 :       if (pset->read_probe != NULL)
    4812                 :         {
    4813                 :           s.op->line() << " .read_pp="
    4814                 :                        << lex_cast_qstring (*pset->read_probe->sole_location())
    4815               2 :                        << ",";
    4816               2 :           s.op->line() << " .read_ph=&" << pset->read_probe->name << ",";
    4817                 :         }
    4818                 :       else
    4819                 :         {
    4820               1 :           s.op->line() << " .read_pp=NULL,";
    4821               1 :           s.op->line() << " .read_ph=NULL,";
    4822                 :         }
    4823                 : 
    4824               3 :       if (pset->write_probe != NULL)
    4825                 :         {
    4826                 :           s.op->line() << " .write_pp="
    4827                 :                        << lex_cast_qstring (*pset->write_probe->sole_location())
    4828               3 :                        << ",";
    4829               3 :           s.op->line() << " .write_ph=&" << pset->write_probe->name;
    4830                 :         }
    4831                 :       else
    4832                 :         {
    4833               0 :           s.op->line() << " .write_pp=NULL,";
    4834               0 :           s.op->line() << " .write_ph=NULL";
    4835                 :         }
    4836               3 :       s.op->line() << " },";
    4837                 :   }
    4838               3 :   s.op->newline(-1) << "};";
    4839                 : 
    4840               3 :   if (has_read_probes)
    4841                 :     {
    4842                 :       // Output routine to fill in 'page' with our data.
    4843               2 :       s.op->newline();
    4844                 : 
    4845               2 :       s.op->newline() << "static int _stp_procfs_read(char *page, char **start, off_t off, int count, int *eof, void *data) {";
    4846                 : 
    4847               2 :       s.op->newline(1) << "struct stap_procfs_probe *spp = (struct stap_procfs_probe *)data;";
    4848               2 :       s.op->newline() << "int bytes = 0;";
    4849               2 :       s.op->newline() << "string_t strdata = {'\\0'};";
    4850                 : 
    4851               2 :       common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
    4852               2 :       s.op->newline() << "c->probe_point = spp->read_pp;";
    4853                 : 
    4854               2 :       s.op->newline() << "if (c->data == NULL)";
    4855               2 :       s.op->newline(1) << "c->data = &strdata;";
    4856               2 :       s.op->newline(-1) << "else {";
    4857                 : 
    4858               2 :       s.op->newline(1) << "if (unlikely (atomic_inc_return (& skipped_count) > MAXSKIPPED)) {";
    4859               2 :       s.op->newline(1) << "atomic_set (& session_state, STAP_SESSION_ERROR);";
    4860               2 :       s.op->newline() << "_stp_exit ();";
    4861               2 :       s.op->newline(-1) << "}";
    4862               2 :       s.op->newline() << "atomic_dec (& c->busy);";
    4863               2 :       s.op->newline() << "goto probe_epilogue;";
    4864               2 :       s.op->newline(-1) << "}";
    4865                 : 
    4866                 :       // call probe function (which copies data into strdata)
    4867               2 :       s.op->newline() << "(*spp->read_ph) (c);";
    4868                 : 
    4869                 :       // copy string data into 'page'
    4870               2 :       s.op->newline() << "c->data = NULL;";
    4871               2 :       s.op->newline() << "bytes = strnlen(strdata, MAXSTRINGLEN - 1);";
    4872               2 :       s.op->newline() << "if (off >= bytes)";
    4873               2 :       s.op->newline(1) << "*eof = 1;";
    4874               2 :       s.op->newline(-1) << "else {";
    4875               2 :       s.op->newline(1) << "bytes -= off;";
    4876               2 :       s.op->newline() << "if (bytes > count)";
    4877               2 :       s.op->newline(1) << "bytes = count;";
    4878               2 :       s.op->newline(-1) << "memcpy(page, strdata + off, bytes);";
    4879               2 :       s.op->newline() << "*start = page;";
    4880               2 :       s.op->newline(-1) << "}";
    4881                 : 
    4882               2 :       common_probe_entryfn_epilogue (s.op);
    4883               2 :       s.op->newline() << "return bytes;";
    4884                 : 
    4885               2 :       s.op->newline(-1) << "}";
    4886                 :     }
    4887               3 :   if (has_write_probes)
    4888                 :     {
    4889               3 :       s.op->newline() << "static int _stp_procfs_write(struct file *file, const char *buffer, unsigned long count, void *data) {";
    4890                 : 
    4891               3 :       s.op->newline(1) << "struct stap_procfs_probe *spp = (struct stap_procfs_probe *)data;";
    4892               3 :       s.op->newline() << "string_t strdata = {'\\0'};";
    4893                 : 
    4894               3 :       common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
    4895               3 :       s.op->newline() << "c->probe_point = spp->write_pp;";
    4896                 : 
    4897               3 :       s.op->newline() << "if (count > (MAXSTRINGLEN - 1))";
    4898               3 :       s.op->newline(1) << "count = MAXSTRINGLEN - 1;";
    4899               3 :       s.op->newline(-1) << "_stp_copy_from_user(strdata, buffer, count);";
    4900                 : 
    4901               3 :       s.op->newline() << "if (c->data == NULL)";
    4902               3 :       s.op->newline(1) << "c->data = &strdata;";
    4903               3 :       s.op->newline(-1) << "else {";
    4904                 : 
    4905               3 :       s.op->newline(1) << "if (unlikely (atomic_inc_return (& skipped_count) > MAXSKIPPED)) {";
    4906               3 :       s.op->newline(1) << "atomic_set (& session_state, STAP_SESSION_ERROR);";
    4907               3 :       s.op->newline() << "_stp_exit ();";
    4908               3 :       s.op->newline(-1) << "}";
    4909               3 :       s.op->newline() << "atomic_dec (& c->busy);";
    4910               3 :       s.op->newline() << "goto probe_epilogue;";
    4911               3 :       s.op->newline(-1) << "}";
    4912                 : 
    4913                 :       // call probe function (which copies data out of strdata)
    4914               3 :       s.op->newline() << "(*spp->write_ph) (c);";
    4915                 : 
    4916               3 :       s.op->newline() << "c->data = NULL;";
    4917               3 :       common_probe_entryfn_epilogue (s.op);
    4918                 : 
    4919               3 :       s.op->newline() << "return count;";
    4920               3 :       s.op->newline(-1) << "}";
    4921                 :     }
    4922                 : }
    4923                 : 
    4924                 : 
    4925                 : void
    4926               3 : procfs_derived_probe_group::emit_module_init (systemtap_session& s)
    4927                 : {
    4928               3 :   if (probes_by_path.empty())
    4929               0 :     return;
    4930                 : 
    4931               3 :   s.op->newline() << "for (i = 0; i < " << probes_by_path.size() << "; i++) {";
    4932               3 :   s.op->newline(1) << "struct stap_procfs_probe *spp = &stap_procfs_probes[i];";
    4933                 : 
    4934               3 :   s.op->newline() << "if (spp->read_pp)";
    4935               3 :   s.op->newline(1) << "probe_point = spp->read_pp;";
    4936               3 :   s.op->newline(-1) << "else";
    4937               3 :   s.op->newline(1) << "probe_point = spp->write_pp;";
    4938                 : 
    4939               3 :   s.op->newline(-1) << "rc = _stp_create_procfs(spp->path, i);";
    4940                 : 
    4941               3 :   s.op->newline() << "if (rc) {";
    4942               3 :   s.op->newline(1) << "_stp_close_procfs();";
    4943               3 :   s.op->newline() << "break;";
    4944               3 :   s.op->newline(-1) << "}";
    4945                 : 
    4946               3 :   if (has_read_probes)
    4947                 :     {
    4948               2 :       s.op->newline() << "if (spp->read_pp)";
    4949               2 :       s.op->newline(1) << "_stp_procfs_files[i]->read_proc = &_stp_procfs_read;";
    4950               2 :       s.op->newline(-1) << "else";
    4951               2 :       s.op->newline(1) << "_stp_procfs_files[i]->read_proc = NULL;";
    4952               2 :       s.op->indent(-1);
    4953                 :     }
    4954                 :   else
    4955               1 :     s.op->newline() << "_stp_procfs_files[i]->read_proc = NULL;";
    4956                 : 
    4957               3 :   if (has_write_probes)
    4958                 :     {
    4959               3 :       s.op->newline() << "if (spp->write_pp)";
    4960               3 :       s.op->newline(1) << "_stp_procfs_files[i]->write_proc = &_stp_procfs_write;";
    4961               3 :       s.op->newline(-1) << "else";
    4962               3 :       s.op->newline(1) << "_stp_procfs_files[i]->write_proc = NULL;";
    4963               3 :       s.op->indent(-1);
    4964                 :     }
    4965                 :   else
    4966               0 :     s.op->newline() << "_stp_procfs_files[i]->write_proc = NULL;";
    4967                 : 
    4968               3 :   s.op->newline() << "_stp_procfs_files[i]->data = spp;";
    4969               3 :   s.op->newline(-1) << "}"; // for loop
    4970                 : }
    4971                 : 
    4972                 : 
    4973                 : void
    4974               3 : procfs_derived_probe_group::emit_module_exit (systemtap_session& s)
    4975                 : {
    4976               3 :   if (probes_by_path.empty())
    4977               0 :     return;
    4978                 : 
    4979               3 :   s.op->newline() << "_stp_close_procfs();";
    4980                 : }
    4981                 : 
    4982                 : 
    4983                 : void
    4984               9 : procfs_var_expanding_copy_visitor::visit_target_symbol (target_symbol* e)
    4985                 : {
    4986               9 :   assert(e->base_name.size() > 0 && e->base_name[0] == '$');
    4987                 : 
    4988               9 :   if (e->base_name != "$value")
    4989                 :     throw semantic_error ("invalid target symbol for procfs probe, $value expected",
    4990               0 :                           e->tok);
    4991                 : 
    4992               9 :   if (e->components.size() > 0)
    4993                 :     {
    4994               2 :       switch (e->components[0].first)
    4995                 :         {
    4996                 :         case target_symbol::comp_literal_array_index:
    4997                 :           throw semantic_error("procfs target variable '$value' may not be used as array",
    4998               1 :                                e->tok);
    4999                 :           break;
    5000                 :         case target_symbol::comp_struct_member:
    5001                 :           throw semantic_error("procfs target variable '$value' may not be used as a structure",
    5002               1 :                                e->tok);
    5003                 :           break;
    5004                 :         default:
    5005                 :           throw semantic_error ("invalid use of procfs target variable '$value'",
    5006               0 :                                 e->tok);
    5007                 :           break;
    5008                 :         }
    5009                 :     }
    5010                 : 
    5011               7 :   bool lvalue = is_active_lvalue(e);
    5012               7 :   if (write_probe && lvalue)
    5013               1 :     throw semantic_error("procfs $value variable is read-only in a procfs write probe", e->tok);
    5014               6 :   else if (! write_probe && ! lvalue)
    5015               1 :     throw semantic_error("procfs $value variable cannot be read in a procfs read probe", e->tok);
    5016                 : 
    5017                 :   // Remember that we've seen a target variable.
    5018               5 :   target_symbol_seen = true;
    5019                 : 
    5020                 :   // Synthesize a function.
    5021               5 :   functiondecl *fdecl = new functiondecl;
    5022               5 :   fdecl->tok = e->tok;
    5023              10 :   embeddedcode *ec = new embeddedcode;
    5024               5 :   ec->tok = e->tok;
    5025                 : 
    5026                 :   string fname = (string(lvalue ? "_procfs_value_set" : "_procfs_value_get")
    5027               7 :                   + "_" + lex_cast<string>(tick++));
    5028              10 :   string locvalue = "CONTEXT->data";
    5029                 : 
    5030               5 :   if (! lvalue)
    5031                 :     ec->code = string("strlcpy (THIS->__retvalue, ") + locvalue
    5032               3 :       + string(", MAXSTRINGLEN); /* pure */");
    5033                 :   else
    5034                 :     ec->code = string("strlcpy (") + locvalue
    5035               2 :       + string(", THIS->value, MAXSTRINGLEN);");
    5036                 : 
    5037               5 :   fdecl->name = fname;
    5038               5 :   fdecl->body = ec;
    5039               5 :   fdecl->type = pe_string;
    5040                 : 
    5041               5 :   if (lvalue)
    5042                 :     {
    5043                 :       // Modify the fdecl so it carries a single pe_string formal
    5044                 :       // argument called "value".
    5045                 : 
    5046               2 :       vardecl *v = new vardecl;
    5047               2 :       v->type = pe_string;
    5048               2 :       v->name = "value";
    5049               2 :       v->tok = e->tok;
    5050               2 :       fdecl->formal_args.push_back(v);
    5051                 :     }
    5052               5 :   sess.functions.push_back(fdecl);
    5053                 : 
    5054                 :   // Synthesize a functioncall.
    5055               5 :   functioncall* n = new functioncall;
    5056               5 :   n->tok = e->tok;
    5057               5 :   n->function = fname;
    5058               5 :   n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
    5059                 : 
    5060               5 :   if (lvalue)
    5061                 :     {
    5062                 :       // Provide the functioncall to our parent, so that it can be
    5063                 :       // used to substitute for the assignment node immediately above
    5064                 :       // us.
    5065               2 :       assert(!target_symbol_setter_functioncalls.empty());
    5066               2 :       *(target_symbol_setter_functioncalls.top()) = n;
    5067                 :     }
    5068                 : 
    5069               5 :   provide <functioncall*> (this, n);
    5070               5 : }
    5071                 : 
    5072                 : 
    5073                 : struct procfs_builder: public derived_probe_builder
    5074               0 : {
    5075            1940 :   procfs_builder() {}
    5076                 :   virtual void build(systemtap_session & sess,
    5077                 :                      probe * base,
    5078                 :                      probe_point * location,
    5079                 :                      std::map<std::string, literal *> const & parameters,
    5080                 :                      vector<derived_probe *> & finished_results);
    5081                 : };
    5082                 : 
    5083                 : 
    5084                 : void
    5085                 : procfs_builder::build(systemtap_session & sess,
    5086                 :                       probe * base,
    5087                 :                       probe_point * location,
    5088                 :                       std::map<std::string, literal *> const & parameters,
    5089              14 :                       vector<derived_probe *> & finished_results)
    5090                 : {
    5091              14 :   string path;
    5092              14 :   bool has_procfs = get_param(parameters, "procfs", path);
    5093              28 :   bool has_read = (parameters.find("read") != parameters.end());
    5094              28 :   bool has_write = (parameters.find("write") != parameters.end());
    5095                 : 
    5096                 :   // If no procfs path, default to "command".  The runtime will do
    5097                 :   // this for us, but if we don't do it here, we'll think the
    5098                 :   // following 2 probes are attached to different paths:
    5099                 :   //
    5100                 :   //   probe procfs("command").read {}"
    5101                 :   //   probe procfs.write {}
    5102                 : 
    5103              14 :   if (! has_procfs)
    5104               4 :     path = "command";
    5105                 :   // If we have a path, we need to validate it.
    5106                 :   else
    5107                 :     {
    5108                 :       string::size_type start_pos, end_pos;
    5109              10 :       string component;
    5110              10 :       start_pos = 0;
    5111              24 :       while ((end_pos = path.find('/', start_pos)) != string::npos)
    5112                 :         {
    5113                 :           // Make sure it doesn't start with '/'.
    5114               7 :           if (end_pos == 0)
    5115                 :             throw semantic_error ("procfs path cannot start with a '/'",
    5116               1 :                                   location->tok);
    5117                 : 
    5118               6 :           component = path.substr(start_pos, end_pos - start_pos);
    5119                 :           // Make sure it isn't empty.
    5120               6 :           if (component.size() == 0)
    5121                 :             throw semantic_error ("procfs path component cannot be empty",
    5122               1 :                                   location->tok);
    5123                 :           // Make sure it isn't relative.
    5124               5 :           else if (component == "." || component == "..")
    5125               1 :             throw semantic_error ("procfs path cannot be relative (and contain '.' or '..')", location->tok);
    5126                 : 
    5127               4 :           start_pos = end_pos + 1;
    5128                 :         }
    5129               7 :       component = path.substr(start_pos);
    5130                 :       // Make sure it doesn't end with '/'.
    5131               7 :       if (component.size() == 0)
    5132               1 :         throw semantic_error ("procfs path cannot end with a '/'", location->tok);
    5133                 :       // Make sure it isn't relative.
    5134               6 :       else if (component == "." || component == "..")
    5135               1 :         throw semantic_error ("procfs path cannot be relative (and contain '.' or '..')", location->tok);
    5136                 :     }
    5137                 : 
    5138               9 :   if (!(has_read ^ has_write))
    5139               0 :     throw semantic_error ("need read/write component", location->tok);
    5140                 : 
    5141                 :   finished_results.push_back(new procfs_derived_probe(sess, base, location,
    5142              18 :                                                       path, has_write));
    5143               5 : }
    5144                 : 
    5145                 : 
    5146                 : // ------------------------------------------------------------------------
    5147                 : // statically inserted macro-based derived probes
    5148                 : // ------------------------------------------------------------------------
    5149                 : 
    5150                 : 
    5151                 : struct mark_arg
    5152               0 : {
    5153                 :   bool str;
    5154                 :   string c_type;
    5155                 :   exp_type stp_type;
    5156                 : };
    5157                 : 
    5158                 : struct mark_derived_probe: public derived_probe
    5159               0 : {
    5160                 :   mark_derived_probe (systemtap_session &s,
    5161                 :                       const string& probe_name, const string& probe_format,
    5162                 :                       probe* base_probe, probe_point* location);
    5163                 : 
    5164                 :   systemtap_session& sess;
    5165                 :   string probe_name, probe_format;
    5166                 :   vector <struct mark_arg *> mark_args;
    5167                 :   bool target_symbol_seen;
    5168                 : 
    5169                 :   void join_group (systemtap_session& s);
    5170                 :   void emit_probe_context_vars (translator_output* o);
    5171                 :   void initialize_probe_context_vars (translator_output* o);
    5172                 : 
    5173                 :   void parse_probe_format ();
    5174                 : };
    5175                 : 
    5176                 : 
    5177                 : struct mark_derived_probe_group: public generic_dpg<mark_derived_probe>
    5178               0 : {
    5179                 : public:
    5180                 :   void emit_module_decls (systemtap_session& s);
    5181                 :   void emit_module_init (systemtap_session& s);
    5182                 :   void emit_module_exit (systemtap_session& s);
    5183                 : };
    5184                 : 
    5185                 : 
    5186                 : struct mark_var_expanding_copy_visitor: public var_expanding_copy_visitor
    5187               0 : {
    5188                 :   mark_var_expanding_copy_visitor(systemtap_session& s,
    5189                 :                                   const string& pn,
    5190               0 :                                   vector <struct mark_arg *> &mark_args):
    5191                 :     sess (s), probe_name (pn), mark_args (mark_args),
    5192               0 :     target_symbol_seen (false) {}
    5193                 :   systemtap_session& sess;
    5194                 :   string probe_name;
    5195                 :   vector <struct mark_arg *> &mark_args;
    5196                 :   bool target_symbol_seen;
    5197                 : 
    5198                 :   void visit_target_symbol (target_symbol* e);
    5199                 :   void visit_target_symbol_arg (target_symbol* e);
    5200                 :   void visit_target_symbol_format (target_symbol* e);
    5201                 : };
    5202                 : 
    5203                 : 
    5204                 : void
    5205               0 : hex_dump(unsigned char *data, size_t len)
    5206                 : {
    5207                 :   // Dump data
    5208               0 :   size_t idx = 0;
    5209               0 :   while (idx < len)
    5210                 :     {
    5211               0 :       string char_rep;
    5212                 : 
    5213               0 :       clog << "  0x" << setfill('0') << setw(8) << hex << internal << idx;
    5214                 : 
    5215               0 :       for (int i = 0; i < 4; i++)
    5216                 :         {
    5217               0 :           clog << " ";
    5218               0 :           size_t limit = idx + 4;
    5219               0 :           while (idx < len && idx < limit)
    5220                 :             {
    5221                 :               clog << setfill('0') << setw(2)
    5222               0 :                    << ((unsigned) *((unsigned char *)data + idx));
    5223               0 :               if (isprint(*((char *)data + idx)))
    5224               0 :                 char_rep += *((char *)data + idx);
    5225                 :               else
    5226               0 :                 char_rep += '.';
    5227               0 :               idx++;
    5228                 :             }
    5229               0 :           while (idx < limit)
    5230                 :             {
    5231               0 :               clog << "  ";
    5232               0 :               idx++;
    5233                 :             }
    5234                 :         }
    5235               0 :       clog << " " << char_rep << dec << setfill(' ') << endl;
    5236                 :     }
    5237               0 : }
    5238                 : 
    5239                 : 
    5240                 : void
    5241               0 : mark_var_expanding_copy_visitor::visit_target_symbol_arg (target_symbol* e)
    5242                 : {
    5243               0 :   string argnum_s = e->base_name.substr(4,e->base_name.length()-4);
    5244               0 :   int argnum = atoi (argnum_s.c_str());
    5245                 : 
    5246               0 :   if (argnum < 1 || argnum > (int)mark_args.size())
    5247               0 :     throw semantic_error ("invalid marker argument number", e->tok);
    5248                 : 
    5249               0 :   if (is_active_lvalue (e))
    5250               0 :     throw semantic_error("write to marker parameter not permitted", e->tok);
    5251                 : 
    5252               0 :   if (e->components.size() > 0)
    5253                 :     {
    5254               0 :       switch (e->components[0].first)
    5255                 :         {
    5256                 :         case target_symbol::comp_literal_array_index:
    5257                 :           throw semantic_error("marker argument may not be used as array",
    5258               0 :                                e->tok);
    5259                 :           break;
    5260                 :         case target_symbol::comp_struct_member:
    5261                 :           throw semantic_error("marker argument may not be used as a structure",
    5262               0 :                                e->tok);
    5263                 :           break;
    5264                 :         default:
    5265               0 :           throw semantic_error ("invalid marker argument use", e->tok);
    5266                 :           break;
    5267                 :         }
    5268                 :     }
    5269                 : 
    5270                 :   // Remember that we've seen a target variable.
    5271               0 :   target_symbol_seen = true;
    5272                 : 
    5273                 :   // Synthesize a function.
    5274               0 :   functiondecl *fdecl = new functiondecl;
    5275               0 :   fdecl->tok = e->tok;
    5276               0 :   embeddedcode *ec = new embeddedcode;
    5277               0 :   ec->tok = e->tok;
    5278                 : 
    5279                 :   string fname = string("_mark_tvar_get")
    5280                 :     + "_" + e->base_name.substr(1)
    5281               0 :     + "_" + lex_cast<string>(tick++);
    5282                 : 
    5283               0 :   if (mark_args[argnum-1]->stp_type == pe_long)
    5284                 :     ec->code = string("THIS->__retvalue = CONTEXT->locals[0].")
    5285                 :       + probe_name + string(".__mark_arg")
    5286               0 :       + lex_cast<string>(argnum) + string (";");
    5287                 :   else
    5288                 :     ec->code = string("strlcpy (THIS->__retvalue, CONTEXT->locals[0].")
    5289                 :       + probe_name + string(".__mark_arg")
    5290               0 :       + lex_cast<string>(argnum) + string (", MAXSTRINGLEN);");
    5291               0 :   ec->code += "/* pure */";
    5292               0 :   fdecl->name = fname;
    5293               0 :   fdecl->body = ec;
    5294               0 :   fdecl->type = mark_args[argnum-1]->stp_type;
    5295               0 :   sess.functions.push_back(fdecl);
    5296                 : 
    5297                 :   // Synthesize a functioncall.
    5298               0 :   functioncall* n = new functioncall;
    5299               0 :   n->tok = e->tok;
    5300               0 :   n->function = fname;
    5301               0 :   n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
    5302               0 :   provide <functioncall*> (this, n);
    5303               0 : }
    5304                 : 
    5305                 : 
    5306                 : void
    5307               0 : mark_var_expanding_copy_visitor::visit_target_symbol_format (target_symbol* e)
    5308                 : {
    5309                 :   static bool function_synthesized = false;
    5310                 : 
    5311               0 :   if (is_active_lvalue (e))
    5312               0 :     throw semantic_error("write to marker format not permitted", e->tok);
    5313                 : 
    5314               0 :   if (e->components.size() > 0)
    5315                 :     {
    5316               0 :       switch (e->components[0].first)
    5317                 :         {
    5318                 :         case target_symbol::comp_literal_array_index:
    5319                 :           throw semantic_error("marker format may not be used as array",
    5320               0 :                                e->tok);
    5321                 :           break;
    5322                 :         case target_symbol::comp_struct_member:
    5323                 :           throw semantic_error("marker format may not be used as a structure",
    5324               0 :                                e->tok);
    5325                 :           break;
    5326                 :         default:
    5327               0 :           throw semantic_error ("invalid marker format use", e->tok);
    5328                 :           break;
    5329                 :         }
    5330                 :     }
    5331                 : 
    5332               0 :   string fname = string("_mark_format_get");
    5333                 : 
    5334                 :   // Synthesize a function (if not already synthesized).
    5335               0 :   if (! function_synthesized)
    5336                 :     {
    5337               0 :       function_synthesized = true;
    5338               0 :       functiondecl *fdecl = new functiondecl;
    5339               0 :       fdecl->tok = e->tok;
    5340               0 :       embeddedcode *ec = new embeddedcode;
    5341               0 :       ec->tok = e->tok;
    5342                 : 
    5343               0 :       ec->code = string("strlcpy (THIS->__retvalue, CONTEXT->data, MAXSTRINGLEN); /* pure */");
    5344               0 :       fdecl->name = fname;
    5345               0 :       fdecl->body = ec;
    5346               0 :       fdecl->type = pe_string;
    5347               0 :       sess.functions.push_back(fdecl);
    5348                 :     }
    5349                 : 
    5350                 :   // Synthesize a functioncall.
    5351               0 :   functioncall* n = new functioncall;
    5352               0 :   n->tok = e->tok;
    5353               0 :   n->function = fname;
    5354               0 :   n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
    5355               0 :   provide <functioncall*> (this, n);
    5356               0 : }
    5357                 : 
    5358                 : void
    5359               0 : mark_var_expanding_copy_visitor::visit_target_symbol (target_symbol* e)
    5360                 : {
    5361               0 :   assert(e->base_name.size() > 0 && e->base_name[0] == '$');
    5362                 : 
    5363               0 :   if (e->base_name.substr(0,4) == "$arg")
    5364               0 :     visit_target_symbol_arg (e);
    5365               0 :   else if (e->base_name == "$format")
    5366               0 :     visit_target_symbol_format (e);
    5367                 :   else
    5368                 :     throw semantic_error ("invalid target symbol for marker, $argN or $format expected",
    5369               0 :                           e->tok);
    5370               0 : }
    5371                 : 
    5372                 : 
    5373                 : 
    5374                 : mark_derived_probe::mark_derived_probe (systemtap_session &s,
    5375                 :                                         const string& p_n,
    5376                 :                                         const string& p_f,
    5377               0 :                                         probe* base, probe_point* loc):
    5378                 :   derived_probe (base, new probe_point(*loc) /* .components soon rewritten */),
    5379                 :   sess (s), probe_name (p_n), probe_format (p_f),
    5380               0 :   target_symbol_seen (false)
    5381                 : {
    5382                 :   // create synthetic probe point name; preserve condition
    5383               0 :   vector<probe_point::component*> comps;
    5384               0 :   comps.push_back (new probe_point::component ("kernel"));
    5385               0 :   comps.push_back (new probe_point::component ("mark", new literal_string (probe_name)));
    5386               0 :   comps.push_back (new probe_point::component ("format", new literal_string (probe_format)));
    5387               0 :   this->sole_location()->components = comps;
    5388                 : 
    5389                 :   // expand the marker format
    5390               0 :   parse_probe_format();
    5391                 : 
    5392                 :   // Now make a local-variable-expanded copy of the probe body
    5393               0 :   mark_var_expanding_copy_visitor v (sess, name, mark_args);
    5394               0 :   require <block*> (&v, &(this->body), base->body);
    5395               0 :   target_symbol_seen = v.target_symbol_seen;
    5396                 : 
    5397               0 :   if (sess.verbose > 2)
    5398                 :     clog << "marker-based " << name << " mark=" << probe_name
    5399               0 :          << " fmt='" << probe_format << "'" << endl;
    5400               0 : }
    5401                 : 
    5402                 : 
    5403                 : static int
    5404               0 : skip_atoi(const char **s)
    5405                 : {
    5406               0 :   int i = 0;
    5407               0 :   while (isdigit(**s))
    5408               0 :     i = i * 10 + *((*s)++) - '0';
    5409               0 :   return i;
    5410                 : }
    5411                 : 
    5412                 : 
    5413                 : void
    5414               0 : mark_derived_probe::parse_probe_format()
    5415                 : {
    5416               0 :   const char *fmt = probe_format.c_str();
    5417                 :   int qualifier;                // 'h', 'l', or 'L' for integer fields
    5418                 :   mark_arg *arg;
    5419                 : 
    5420               0 :   for (; *fmt ; ++fmt)
    5421                 :     {
    5422               0 :       if (*fmt != '%')
    5423                 :         {
    5424                 :           /* Skip text */
    5425               0 :           continue;
    5426                 :         }
    5427                 : 
    5428               0 : repeat:
    5429               0 :       ++fmt;
    5430                 : 
    5431                 :       // skip conversion flags (if present)
    5432               0 :       switch (*fmt)
    5433                 :         {
    5434                 :         case '-':
    5435                 :         case '+':
    5436                 :         case ' ':
    5437                 :         case '#':
    5438                 :         case '0':
    5439               0 :           goto repeat;
    5440                 :         }
    5441                 : 
    5442                 :       // skip minimum field witdh (if present)
    5443               0 :       if (isdigit(*fmt))
    5444               0 :         skip_atoi(&fmt);
    5445                 : 
    5446                 :       // skip precision (if present)
    5447               0 :       if (*fmt == '.')
    5448                 :         {
    5449               0 :           ++fmt;
    5450               0 :           if (isdigit(*fmt))
    5451               0 :             skip_atoi(&fmt);
    5452                 :         }
    5453                 : 
    5454                 :       // get the conversion qualifier (if present)
    5455               0 :       qualifier = -1;
    5456               0 :       if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L')
    5457                 :         {
    5458               0 :           qualifier = *fmt;
    5459               0 :           ++fmt;
    5460               0 :           if (qualifier == 'l' && *fmt == 'l')
    5461                 :             {
    5462               0 :               qualifier = 'L';
    5463               0 :               ++fmt;
    5464                 :             }
    5465                 :         }
    5466                 : 
    5467                 :       // get the conversion type
    5468               0 :       switch (*fmt)
    5469                 :         {
    5470                 :         case 'c':
    5471               0 :           arg = new mark_arg;
    5472               0 :           arg->str = false;
    5473               0 :           arg->c_type = "int";
    5474               0 :           arg->stp_type = pe_long;
    5475               0 :           mark_args.push_back(arg);
    5476               0 :           continue;
    5477                 : 
    5478                 :         case 's':
    5479               0 :           arg = new mark_arg;
    5480               0 :           arg->str = true;
    5481               0 :           arg->c_type = "char *";
    5482               0 :           arg->stp_type = pe_string;
    5483               0 :           mark_args.push_back(arg);
    5484               0 :           continue;
    5485                 : 
    5486                 :         case 'p':
    5487               0 :           arg = new mark_arg;
    5488               0 :           arg->str = false;
    5489                 :           // This should really be 'void *'.  But, then we'll get a
    5490                 :           // compile error when we assign the void pointer to an
    5491                 :           // integer without a cast.  So, we use 'long' instead, since
    5492                 :           // it should have the same size as 'void *'.
    5493               0 :           arg->c_type = "long";
    5494               0 :           arg->stp_type = pe_long;
    5495               0 :           mark_args.push_back(arg);
    5496               0 :           continue;
    5497                 : 
    5498                 :         case '%':
    5499               0 :           continue;
    5500                 : 
    5501                 :         case 'o':
    5502                 :         case 'X':
    5503                 :         case 'x':
    5504                 :         case 'd':
    5505                 :         case 'i':
    5506                 :         case 'u':
    5507                 :           // fall through...
    5508                 :           break;
    5509                 : 
    5510                 :         default:
    5511               0 :           if (!*fmt)
    5512               0 :             --fmt;
    5513               0 :           continue;
    5514                 :         }
    5515                 : 
    5516               0 :       arg = new mark_arg;
    5517               0 :       arg->str = false;
    5518               0 :       arg->stp_type = pe_long;
    5519               0 :       switch (qualifier)
    5520                 :         {
    5521                 :         case 'L':
    5522               0 :           arg->c_type = "long long";
    5523               0 :           break;
    5524                 : 
    5525                 :         case 'l':
    5526               0 :           arg->c_type = "long";
    5527               0 :           break;
    5528                 : 
    5529                 :         case 'h':
    5530               0 :           arg->c_type = "short";
    5531               0 :           break;
    5532                 : 
    5533                 :         default:
    5534               0 :           arg->c_type = "int";
    5535                 :           break;
    5536                 :         }
    5537               0 :       mark_args.push_back(arg);
    5538                 :     }
    5539               0 : }
    5540                 : 
    5541                 : 
    5542                 : void
    5543               0 : mark_derived_probe::join_group (systemtap_session& s)
    5544                 : {
    5545               0 :   if (! s.mark_derived_probes)
    5546               0 :     s.mark_derived_probes = new mark_derived_probe_group ();
    5547               0 :   s.mark_derived_probes->enroll (this);
    5548               0 : }
    5549                 : 
    5550                 : 
    5551                 : void
    5552               0 : mark_derived_probe::emit_probe_context_vars (translator_output* o)
    5553                 : {
    5554                 :   // If we haven't seen a target symbol for this probe, quit.
    5555               0 :   if (! target_symbol_seen)
    5556               0 :     return;
    5557                 : 
    5558               0 :   for (unsigned i = 0; i < mark_args.size(); i++)
    5559                 :     {
    5560               0 :       string localname = "__mark_arg" + lex_cast<string>(i+1);
    5561               0 :       switch (mark_args[i]->stp_type)
    5562                 :         {
    5563                 :         case pe_long:
    5564               0 :           o->newline() << "int64_t " << localname << ";";
    5565               0 :           break;
    5566                 :         case pe_string:
    5567               0 :           o->newline() << "string_t " << localname << ";";
    5568               0 :           break;
    5569                 :         default:
    5570               0 :           throw semantic_error ("cannot expand unknown type");
    5571                 :           break;
    5572                 :         }
    5573                 :     }
    5574                 : }
    5575                 : 
    5576                 : 
    5577                 : void
    5578               0 : mark_derived_probe::initialize_probe_context_vars (translator_output* o)
    5579                 : {
    5580                 :   // If we haven't seen a target symbol for this probe, quit.
    5581               0 :   if (! target_symbol_seen)
    5582               0 :     return;
    5583                 : 
    5584               0 :   bool deref_fault_needed = false;
    5585               0 :   for (unsigned i = 0; i < mark_args.size(); i++)
    5586                 :     {
    5587               0 :       string localname = "l->__mark_arg" + lex_cast<string>(i+1);
    5588               0 :       switch (mark_args[i]->stp_type)
    5589                 :         {
    5590                 :         case pe_long:
    5591                 :           o->newline() << localname << " = va_arg(*c->mark_va_list, "
    5592               0 :                        << mark_args[i]->c_type << ");";
    5593               0 :           break;
    5594                 : 
    5595                 :         case pe_string:
    5596                 :           // We're assuming that this is a kernel string (this code is
    5597                 :           // basically the guts of kernel_string), not a user string.
    5598                 :           o->newline() << "{ " << mark_args[i]->c_type
    5599                 :                        << " tmp_str = va_arg(*c->mark_va_list, "
    5600               0 :                        << mark_args[i]->c_type << ");";
    5601                 :           o->newline() << "deref_string (" << localname
    5602               0 :                        << ", tmp_str, MAXSTRINGLEN); }";
    5603               0 :           deref_fault_needed = true;
    5604               0 :           break;
    5605                 : 
    5606                 :         default:
    5607               0 :           throw semantic_error ("cannot expand unknown type");
    5608                 :           break;
    5609                 :         }
    5610                 :     }
    5611               0 :   if (deref_fault_needed)
    5612                 :     // Need to report errors?
    5613               0 :     o->newline() << "deref_fault: ;";
    5614                 : }
    5615                 : 
    5616                 : 
    5617                 : void
    5618               0 : mark_derived_probe_group::emit_module_decls (systemtap_session& s)
    5619                 : {
    5620               0 :   if (probes.empty())
    5621               0 :     return;
    5622                 : 
    5623               0 :   s.op->newline() << "/* ---- marker probes ---- */";
    5624                 : 
    5625                 :   // Warn of misconfigured kernels
    5626               0 :   s.op->newline() << "#if ! defined(CONFIG_MARKERS)";
    5627               0 :   s.op->newline() << "#error \"Need CONFIG_MARKERS!\"";
    5628               0 :   s.op->newline() << "#endif";
    5629               0 :   s.op->newline();
    5630                 : 
    5631               0 :   s.op->newline() << "struct stap_marker_probe {";
    5632               0 :   s.op->newline(1) << "const char * const name;";
    5633               0 :   s.op->newline() << "const char * const format;";
    5634               0 :   s.op->newline() << "const char * const pp;";
    5635               0 :   s.op->newline() << "void (* const ph) (struct context *);";
    5636                 : 
    5637               0 :   s.op->newline(-1) << "} stap_marker_probes [" << probes.size() << "] = {";
    5638               0 :   s.op->indent(1);
    5639               0 :   for (unsigned i=0; i < probes.size(); i++)
    5640                 :     {
    5641               0 :       s.op->newline () << "{";
    5642                 :       s.op->line() << " .name=" << lex_cast_qstring(probes[i]->probe_name)
    5643               0 :                    << ",";
    5644                 :       s.op->line() << " .format=" << lex_cast_qstring(probes[i]->probe_format)
    5645               0 :                    << ",";
    5646                 :       s.op->line() << " .pp=" << lex_cast_qstring (*probes[i]->sole_location())
    5647               0 :                    << ",";
    5648               0 :       s.op->line() << " .ph=&" << probes[i]->name;
    5649               0 :       s.op->line() << " },";
    5650                 :     }
    5651               0 :   s.op->newline(-1) << "};";
    5652               0 :   s.op->newline();
    5653                 : 
    5654                 : 
    5655                 :   // Emit the marker callback function
    5656               0 :   s.op->newline();
    5657               0 :   s.op->newline() << "static void enter_marker_probe (void *probe_data, void *call_data, const char *fmt, va_list *args) {";
    5658               0 :   s.op->newline(1) << "struct stap_marker_probe *smp = (struct stap_marker_probe *)probe_data;";
    5659               0 :   common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
    5660               0 :   s.op->newline() << "c->probe_point = smp->pp;";
    5661               0 :   s.op->newline() << "c->data = (char *)smp->format;";
    5662                 : 
    5663               0 :   s.op->newline() << "c->mark_va_list = args;";
    5664               0 :   s.op->newline() << "(*smp->ph) (c);";
    5665               0 :   s.op->newline() << "c->mark_va_list = NULL;";
    5666               0 :   s.op->newline() << "c->data = NULL;";
    5667                 : 
    5668               0 :   common_probe_entryfn_epilogue (s.op);
    5669               0 :   s.op->newline(-1) << "}";
    5670                 : 
    5671               0 :   return;
    5672                 : }
    5673                 : 
    5674                 : 
    5675                 : void
    5676               0 : mark_derived_probe_group::emit_module_init (systemtap_session &s)
    5677                 : {
    5678               0 :   if (probes.size () == 0)
    5679               0 :     return;
    5680                 : 
    5681               0 :   s.op->newline() << "/* init marker probes */";
    5682               0 :   s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
    5683               0 :   s.op->newline(1) << "struct stap_marker_probe *smp = &stap_marker_probes[i];";
    5684               0 :   s.op->newline() << "probe_point = smp->pp;";
    5685               0 :   s.op->newline() << "rc = marker_probe_register(smp->name, smp->format, enter_marker_probe, smp);";
    5686               0 :   s.op->newline() << "if (rc) {";
    5687               0 :   s.op->newline(1) << "for (j=i-1; j>=0; j--) {"; // partial rollback
    5688               0 :   s.op->newline(1) << "struct stap_marker_probe *smp2 = &stap_marker_probes[j];";
    5689               0 :   s.op->newline() << "marker_probe_unregister(smp2->name, enter_marker_probe, smp2);";
    5690               0 :   s.op->newline(-1) << "}";
    5691               0 :   s.op->newline() << "break;"; // don't attempt to register any more probes
    5692               0 :   s.op->newline(-1) << "}";
    5693               0 :   s.op->newline(-1) << "}"; // for loop
    5694                 : }
    5695                 : 
    5696                 : 
    5697                 : void
    5698               0 : mark_derived_probe_group::emit_module_exit (systemtap_session& s)
    5699                 : {
    5700               0 :   if (probes.empty())
    5701               0 :     return;
    5702                 : 
    5703               0 :   s.op->newline() << "/* deregister marker probes */";
    5704               0 :   s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
    5705               0 :   s.op->newline(1) << "struct stap_marker_probe *smp = &stap_marker_probes[i];";
    5706               0 :   s.op->newline() << "marker_probe_unregister(smp->name, enter_marker_probe, smp);";
    5707               0 :   s.op->newline(-1) << "}"; // for loop
    5708                 : }
    5709                 : 
    5710                 : 
    5711                 : struct mark_builder: public derived_probe_builder
    5712               0 : {
    5713                 : private:
    5714                 :   bool cache_initialized;
    5715                 :   typedef multimap<string, string> mark_cache_t;
    5716                 :   typedef multimap<string, string>::const_iterator mark_cache_const_iterator_t;
    5717                 :   typedef pair<mark_cache_const_iterator_t, mark_cache_const_iterator_t>
    5718                 :     mark_cache_const_iterator_pair_t;
    5719                 :   mark_cache_t mark_cache;
    5720                 : 
    5721                 : public:
    5722             970 :   mark_builder(): cache_initialized(false) {}
    5723                 : 
    5724             968 :   void build_no_more (systemtap_session &s)
    5725                 :   {
    5726             968 :     if (! mark_cache.empty())
    5727                 :       {
    5728               0 :         if (s.verbose > 3)
    5729               0 :           clog << "mark_builder releasing cache" << endl;
    5730               0 :         mark_cache.clear();
    5731                 :       }
    5732             968 :   }
    5733                 : 
    5734                 :   void build(systemtap_session & sess,
    5735                 :              probe * base,
    5736                 :              probe_point * location,
    5737                 :              std::map<std::string, literal *> const & parameters,
    5738                 :              vector<derived_probe *> & finished_results);
    5739                 : };
    5740                 : 
    5741                 : 
    5742                 : void
    5743                 : mark_builder::build(systemtap_session & sess,
    5744                 :                     probe * base,
    5745                 :                     probe_point *loc,
    5746                 :                     std::map<std::string, literal *> const & parameters,
    5747               1 :                     vector<derived_probe *> & finished_results)
    5748                 : {
    5749               1 :   string mark_str_val;
    5750               1 :   bool has_mark_str = get_param (parameters, "mark", mark_str_val);
    5751               1 :   string mark_format_val;
    5752               1 :   bool has_mark_format = get_param (parameters, "format", mark_format_val);
    5753               1 :   assert (has_mark_str);
    5754                 : 
    5755               1 :   if (! cache_initialized)
    5756                 :     {
    5757               1 :       cache_initialized = true;
    5758                 :       string module_markers_path = "/lib/modules/" + sess.kernel_release
    5759               1 :           + "/build/Module.markers";
    5760                 : 
    5761               1 :       ifstream module_markers;
    5762               1 :       module_markers.open(module_markers_path.c_str(), ifstream::in);
    5763               1 :       if (! module_markers)
    5764                 :         {
    5765               1 :           if (sess.verbose>3)
    5766                 :             clog << module_markers_path << " cannot be opened: "
    5767               0 :                  << strerror(errno) << endl;
    5768               1 :           return;
    5769                 :         }
    5770                 : 
    5771               0 :       string name, module, format;
    5772               0 :       do
    5773                 :         {
    5774               0 :           module_markers >> name >> module;
    5775               0 :           getline(module_markers, format);
    5776                 : 
    5777                 :           // trim leading whitespace
    5778               0 :           string::size_type notwhite = format.find_first_not_of(" \t");
    5779               0 :           format.erase(0, notwhite);
    5780                 : 
    5781               0 :           if (sess.verbose>3)
    5782                 :             clog << "'" << name << "' '" << module << "' '" << format
    5783               0 :                  << "'" << endl;
    5784                 : 
    5785               0 :           if (mark_cache.count(name) > 0)
    5786                 :             {
    5787                 :               // If we have 2 markers with the same we've got 2 cases:
    5788                 :               // different format strings or duplicate format strings.
    5789                 :               // If an existing marker in the cache doesn't have the
    5790                 :               // same format string, add this marker.
    5791               0 :               mark_cache_const_iterator_pair_t ret;
    5792               0 :               mark_cache_const_iterator_t it;
    5793               0 :               bool matching_format_string = false;
    5794                 :                   
    5795               0 :               ret = mark_cache.equal_range(name);
    5796               0 :               for (it = ret.first; it != ret.second; ++it)
    5797                 :                 {
    5798               0 :                   if (format == it->second)
    5799                 :                     {
    5800               0 :                       matching_format_string = true;
    5801               0 :                       break;
    5802                 :                     }
    5803                 :                 }
    5804                 : 
    5805               0 :               if (! matching_format_string)
    5806               0 :                 mark_cache.insert(pair<string,string>(name, format));
    5807                 :           }
    5808                 :           else
    5809               0 :             mark_cache.insert(pair<string,string>(name, format));
    5810                 :         }
    5811                 :       while (! module_markers.eof());
    5812               0 :       module_markers.close();
    5813                 :     }
    5814                 : 
    5815                 :   // Search marker list for matching markers
    5816               0 :   for (mark_cache_const_iterator_t it = mark_cache.begin();
    5817                 :        it != mark_cache.end(); it++)
    5818                 :     {
    5819                 :       // Below, "rc" has negative polarity: zero iff matching.
    5820               0 :       int rc = fnmatch(mark_str_val.c_str(), it->first.c_str(), 0);
    5821               0 :       if (! rc)
    5822                 :         {
    5823               0 :           bool add_result = true;
    5824                 : 
    5825                 :           // Match format strings (if the user specified one)
    5826               0 :           if (has_mark_format && fnmatch(mark_format_val.c_str(),
    5827                 :                                          it->second.c_str(), 0))
    5828               0 :             add_result = false;
    5829                 : 
    5830               0 :           if (add_result)
    5831                 :             {
    5832                 :               derived_probe *dp
    5833                 :                 = new mark_derived_probe (sess,
    5834                 :                                           it->first, it->second,
    5835               0 :                                           base, loc);
    5836               0 :               finished_results.push_back (dp);
    5837                 :             }
    5838                 :         }
    5839               0 :     }
    5840                 : }
    5841                 : 
    5842                 : 
    5843                 : // ------------------------------------------------------------------------
    5844                 : // hrtimer derived probes
    5845                 : // ------------------------------------------------------------------------
    5846                 : // This is a new timer interface that provides more flexibility in specifying
    5847                 : // intervals, and uses the hrtimer APIs when available for greater precision.
    5848                 : // While hrtimers were added in 2.6.16, the API's weren't exported until
    5849                 : // 2.6.17, so we must check this kernel version before attempting to use
    5850                 : // hrtimers.
    5851                 : //
    5852                 : // * hrtimer_derived_probe: creates a probe point based on the hrtimer APIs.
    5853                 : 
    5854                 : 
    5855                 : struct hrtimer_derived_probe: public derived_probe
    5856               0 : {
    5857                 :   // set a (generous) maximum of one day in ns
    5858                 :   static const int64_t max_ns_interval = 1000000000LL * 60LL * 60LL * 24LL;
    5859                 : 
    5860                 :   // 100us seems like a reasonable minimum
    5861                 :   static const int64_t min_ns_interval = 100000LL;
    5862                 : 
    5863                 :   int64_t interval, randomize;
    5864                 : 
    5865              71 :   hrtimer_derived_probe (probe* p, probe_point* l, int64_t i, int64_t r):
    5866              71 :     derived_probe (p, l), interval (i), randomize (r)
    5867                 :   {
    5868              71 :     if ((i < min_ns_interval) || (i > max_ns_interval))
    5869               0 :       throw semantic_error("interval value out of range");
    5870                 : 
    5871                 :     // randomize = 0 means no randomization
    5872              71 :     if ((r < 0) || (r > i))
    5873               0 :       throw semantic_error("randomization value out of range");
    5874              71 :   }
    5875                 : 
    5876                 :   void join_group (systemtap_session& s);
    5877                 : };
    5878                 : 
    5879                 : 
    5880                 : struct hrtimer_derived_probe_group: public generic_dpg<hrtimer_derived_probe>
    5881              25 : {
    5882                 :   void emit_interval (translator_output* o);
    5883                 : public:
    5884                 :   void emit_module_decls (systemtap_session& s);
    5885                 :   void emit_module_init (systemtap_session& s);
    5886                 :   void emit_module_exit (systemtap_session& s);
    5887                 : };
    5888                 : 
    5889                 : 
    5890                 : void
    5891              71 : hrtimer_derived_probe::join_group (systemtap_session& s)
    5892                 : {
    5893              71 :   if (! s.hrtimer_derived_probes)
    5894              25 :     s.hrtimer_derived_probes = new hrtimer_derived_probe_group ();
    5895              71 :   s.hrtimer_derived_probes->enroll (this);
    5896              71 : }
    5897                 : 
    5898                 : 
    5899                 : void
    5900              48 : hrtimer_derived_probe_group::emit_interval (translator_output* o)
    5901                 : {
    5902              48 :   o->line() << "({";
    5903              48 :   o->newline(1) << "unsigned long nsecs;";
    5904              48 :   o->newline() << "int64_t i = stp->intrv;";
    5905              48 :   o->newline() << "if (stp->rnd != 0) {";
    5906                 :   // XXX: why not use stp_random_pm instead of this?
    5907              48 :   o->newline(1) << "int64_t r;";
    5908              48 :   o->newline() << "get_random_bytes(&r, sizeof(r));";
    5909                 :   // ensure that r is positive
    5910              48 :   o->newline() << "r &= ((uint64_t)1 << (8*sizeof(r) - 1)) - 1;";
    5911              48 :   o->newline() << "r = _stp_mod64(NULL, r, (2*stp->rnd+1));";
    5912              48 :   o->newline() << "r -= stp->rnd;";
    5913              48 :   o->newline() << "i += r;";
    5914              48 :   o->newline(-1) << "}";
    5915              48 :   o->newline() << "if (unlikely(i < stap_hrtimer_resolution))";
    5916              48 :   o->newline(1) << "i = stap_hrtimer_resolution;";
    5917              48 :   o->indent(-1);
    5918              48 :   o->newline() << "nsecs = do_div(i, NSEC_PER_SEC);";
    5919              48 :   o->newline() << "ktime_set(i, nsecs);";
    5920              48 :   o->newline(-1) << "})";
    5921              48 : }
    5922                 : 
    5923                 : 
    5924                 : void
    5925              24 : hrtimer_derived_probe_group::emit_module_decls (systemtap_session& s)
    5926                 : {
    5927              24 :   if (probes.empty()) return;
    5928                 : 
    5929              24 :   s.op->newline() << "/* ---- hrtimer probes ---- */";
    5930                 : 
    5931              24 :   s.op->newline() << "unsigned long stap_hrtimer_resolution;"; // init later
    5932              24 :   s.op->newline() << "struct stap_hrtimer_probe {";
    5933              24 :   s.op->newline(1) << "struct hrtimer hrtimer;";
    5934              24 :   s.op->newline() << "const char *pp;";
    5935              24 :   s.op->newline() << "void (*ph) (struct context*);";
    5936              24 :   s.op->newline() << "int64_t intrv, rnd;";
    5937              24 :   s.op->newline(-1) << "} stap_hrtimer_probes [" << probes.size() << "] = {";
    5938              24 :   s.op->indent(1);
    5939             188 :   for (unsigned i=0; i < probes.size(); i++)
    5940                 :     {
    5941              70 :       s.op->newline () << "{";
    5942              70 :       s.op->line() << " .pp=" << lex_cast_qstring (*probes[i]->sole_location()) << ",";
    5943              70 :       s.op->line() << " .ph=&" << probes[i]->name << ",";
    5944              70 :       s.op->line() << " .intrv=" << probes[i]->interval << "LL,";
    5945              70 :       s.op->line() << " .rnd=" << probes[i]->randomize << "LL";
    5946              70 :       s.op->line() << " },";
    5947                 :     }
    5948              24 :   s.op->newline(-1) << "};";
    5949              24 :   s.op->newline();
    5950                 : 
    5951                 :   // autoconf: adapt to HRTIMER_REL -> HRTIMER_MODE_REL renaming near 2.6.21
    5952              24 :   s.op->newline() << "#ifdef STAPCONF_HRTIMER_REL";
    5953              24 :   s.op->newline() << "#define HRTIMER_MODE_REL HRTIMER_REL";
    5954              24 :   s.op->newline() << "#endif";
    5955                 : 
    5956                 :   // The function signature changed in 2.6.21.
    5957              24 :   s.op->newline() << "#ifdef STAPCONF_HRTIMER_REL";
    5958              24 :   s.op->newline() << "static int ";
    5959              24 :   s.op->newline() << "#else";
    5960              24 :   s.op->newline() << "static enum hrtimer_restart ";
    5961              24 :   s.op->newline() << "#endif";
    5962              24 :   s.op->newline() << "enter_hrtimer_probe (struct hrtimer *timer) {";
    5963                 : 
    5964              24 :   s.op->newline(1) << "int rc = HRTIMER_NORESTART;";
    5965              24 :   s.op->newline() << "struct stap_hrtimer_probe *stp = container_of(timer, struct stap_hrtimer_probe, hrtimer);";
    5966              24 :   s.op->newline() << "if ((atomic_read (&session_state) == STAP_SESSION_STARTING) ||";
    5967              24 :   s.op->newline() << "    (atomic_read (&session_state) == STAP_SESSION_RUNNING)) {";
    5968                 :   // Compute next trigger time
    5969              24 :   s.op->newline(1) << "timer->expires = ktime_add (timer->expires,";
    5970              24 :   emit_interval (s.op);
    5971              24 :   s.op->line() << ");";
    5972              24 :   s.op->newline() << "rc = HRTIMER_RESTART;";
    5973              24 :   s.op->newline(-1) << "}";
    5974              24 :   s.op->newline() << "{";
    5975              24 :   s.op->indent(1);
    5976              24 :   common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
    5977              24 :   s.op->newline() << "c->probe_point = stp->pp;";
    5978              24 :   s.op->newline() << "(*stp->ph) (c);";
    5979              24 :   common_probe_entryfn_epilogue (s.op);
    5980              24 :   s.op->newline(-1) << "}";
    5981              24 :   s.op->newline() << "return rc;";
    5982              24 :   s.op->newline(-1) << "}";
    5983                 : }
    5984                 : 
    5985                 : 
    5986                 : void
    5987              24 : hrtimer_derived_probe_group::emit_module_init (systemtap_session& s)
    5988                 : {
    5989              24 :   if (probes.empty()) return;
    5990                 : 
    5991              24 :   s.op->newline() << "{";
    5992              24 :   s.op->newline(1) << "struct timespec res;";
    5993              24 :   s.op->newline() << "hrtimer_get_res (CLOCK_MONOTONIC, &res);";
    5994              24 :   s.op->newline() << "stap_hrtimer_resolution = timespec_to_ns (&res);";
    5995              24 :   s.op->newline(-1) << "}";
    5996                 : 
    5997              24 :   s.op->newline() << "for (i=0; i<" << probes.size() << "; i++) {";
    5998              24 :   s.op->newline(1) << "struct stap_hrtimer_probe* stp = & stap_hrtimer_probes [i];";
    5999              24 :   s.op->newline() << "probe_point = stp->pp;";
    6000              24 :   s.op->newline() << "hrtimer_init (& stp->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);";
    6001              24 :   s.op->newline() << "stp->hrtimer.function = & enter_hrtimer_probe;";
    6002                 :   // There is no hrtimer field to identify *this* (i-th) probe handler
    6003                 :   // callback.  So instead we'll deduce it at entry time.
    6004              24 :   s.op->newline() << "(void) hrtimer_start (& stp->hrtimer, ";
    6005              24 :   emit_interval (s.op);
    6006              24 :   s.op->line() << ", HRTIMER_MODE_REL);";
    6007                 :   // Note: no partial failure rollback is needed: hrtimer_start only
    6008                 :   // "fails" if the timer was already active, which cannot be.
    6009              24 :   s.op->newline(-1) << "}"; // for loop
    6010                 : }
    6011                 : 
    6012                 : 
    6013                 : void
    6014              25 : hrtimer_derived_probe_group::emit_module_exit (systemtap_session& s)
    6015                 : {
    6016              25 :   if (probes.empty()) return;
    6017                 : 
    6018              25 :   s.op->newline() << "for (i=0; i<" << probes.size() << "; i++)";
    6019              25 :   s.op->newline(1) << "hrtimer_cancel (& stap_hrtimer_probes[i].hrtimer);";
    6020              25 :   s.op->indent(-1);
    6021                 : }
    6022                 : 
    6023                 : 
    6024                 : 
    6025                 : struct timer_builder: public derived_probe_builder
    6026             485 : {
    6027                 :     virtual void build(systemtap_session & sess,
    6028                 :         probe * base, probe_point * location,
    6029                 :         std::map<std::string, literal *> const & parameters,
    6030                 :         vector<derived_probe *> & finished_results);
    6031                 : 
    6032                 :     static void register_patterns(match_node *root);
    6033                 : };
    6034                 : 
    6035                 : void
    6036                 : timer_builder::build(systemtap_session & sess,
    6037                 :     probe * base,
    6038                 :     probe_point * location,
    6039                 :     std::map<std::string, literal *> const & parameters,
    6040              83 :     vector<derived_probe *> & finished_results)
    6041                 : {
    6042              83 :   int64_t period, rand=0;
    6043                 : 
    6044              83 :   if (!get_param(parameters, "randomize", rand))
    6045              59 :     rand = 0;
    6046                 : 
    6047              83 :   if (get_param(parameters, "jiffies", period))
    6048                 :     {
    6049                 :       // always use basic timers for jiffies
    6050                 :       finished_results.push_back(
    6051              12 :           new timer_derived_probe(base, location, period, rand, false));
    6052              12 :       return;
    6053                 :     }
    6054              71 :   else if (get_param(parameters, "hz", period))
    6055                 :     {
    6056               2 :       if (period <= 0)
    6057               0 :         throw semantic_error ("frequency must be greater than 0");
    6058               2 :       period = (1000000000 + period - 1)/period;
    6059                 :     }
    6060              69 :   else if (get_param(parameters, "s", period)
    6061                 :       || get_param(parameters, "sec", period))
    6062                 :     {
    6063              15 :       period *= 1000000000;
    6064              15 :       rand *= 1000000000;
    6065                 :     }
    6066              54 :   else if (get_param(parameters, "ms", period)
    6067                 :       || get_param(parameters, "msec", period))
    6068                 :     {
    6069              38 :       period *= 1000000;
    6070              38 :       rand *= 1000000;
    6071                 :     }
    6072              16 :   else if (get_param(parameters, "us", period)
    6073                 :       || get_param(parameters, "usec", period))
    6074                 :     {
    6075               8 :       period *= 1000;
    6076               8 :       rand *= 1000;
    6077                 :     }
    6078               8 :   else if (get_param(parameters, "ns", period)
    6079                 :       || get_param(parameters, "nsec", period))
    6080                 :     {
    6081                 :       // ok
    6082                 :     }
    6083                 :   else
    6084               0 :     throw semantic_error ("unrecognized timer variant");
    6085                 : 
    6086                 :   // Redirect wallclock-time based probes to hrtimer code on recent
    6087                 :   // enough kernels.
    6088              71 :   if (strverscmp(sess.kernel_base_release.c_str(), "2.6.17") < 0)
    6089                 :     {
    6090                 :       // hrtimers didn't exist, so use the old-school timers
    6091               0 :       period = (period + 1000000 - 1)/1000000;
    6092               0 :       rand = (rand + 1000000 - 1)/1000000;
    6093                 : 
    6094                 :       finished_results.push_back(
    6095               0 :           new timer_derived_probe(base, location, period, rand, true));
    6096                 :     }
    6097                 :   else
    6098                 :     finished_results.push_back(
    6099              71 :         new hrtimer_derived_probe(base, location, period, rand));
    6100                 : }
    6101                 : 
    6102                 : void
    6103             485 : timer_builder::register_patterns(match_node *root)
    6104                 : {
    6105             485 :   derived_probe_builder *builder = new timer_builder();
    6106                 : 
    6107             485 :   root = root->bind("timer");
    6108                 : 
    6109             970 :   root->bind_num("s")->bind(builder);
    6110             970 :   root->bind_num("s")->bind_num("randomize")->bind(builder);
    6111             970 :   root->bind_num("sec")->bind(builder);
    6112             970 :   root->bind_num("sec")->bind_num("randomize")->bind(builder);
    6113                 : 
    6114             970 :   root->bind_num("ms")->bind(builder);
    6115             970 :   root->bind_num("ms")->bind_num("randomize")->bind(builder);
    6116             970 :   root->bind_num("msec")->bind(builder);
    6117             970 :   root->bind_num("msec")->bind_num("randomize")->bind(builder);
    6118                 : 
    6119             970 :   root->bind_num("us")->bind(builder);
    6120             970 :   root->bind_num("us")->bind_num("randomize")->bind(builder);
    6121             970 :   root->bind_num("usec")->bind(builder);
    6122             970 :   root->bind_num("usec")->bind_num("randomize")->bind(builder);
    6123                 : 
    6124             970 :   root->bind_num("ns")->bind(builder);
    6125             970 :   root->bind_num("ns")->bind_num("randomize")->bind(builder);
    6126             970 :   root->bind_num("nsec")->bind(builder);
    6127             970 :   root->bind_num("nsec")->bind_num("randomize")->bind(builder);
    6128                 : 
    6129             970 :   root->bind_num("jiffies")->bind(builder);
    6130             970 :   root->bind_num("jiffies")->bind_num("randomize")->bind(builder);
    6131                 : 
    6132             970 :   root->bind_num("hz")->bind(builder);
    6133             485 : }
    6134                 : 
    6135                 : 
    6136                 : // ------------------------------------------------------------------------
    6137                 : // perfmon derived probes
    6138                 : // ------------------------------------------------------------------------
    6139                 : // This is a new interface to the perfmon hw.
    6140                 : //
    6141                 : 
    6142                 : 
    6143                 : struct perfmon_var_expanding_copy_visitor: public var_expanding_copy_visitor
    6144               1 : {
    6145                 :   systemtap_session & sess;
    6146                 :   unsigned counter_number;
    6147               1 :   perfmon_var_expanding_copy_visitor(systemtap_session & s, unsigned c):
    6148               1 :           sess(s), counter_number(c) {}
    6149                 :   void visit_target_symbol (target_symbol* e);
    6150                 : };
    6151                 : 
    6152                 : 
    6153                 : void
    6154               1 : perfmon_var_expanding_copy_visitor::visit_target_symbol (target_symbol *e)
    6155                 : {
    6156               1 :   assert(e->base_name.size() > 0 && e->base_name[0] == '$');
    6157                 : 
    6158                 :   // Synthesize a function.
    6159               1 :   functiondecl *fdecl = new functiondecl;
    6160               1 :   fdecl->tok = e->tok;
    6161               2 :   embeddedcode *ec = new embeddedcode;
    6162               1 :   ec->tok = e->tok;
    6163               1 :   bool lvalue = is_active_lvalue(e);
    6164                 : 
    6165               1 :   if (lvalue )
    6166               0 :     throw semantic_error("writes to $counter not permitted");
    6167                 : 
    6168                 :   string fname = string("_perfmon_tvar_get")
    6169                 :                   + "_" + e->base_name.substr(1)
    6170               1 :                   + "_" + lex_cast<string>(counter_number);
    6171                 : 
    6172               2 :   if (e->base_name != "$counter")
    6173               0 :     throw semantic_error ("target variables not available to perfmon probes");
    6174                 : 
    6175               1 :   if (e->components.size() > 0)
    6176                 :     {
    6177               0 :       switch (e->components[0].first)
    6178                 :         {
    6179                 :         case target_symbol::comp_literal_array_index:
    6180                 :           throw semantic_error("perfmon probe '$counter' variable may not be used as array",
    6181               0 :                                e->tok);
    6182                 :           break;
    6183                 :         case target_symbol::comp_struct_member:
    6184                 :           throw semantic_error("perfmon probe '$counter' variable may not be used as a structure",
    6185               0 :                                e->tok);
    6186                 :           break;
    6187                 :         default:
    6188                 :           throw semantic_error ("invalid use of perfmon probe '$counter' variable",
    6189               0 :                                 e->tok);
    6190                 :           break;
    6191                 :         }
    6192                 :     }
    6193                 : 
    6194                 :   ec->code = "THIS->__retvalue = _pfm_pmd_x[" +
    6195               1 :           lex_cast<string>(counter_number) + "].reg_num;";
    6196               1 :   ec->code += "/* pure */";
    6197               1 :   fdecl->name = fname;
    6198               1 :   fdecl->body = ec;
    6199               1 :   fdecl->type = pe_long;
    6200               1 :   sess.functions.push_back(fdecl);
    6201                 : 
    6202                 :   // Synthesize a functioncall.
    6203               1 :   functioncall* n = new functioncall;
    6204               1 :   n->tok = e->tok;
    6205               1 :   n->function = fname;
    6206               1 :   n->referent = 0;  // NB: must not resolve yet, to ensure inclusion in session
    6207                 : 
    6208               1 :   provide <functioncall*> (this, n);
    6209               1 : }
    6210                 : 
    6211                 : 
    6212                 : enum perfmon_mode
    6213                 : {
    6214                 :   perfmon_count,
    6215                 :   perfmon_sample
    6216                 : };
    6217                 : 
    6218                 : 
    6219                 : struct perfmon_derived_probe: public derived_probe
    6220               0 : {
    6221                 : protected:
    6222                 :   static unsigned probes_allocated;
    6223                 : 
    6224                 : public:
    6225                 :   systemtap_session & sess;
    6226                 :   string event;
    6227                 :   perfmon_mode mode;
    6228                 : 
    6229                 :   perfmon_derived_probe (probe* p, probe_point* l, systemtap_session &s,
    6230                 :                          string e, perfmon_mode m);
    6231                 :   virtual void join_group (systemtap_session& s);
    6232                 : };
    6233                 : 
    6234                 : 
    6235                 : struct perfmon_derived_probe_group: public generic_dpg<perfmon_derived_probe>
    6236                 : {
    6237                 : public:
    6238                 :   void emit_module_decls (systemtap_session&) {}
    6239                 :   void emit_module_init (systemtap_session&) {}
    6240                 :   void emit_module_exit (systemtap_session&) {}
    6241                 : };
    6242                 : 
    6243                 : 
    6244                 : struct perfmon_builder: public derived_probe_builder
    6245               0 : {
    6246             485 :   perfmon_builder() {}
    6247                 :   virtual void build(systemtap_session & sess,
    6248                 :                      probe * base,
    6249                 :                      probe_point * location,
    6250                 :                      std::map<std::string, literal *> const & parameters,
    6251               1 :                      vector<derived_probe *> & finished_results)
    6252                 :   {
    6253               1 :     string event;
    6254               1 :     if (!get_param (parameters, "counter", event))
    6255               0 :       throw semantic_error("perfmon requires an event");
    6256                 : 
    6257               1 :     sess.perfmon++;
    6258                 : 
    6259                 :     // XXX: need to revise when doing sampling
    6260                 :     finished_results.push_back(new perfmon_derived_probe(base, location,
    6261                 :                                                          sess, event,
    6262               1 :                                                          perfmon_count));
    6263               1 :   }
    6264                 : };
    6265                 : 
    6266                 : 
    6267                 : unsigned perfmon_derived_probe::probes_allocated;
    6268                 : 
    6269                 : perfmon_derived_probe::perfmon_derived_probe (probe* p, probe_point* l,
    6270                 :                                               systemtap_session &s,
    6271               1 :                                               string e, perfmon_mode m)
    6272               1 :         : derived_probe (p, l), sess(s), event(e), mode(m)
    6273                 : {
    6274               1 :   ++probes_allocated;
    6275                 : 
    6276                 :   // Now make a local-variable-expanded copy of the probe body
    6277               1 :   perfmon_var_expanding_copy_visitor v (sess, probes_allocated-1);
    6278               1 :   require <block*> (&v, &(this->body), base->body);
    6279                 : 
    6280               1 :   if (sess.verbose > 1)
    6281               0 :     clog << "perfmon-based probe" << endl;
    6282               1 : }
    6283                 : 
    6284                 : 
    6285                 : void
    6286               1 : perfmon_derived_probe::join_group (systemtap_session& s)
    6287                 : {
    6288               1 :   throw semantic_error ("incomplete", this->tok);
    6289                 : 
    6290                 :   if (! s.perfmon_derived_probes)
    6291                 :     s.perfmon_derived_probes = new perfmon_derived_probe_group ();
    6292                 :   s.perfmon_derived_probes->enroll (this);
    6293                 : }
    6294                 : 
    6295                 : 
    6296                 : #if 0
    6297                 : void
    6298                 : perfmon_derived_probe::emit_registrations_start (translator_output* o,
    6299                 :                                                  unsigned index)
    6300                 : {
    6301                 :   for (unsigned i=0; i<locations.size(); i++)
    6302                 :     o->newline() << "enter_" << name << "_" << i << " ();";
    6303                 : }
    6304                 : 
    6305                 : 
    6306                 : void
    6307                 : perfmon_derived_probe::emit_registrations_end (translator_output * o,
    6308                 :                                                unsigned index)
    6309                 : {
    6310                 : }
    6311                 : 
    6312                 : 
    6313                 : void
    6314                 : perfmon_derived_probe::emit_deregistrations (translator_output * o)
    6315                 : {
    6316                 : }
    6317                 : 
    6318                 : 
    6319                 : void
    6320                 : perfmon_derived_probe::emit_probe_entries (translator_output * o)
    6321                 : {
    6322                 :   o->newline() << "#ifdef STP_TIMING";
    6323                 :   // NB: This variable may be multiply (but identically) defined.
    6324                 :   o->newline() << "static __cacheline_aligned Stat " << "time_" << basest()->name << ";";
    6325                 :   o->newline() << "#endif";
    6326                 : 
    6327                 :   for (unsigned i=0; i<locations.size(); i++)
    6328                 :     {
    6329                 :       probe_point *l = locations[i];
    6330                 :       o->newline() << "/* location " << i << ": " << *l << " */";
    6331                 :       o->newline() << "static void enter_" << name << "_" << i << " (void) {";
    6332                 : 
    6333                 :       o->indent(1);
    6334                 :       o->newline() << "const char* probe_point = "
    6335                 :                    << lex_cast_qstring(*l) << ";";
    6336                 :       emit_probe_prologue (o,
    6337                 :                            (mode == perfmon_count ?
    6338                 :                             "STAP_SESSION_STARTING" :
    6339                 :                             "STAP_SESSION_RUNNING"));
    6340                 : 
    6341                 :       // NB: locals are initialized by probe function itself
    6342                 :       o->newline() << name << " (c);";
    6343                 : 
    6344                 :       emit_probe_epilogue (o);
    6345                 : 
    6346                 :       o->newline(-1) << "}\n";
    6347                 :     }
    6348                 : }
    6349                 : #endif
    6350                 : 
    6351                 : 
    6352                 : #if 0
    6353                 : void no_pfm_event_error (string s)
    6354                 : {
    6355                 :   string msg(string("Cannot find event:" + s));
    6356                 :   throw semantic_error(msg);
    6357                 : }
    6358                 : 
    6359                 : 
    6360                 : void no_pfm_mask_error (string s)
    6361                 : {
    6362                 :   string msg(string("Cannot find mask:" + s));
    6363                 :   throw semantic_error(msg);
    6364                 : }
    6365                 : 
    6366                 : 
    6367                 : void
    6368                 : split(const string& s, vector<string>& v, const string & separator)
    6369                 : {
    6370                 :   string::size_type last_pos = s.find_first_not_of(separator, 0);
    6371                 :   string::size_type pos = s.find_first_of(separator, last_pos);
    6372                 : 
    6373                 :   while (string::npos != pos || string::npos != last_pos) {
    6374                 :     v.push_back(s.substr(last_pos, pos - last_pos));
    6375                 :     last_pos = s.find_first_not_of(separator, pos);
    6376                 :     pos = s.find_first_of(separator, last_pos);
    6377                 :   }
    6378                 : }
    6379                 : 
    6380                 : 
    6381                 : void
    6382                 : perfmon_derived_probe_group::emit_probes (translator_output* op, unparser* up)
    6383                 : {
    6384                 :   for (unsigned i=0; i < probes.size(); i++)
    6385                 :     {
    6386                 :       op->newline ();
    6387                 :       up->emit_probe (probes[i]);
    6388                 :     }
    6389                 : }
    6390                 : 
    6391                 : 
    6392                 : void
    6393                 : perfmon_derived_probe_group::emit_module_init (translator_output* o)
    6394                 : {
    6395                 :   int ret;
    6396                 :   pfmlib_input_param_t inp;
    6397                 :   pfmlib_output_param_t outp;
    6398                 :   pfarg_pmd_t pd[PFMLIB_MAX_PMDS];
    6399                 :   pfarg_pmc_t pc[PFMLIB_MAX_PMCS];
    6400                 :   pfarg_ctx_t ctx;
    6401                 :   pfarg_load_t load_args;
    6402                 :   pfmlib_options_t pfmlib_options;
    6403                 :   unsigned int max_counters;
    6404                 : 
    6405                 :   if ( probes.size() == 0)
    6406                 :           return;
    6407                 :   ret = pfm_initialize();
    6408                 :   if (ret != PFMLIB_SUCCESS)
    6409                 :     throw semantic_error("Unable to generate performance monitoring events (no libpfm)");
    6410                 : 
    6411                 :   pfm_get_num_counters(&max_counters);
    6412                 : 
    6413                 :   memset(&pfmlib_options, 0, sizeof(pfmlib_options));
    6414                 :   pfmlib_options.pfm_debug   = 0; /* set to 1 for debug */
    6415                 :   pfmlib_options.pfm_verbose = 0; /* set to 1 for debug */
    6416                 :   pfm_set_options(&pfmlib_options);
    6417                 : 
    6418                 :   memset(pd, 0, sizeof(pd));
    6419                 :   memset(pc, 0, sizeof(pc));
    6420                 :   memset(&ctx, 0, sizeof(ctx));
    6421                 :   memset(&load_args, 0, sizeof(load_args));
    6422                 : 
    6423                 :   /*
    6424                 :    * prepare parameters to library.
    6425                 :    */
    6426                 :   memset(&inp,0, sizeof(inp));
    6427                 :   memset(&outp,0, sizeof(outp));
    6428                 : 
    6429                 :   /* figure out the events */
    6430                 :   for (unsigned i=0; i<probes.size(); ++i)
    6431                 :     {
    6432                 :       if (probes[i]->event == "cycles") {
    6433                 :         if (pfm_get_cycle_event( &inp.pfp_events[i].event) != PFMLIB_SUCCESS)
    6434                 :           no_pfm_event_error(probes[i]->event);
    6435                 :       } else if (probes[i]->event == "instructions") {
    6436                 :         if (pfm_get_inst_retired_event( &inp.pfp_events[i].event) !=
    6437                 :             PFMLIB_SUCCESS)
    6438                 :           no_pfm_event_error(probes[i]->event);
    6439                 :       } else {
    6440                 :         unsigned int event_id = 0;
    6441                 :         unsigned int mask_id = 0;
    6442                 :         vector<string> event_spec;
    6443                 :         split(probes[i]->event, event_spec, ":");
    6444                 :         int num =  event_spec.size();
    6445                 :         int masks = num - 1;
    6446                 : 
    6447                 :         if (num == 0)
    6448                 :           throw semantic_error("No events found");
    6449                 : 
    6450                 :         /* setup event */
    6451                 :         if (pfm_find_event(event_spec[0].c_str(), &event_id) != PFMLIB_SUCCESS)
    6452                 :           no_pfm_event_error(event_spec[0]);
    6453                 :         inp.pfp_events[i].event = event_id;
    6454                 : 
    6455                 :         /* set up masks */
    6456                 :         if (masks > PFMLIB_MAX_MASKS_PER_EVENT)
    6457                 :           throw semantic_error("Too many unit masks specified");
    6458                 : 
    6459                 :         for (int j=0; j < masks; j++) {
    6460                 :                 if (pfm_find_event_mask(event_id, event_spec[j+1].c_str(),
    6461                 :                                         &mask_id) != PFMLIB_SUCCESS)
    6462                 :             no_pfm_mask_error(string(event_spec[j+1]));
    6463                 :           inp.pfp_events[i].unit_masks[j] = mask_id;
    6464                 :         }
    6465                 :         inp.pfp_events[i].num_masks = masks;
    6466                 :       }
    6467                 :     }
    6468                 : 
    6469                 :   /* number of counters in use */
    6470                 :   inp.pfp_event_count = probes.size();
    6471                 : 
    6472                 :   // XXX: no elimination of duplicated counters
    6473                 :   if (inp.pfp_event_count>max_counters)
    6474                 :           throw semantic_error("Too many performance monitoring events.");
    6475                 : 
    6476                 :   /* count events both in kernel and user-space */
    6477                 :   inp.pfp_dfl_plm   = PFM_PLM0 | PFM_PLM3;
    6478                 : 
    6479                 :   /* XXX: some cases a perfmon register might be used of watch dog
    6480                 :      this code doesn't handle that case */
    6481                 : 
    6482                 :   /* figure out the pmcs for the events */
    6483                 :   if ((ret=pfm_dispatch_events(&inp, NULL, &outp, NULL)) != PFMLIB_SUCCESS)
    6484                 :           throw semantic_error("Cannot configure events");
    6485                 : 
    6486                 :   for (unsigned i=0; i < outp.pfp_pmc_count; i++) {
    6487                 :     pc[i].reg_num   = outp.pfp_pmcs[i].reg_num;
    6488                 :     pc[i].reg_value = outp.pfp_pmcs[i].reg_value;
    6489                 :   }
    6490                 : 
    6491                 :   /*
    6492                 :    * There could be more pmc settings than pmd.
    6493                 :    * Figure out the actual pmds to use.
    6494                 :    */
    6495                 :   for (unsigned i=0, j=0; i < inp.pfp_event_count; i++) {
    6496                 :     pd[i].reg_num   = outp.pfp_pmcs[j].reg_pmd_num;
    6497                 :     for(; j < outp.pfp_pmc_count; j++)
    6498                 :       if (outp.pfp_pmcs[j].reg_evt_idx != i) break;
    6499                 :   }
    6500                 : 
    6501                 :   // Output the be probes create function
    6502                 :   o->newline() << "static int register_perfmon_probes (void) {";
    6503                 :   o->newline(1) << "int rc = 0;";
    6504                 : 
    6505                 :   o->newline() << "/* data for perfmon */";
    6506                 :   o->newline() << "static int _pfm_num_pmc = " << outp.pfp_pmc_count << ";";
    6507                 :   o->newline() << "static struct pfarg_pmc _pfm_pmc[" << outp.pfp_pmc_count
    6508                 :                << "] = {";
    6509                 :   /* output the needed bits for pmc here */
    6510                 :   for (unsigned i=0; i < outp.pfp_pmc_count; i++) {
    6511                 :     o->newline() << "{.reg_num=" << pc[i].reg_num << ", "
    6512                 :                  << ".reg_value=" << lex_cast_hex<string>(pc[i].reg_value)
    6513                 :                  << "},";
    6514                 :   }
    6515                 : 
    6516                 :   o->newline() << "};";
    6517                 :   o->newline() << "static int _pfm_num_pmd = " << inp.pfp_event_count << ";";
    6518                 :   o->newline() << "static struct pfarg_pmd _pfm_pmd[" << inp.pfp_event_count
    6519                 :                << "] = {";
    6520                 :   /* output the needed bits for pmd here */
    6521                 :   for (unsigned i=0; i < inp.pfp_event_count; i++) {
    6522                 :     o->newline() << "{.reg_num=" << pd[i].reg_num << ", "
    6523                 :                  << ".reg_value=" << pd[i].reg_value << "},";
    6524                 :   }
    6525                 :   o->newline() << "};";
    6526                 :   o->newline();
    6527                 : 
    6528                 :   o->newline() << "_pfm_pmc_x=_pfm_pmc;";
    6529                 :   o->newline() << "_pfm_num_pmc_x=_pfm_num_pmc;";
    6530                 :   o->newline() << "_pfm_pmd_x=_pfm_pmd;";
    6531                 :   o->newline() << "_pfm_num_pmd_x=_pfm_num_pmd;";
    6532                 : 
    6533                 :   // call all the function bodies associated with perfcounters
    6534                 :   for (unsigned i=0; i < probes.size (); i++)
    6535                 :     probes[i]->emit_registrations_start (o,i);
    6536                 : 
    6537                 :   /* generate call to turn on instrumentation */
    6538                 :   o->newline() << "_pfm_context.ctx_flags |= PFM_FL_SYSTEM_WIDE;";
    6539                 :   o->newline() << "rc = rc || _stp_perfmon_setup(&_pfm_desc, &_pfm_context,";
    6540                 :   o->newline(1) << "_pfm_pmc, _pfm_num_pmc,";
    6541                 :   o->newline() << "_pfm_pmd, _pfm_num_pmd);";
    6542                 :   o->newline(-1);
    6543                 : 
    6544                 :   o->newline() << "return rc;";
    6545                 :   o->newline(-1) << "}\n";
    6546                 : 
    6547                 :   // Output the be probes destroy function
    6548                 :   o->newline() << "static void unregister_perfmon_probes (void) {";
    6549                 :   o->newline(1) << "_stp_perfmon_shutdown(_pfm_desc);";
    6550                 :   o->newline(-1) << "}\n";
    6551                 : }
    6552                 : #endif
    6553                 : 
    6554                 : 
    6555                 : // ------------------------------------------------------------------------
    6556                 : //  Standard tapset registry.
    6557                 : // ------------------------------------------------------------------------
    6558                 : 
    6559                 : void
    6560             485 : register_standard_tapsets(systemtap_session & s)
    6561                 : {
    6562             485 :   s.pattern_root->bind("begin")->bind(new be_builder(BEGIN));
    6563             970 :   s.pattern_root->bind_num("begin")->bind(new be_builder(BEGIN));
    6564             970 :   s.pattern_root->bind("end")->bind(new be_builder(END));
    6565             970 :   s.pattern_root->bind_num("end")->bind(new be_builder(END));
    6566             970 :   s.pattern_root->bind("error")->bind(new be_builder(ERROR));
    6567             970 :   s.pattern_root->bind_num("error")->bind(new be_builder(ERROR));
    6568                 : 
    6569             970 :   s.pattern_root->bind("never")->bind(new never_builder());
    6570                 : 
    6571             485 :   timer_builder::register_patterns(s.pattern_root);
    6572             970 :   s.pattern_root->bind("timer")->bind("profile")->bind(new profile_builder());
    6573             970 :   s.pattern_root->bind("perfmon")->bind_str("counter")->bind(new perfmon_builder());
    6574                 : 
    6575                 :   // dwarf-based kernel/module parts
    6576             485 :   dwarf_derived_probe::register_patterns(s.pattern_root);
    6577                 : 
    6578                 :   // XXX: user-space starter set
    6579                 :   s.pattern_root->bind_num(TOK_PROCESS)
    6580                 :     ->bind_num(TOK_STATEMENT)->bind(TOK_ABSOLUTE)
    6581             485 :     ->bind(new uprobe_builder ());
    6582                 :   s.pattern_root->bind_num(TOK_PROCESS)
    6583                 :     ->bind_num(TOK_STATEMENT)->bind(TOK_ABSOLUTE)->bind(TOK_RETURN)
    6584             485 :     ->bind(new uprobe_builder ());
    6585                 : 
    6586                 :   // marker-based parts
    6587             970 :   s.pattern_root->bind("kernel")->bind_str("mark")->bind(new mark_builder());
    6588                 :   s.pattern_root->bind("kernel")->bind_str("mark")->bind_str("format")
    6589             970 :     ->bind(new mark_builder());
    6590                 : 
    6591                 :   // procfs parts
    6592             970 :   s.pattern_root->bind("procfs")->bind("read")->bind(new procfs_builder());
    6593             970 :   s.pattern_root->bind_str("procfs")->bind("read")->bind(new procfs_builder());
    6594             970 :   s.pattern_root->bind("procfs")->bind("write")->bind(new procfs_builder());
    6595             970 :   s.pattern_root->bind_str("procfs")->bind("write")->bind(new procfs_builder());
    6596             485 : }
    6597                 : 
    6598                 : 
    6599                 : vector<derived_probe_group*>
    6600             562 : all_session_groups(systemtap_session& s)
    6601                 : {
    6602             562 :   vector<derived_probe_group*> g;
    6603                 : #define DOONE(x) if (s. x##_derived_probes) g.push_back (s. x##_derived_probes)
    6604                 : 
    6605                 :   // Note that order *is* important here.  We want to make sure we
    6606                 :   // register (actually run) begin probes before any other probe type
    6607                 :   // is run.  Similarly, when unregistering probes, we want to
    6608                 :   // unregister (actually run) end probes after every other probe type
    6609                 :   // has be unregistered.  To do the latter,
    6610                 :   // c_unparser::emit_module_exit() will run this list backwards.
    6611            1028 :   DOONE(be);
    6612             562 :   DOONE(dwarf);
    6613             562 :   DOONE(uprobe);
    6614             562 :   DOONE(timer);
    6615             562 :   DOONE(profile);
    6616             562 :   DOONE(mark);
    6617             562 :   DOONE(hrtimer);
    6618             562 :   DOONE(perfmon);
    6619             562 :   DOONE(procfs);
    6620                 : #undef DOONE
    6621               0 :   return g;
    6622            2188 : }

Generated by: LTP GCOV extension version 1.5