LCOV - code coverage report
Current view: top level - mnt/wasteland/wcohen/systemtap_write/systemtap - dwflpp.h (source / functions) Hit Total Coverage
Test: stap.info Lines: 14 14 100.0 %
Date: 2013-03-08 Functions: 8 10 80.0 %
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : // C++ interface to dwfl
       2                 :            : // Copyright (C) 2005-2013 Red Hat Inc.
       3                 :            : // Copyright (C) 2005-2007 Intel Corporation.
       4                 :            : // Copyright (C) 2008 James.Bottomley@HansenPartnership.com
       5                 :            : //
       6                 :            : // This file is part of systemtap, and is free software.  You can
       7                 :            : // redistribute it and/or modify it under the terms of the GNU General
       8                 :            : // Public License (GPL); either version 2, or (at your option) any
       9                 :            : // later version.
      10                 :            : 
      11                 :            : #ifndef DWFLPP_H
      12                 :            : #define DWFLPP_H
      13                 :            : 
      14                 :            : #include "config.h"
      15                 :            : #include "dwarf_wrappers.h"
      16                 :            : #include "elaborate.h"
      17                 :            : #include "session.h"
      18                 :            : #include "unordered.h"
      19                 :            : #include "setupdwfl.h"
      20                 :            : 
      21                 :            : #include <cstring>
      22                 :            : #include <iostream>
      23                 :            : #include <map>
      24                 :            : #include <set>
      25                 :            : #include <string>
      26                 :            : #include <vector>
      27                 :            : 
      28                 :            : extern "C" {
      29                 :            : #include <elfutils/libdwfl.h>
      30                 :            : #include <regex.h>
      31                 :            : }
      32                 :            : 
      33                 :            : 
      34                 :            : struct func_info;
      35                 :            : struct inline_instance_info;
      36                 :            : struct symbol_table;
      37                 :            : struct base_query;
      38                 :            : struct dwarf_query;
      39                 :            : 
      40                 :            : enum line_t { ABSOLUTE, RELATIVE, RANGE, WILDCARD };
      41                 :            : enum info_status { info_unknown, info_present, info_absent };
      42                 :            : 
      43                 :            : // module -> cu die[]
      44                 :            : typedef unordered_map<Dwarf*, std::vector<Dwarf_Die>*> module_cu_cache_t;
      45                 :            : 
      46                 :            : // An instance of this type tracks whether the type units for a given
      47                 :            : // Dwarf have been read.
      48                 :            : typedef std::set<Dwarf*> module_tus_read_t;
      49                 :            : 
      50                 :            : // typename -> die
      51                 :            : typedef unordered_map<std::string, Dwarf_Die> cu_type_cache_t;
      52                 :            : 
      53                 :            : // cu die -> (typename -> die)
      54                 :            : typedef unordered_map<void*, cu_type_cache_t*> mod_cu_type_cache_t;
      55                 :            : 
      56                 :            : // function -> die
      57                 :            : typedef unordered_multimap<std::string, Dwarf_Die> cu_function_cache_t;
      58                 :            : typedef std::pair<cu_function_cache_t::iterator,
      59                 :            :                   cu_function_cache_t::iterator>
      60                 :            :         cu_function_cache_range_t;
      61                 :            : 
      62                 :            : // cu die -> (function -> die)
      63                 :            : typedef unordered_map<void*, cu_function_cache_t*> mod_cu_function_cache_t;
      64                 :            : 
      65                 :            : // module -> (function -> die)
      66                 :            : typedef unordered_map<Dwarf*, cu_function_cache_t*> mod_function_cache_t;
      67                 :            : 
      68                 :            : // inline function die -> instance die[]
      69                 :            : typedef unordered_map<void*, std::vector<Dwarf_Die>*> cu_inl_function_cache_t;
      70                 :            : 
      71                 :            : // die -> parent die
      72                 :            : typedef unordered_map<void*, Dwarf_Die> cu_die_parent_cache_t;
      73                 :            : 
      74                 :            : // cu die -> (die -> parent die)
      75                 :            : typedef unordered_map<void*, cu_die_parent_cache_t*> mod_cu_die_parent_cache_t;
      76                 :            : 
      77                 :            : typedef std::vector<func_info> func_info_map_t;
      78                 :            : typedef std::vector<inline_instance_info> inline_instance_map_t;
      79                 :            : 
      80                 :            : 
      81                 :            : /* XXX FIXME functions that dwflpp needs from tapsets.cxx */
      82                 :            : func_info_map_t *get_filtered_functions(dwarf_query *q);
      83                 :            : inline_instance_map_t *get_filtered_inlines(dwarf_query *q);
      84                 :            : 
      85                 :            : 
      86                 :            : struct
      87                 :            : module_info
      88                 :            : {
      89                 :            :   Dwfl_Module* mod;
      90                 :            :   const char* name;
      91                 :            :   std::string elf_path;
      92                 :            :   Dwarf_Addr addr;
      93                 :            :   Dwarf_Addr bias;
      94                 :            :   symbol_table *sym_table;
      95                 :            :   info_status dwarf_status;     // module has dwarf info?
      96                 :            :   info_status symtab_status;    // symbol table cached?
      97                 :            : 
      98                 :            :   void get_symtab(dwarf_query *q);
      99                 :            :   void update_symtab(cu_function_cache_t *funcs);
     100                 :            : 
     101                 :       4646 :   module_info(const char *name) :
     102                 :            :     mod(NULL),
     103                 :            :     name(name),
     104                 :            :     addr(0),
     105                 :            :     bias(0),
     106                 :            :     sym_table(NULL),
     107                 :            :     dwarf_status(info_unknown),
     108                 :       4646 :     symtab_status(info_unknown)
     109                 :       4646 :   {}
     110                 :            : 
     111                 :            :   ~module_info();
     112                 :            : };
     113                 :            : 
     114                 :            : 
     115                 :            : struct
     116                 :            : module_cache
     117                 :            : {
     118                 :            :   std::map<std::string, module_info*> cache;
     119                 :            :   bool paths_collected;
     120                 :            :   bool dwarf_collected;
     121                 :            : 
     122                 :        645 :   module_cache() : paths_collected(false), dwarf_collected(false) {}
     123                 :            :   ~module_cache();
     124                 :            : };
     125                 :            : 
     126                 :            : 
     127                 :   10827270 : struct func_info
     128                 :            : {
     129                 :   10420472 :   func_info()
     130                 :            :     : decl_file(NULL), decl_line(-1), addr(0), entrypc(0), prologue_end(0),
     131                 :   10420472 :       weak(false), descriptor(false)
     132                 :            :   {
     133                 :   10420472 :     std::memset(&die, 0, sizeof(die));
     134                 :   10420472 :   }
     135                 :            :   std::string name;
     136                 :            :   char const * decl_file;
     137                 :            :   int decl_line;
     138                 :            :   Dwarf_Die die;
     139                 :            :   Dwarf_Addr addr;
     140                 :            :   Dwarf_Addr entrypc;
     141                 :            :   Dwarf_Addr prologue_end;
     142                 :            :   bool weak, descriptor;
     143                 :            : };
     144                 :            : 
     145                 :            : 
     146                 :    1081178 : struct inline_instance_info
     147                 :            : {
     148                 :     213596 :   inline_instance_info()
     149                 :     213596 :     : decl_file(NULL), decl_line(-1), entrypc(0)
     150                 :            :   {
     151                 :     213596 :     std::memset(&die, 0, sizeof(die));
     152                 :     213596 :   }
     153                 :            :   bool operator<(const inline_instance_info& other) const;
     154                 :            :   std::string name;
     155                 :            :   char const * decl_file;
     156                 :            :   int decl_line;
     157                 :            :   Dwarf_Addr entrypc;
     158                 :            :   Dwarf_Die die;
     159                 :            : };
     160                 :            : 
     161                 :            : 
     162                 :            : struct dwflpp
     163                 :            : {
     164                 :            :   systemtap_session & sess;
     165                 :            : 
     166                 :            :   // These are "current" values we focus on.
     167                 :            :   Dwfl_Module * module;
     168                 :            :   Dwarf_Addr module_bias;
     169                 :            :   module_info * mod_info;
     170                 :            : 
     171                 :            :   // These describe the current module's PC address range
     172                 :            :   Dwarf_Addr module_start;
     173                 :            :   Dwarf_Addr module_end;
     174                 :            : 
     175                 :            :   Dwarf_Die * cu;
     176                 :            : 
     177                 :            :   std::string module_name;
     178                 :            :   std::string function_name;
     179                 :            : 
     180                 :            :   dwflpp(systemtap_session & session, const std::string& user_module, bool kernel_p);
     181                 :            :   dwflpp(systemtap_session & session, const std::vector<std::string>& user_modules, bool kernel_p);
     182                 :            :   ~dwflpp();
     183                 :            : 
     184                 :            :   void get_module_dwarf(bool required = false, bool report = true);
     185                 :            : 
     186                 :            :   void focus_on_module(Dwfl_Module * m, module_info * mi);
     187                 :            :   void focus_on_cu(Dwarf_Die * c);
     188                 :            :   void focus_on_function(Dwarf_Die * f);
     189                 :            : 
     190                 :            :   std::string cu_name(void);
     191                 :            : 
     192                 :            :   Dwarf_Die *query_cu_containing_address(Dwarf_Addr a);
     193                 :            : 
     194                 :            :   bool module_name_matches(const std::string& pattern);
     195                 :            :   static bool name_has_wildcard(const std::string& pattern);
     196                 :            :   bool module_name_final_match(const std::string& pattern);
     197                 :            : 
     198                 :            :   bool function_name_matches_pattern(const std::string& name, const std::string& pattern);
     199                 :            :   bool function_name_matches(const std::string& pattern);
     200                 :            :   bool function_scope_matches(const std::vector<std::string>& scopes);
     201                 :            : 
     202                 :            :   void iterate_over_modules(int (* callback)(Dwfl_Module *, void **,
     203                 :            :                                              const char *, Dwarf_Addr,
     204                 :            :                                              void *),
     205                 :            :                             void *data);
     206                 :            : 
     207                 :            :   void iterate_over_cus (int (*callback)(Dwarf_Die * die, void * arg),
     208                 :            :                          void * data, bool want_types);
     209                 :            : 
     210                 :            :   bool func_is_inline();
     211                 :            : 
     212                 :            :   bool func_is_exported();
     213                 :            : 
     214                 :            :   void iterate_over_inline_instances (int (* callback)(Dwarf_Die * die, void * arg),
     215                 :            :                                       void * data);
     216                 :            : 
     217                 :            :   std::vector<Dwarf_Die> getscopes_die(Dwarf_Die* die);
     218                 :            :   std::vector<Dwarf_Die> getscopes(Dwarf_Die* die);
     219                 :            :   std::vector<Dwarf_Die> getscopes(Dwarf_Addr pc);
     220                 :            : 
     221                 :            :   Dwarf_Die *declaration_resolve(Dwarf_Die *type);
     222                 :            :   Dwarf_Die *declaration_resolve(const std::string& name);
     223                 :            :   Dwarf_Die *declaration_resolve_other_cus(const std::string& name);
     224                 :            : 
     225                 :            :   int iterate_over_functions (int (* callback)(Dwarf_Die * func, base_query * q),
     226                 :            :                               base_query * q, const std::string& function);
     227                 :            : 
     228                 :            :   int iterate_single_function (int (* callback)(Dwarf_Die * func, base_query * q),
     229                 :            :                                base_query * q, const std::string& function);
     230                 :            : 
     231                 :            :   void iterate_over_srcfile_lines (char const * srcfile,
     232                 :            :                                    int lines[2],
     233                 :            :                                    bool need_single_match,
     234                 :            :                                    enum line_t line_type,
     235                 :            :                                    void (* callback) (const dwarf_line_t& line,
     236                 :            :                                                       void * arg),
     237                 :            :                                    const std::string& func_pattern,
     238                 :            :                                    void *data);
     239                 :            : 
     240                 :            :   void iterate_over_labels (Dwarf_Die *begin_die,
     241                 :            :                             const std::string& sym,
     242                 :            :                             const std::string& function,
     243                 :            :                             dwarf_query *q,
     244                 :            :                             void (* callback)(const std::string &,
     245                 :            :                                               const char *,
     246                 :            :                                               const char *,
     247                 :            :                                               int,
     248                 :            :                                               Dwarf_Die *,
     249                 :            :                                               Dwarf_Addr,
     250                 :            :                                               dwarf_query *));
     251                 :            : 
     252                 :            :   int iterate_over_notes (void *object,
     253                 :            :                           void (*callback)(void *object, int type,
     254                 :            :                                            const char *data, size_t len));
     255                 :            : 
     256                 :            :   void iterate_over_libraries (void (*callback)(void *object,
     257                 :            :       const char *data), void *data);
     258                 :            : 
     259                 :            : 
     260                 :            :   int iterate_over_plt (void *object,
     261                 :            :                           void (*callback)(void *object, const char *name, size_t address));
     262                 :            : 
     263                 :            :   GElf_Shdr * get_section(std::string section_name, GElf_Shdr *shdr_mem,
     264                 :            :                           Elf **elf_ret=NULL);
     265                 :            : 
     266                 :            :   void collect_srcfiles_matching (std::string const & pattern,
     267                 :            :                                   std::set<std::string> & filtered_srcfiles);
     268                 :            : 
     269                 :            :   void resolve_prologue_endings (func_info_map_t & funcs);
     270                 :            : 
     271                 :            :   bool function_entrypc (Dwarf_Addr * addr);
     272                 :            :   bool die_entrypc (Dwarf_Die * die, Dwarf_Addr * addr);
     273                 :            : 
     274                 :            :   void function_die (Dwarf_Die *d);
     275                 :            :   void function_file (char const ** c);
     276                 :            :   void function_line (int *linep);
     277                 :            : 
     278                 :            :   bool die_has_pc (Dwarf_Die & die, Dwarf_Addr pc);
     279                 :            :   bool inner_die_containing_pc(Dwarf_Die& scope, Dwarf_Addr addr,
     280                 :            :                                Dwarf_Die& result);
     281                 :            : 
     282                 :            :   std::string literal_stmt_for_local (std::vector<Dwarf_Die>& scopes,
     283                 :            :                                       Dwarf_Addr pc,
     284                 :            :                                       std::string const & local,
     285                 :            :                                       const target_symbol *e,
     286                 :            :                                       bool lvalue,
     287                 :            :                                       exp_type & ty);
     288                 :            :   Dwarf_Die* type_die_for_local (std::vector<Dwarf_Die>& scopes,
     289                 :            :                                  Dwarf_Addr pc,
     290                 :            :                                  std::string const & local,
     291                 :            :                                  const target_symbol *e,
     292                 :            :                                  Dwarf_Die *die_mem);
     293                 :            : 
     294                 :            :   std::string literal_stmt_for_return (Dwarf_Die *scope_die,
     295                 :            :                                        Dwarf_Addr pc,
     296                 :            :                                        const target_symbol *e,
     297                 :            :                                        bool lvalue,
     298                 :            :                                        exp_type & ty);
     299                 :            :   Dwarf_Die* type_die_for_return (Dwarf_Die *scope_die,
     300                 :            :                                   Dwarf_Addr pc,
     301                 :            :                                   const target_symbol *e,
     302                 :            :                                   Dwarf_Die *die_mem);
     303                 :            : 
     304                 :            :   std::string literal_stmt_for_pointer (Dwarf_Die *type_die,
     305                 :            :                                         const target_symbol *e,
     306                 :            :                                         bool lvalue,
     307                 :            :                                         exp_type & ty);
     308                 :            :   Dwarf_Die* type_die_for_pointer (Dwarf_Die *type_die,
     309                 :            :                                    const target_symbol *e,
     310                 :            :                                    Dwarf_Die *die_mem);
     311                 :            : 
     312                 :            :   bool blacklisted_p(const std::string& funcname,
     313                 :            :                      const std::string& filename,
     314                 :            :                      int line,
     315                 :            :                      const std::string& module,
     316                 :            :                      Dwarf_Addr addr,
     317                 :            :                      bool has_return);
     318                 :            : 
     319                 :            :   Dwarf_Addr relocate_address(Dwarf_Addr addr, std::string& reloc_section);
     320                 :            : 
     321                 :            :   void resolve_unqualified_inner_typedie (Dwarf_Die *typedie,
     322                 :            :                                           Dwarf_Die *innerdie,
     323                 :            :                                           const target_symbol *e);
     324                 :            : 
     325                 :            : 
     326                 :            : private:
     327                 :            :   DwflPtr dwfl_ptr;
     328                 :            : 
     329                 :            :   // These are "current" values we focus on.
     330                 :            :   Dwarf * module_dwarf;
     331                 :            :   Dwarf_Die * function;
     332                 :            : 
     333                 :            :   void setup_kernel(const std::string& module_name, systemtap_session &s, bool debuginfo_needed = true);
     334                 :            :   void setup_kernel(const std::vector<std::string>& modules, bool debuginfo_needed = true);
     335                 :            :   void setup_user(const std::vector<std::string>& modules, bool debuginfo_needed = true);
     336                 :            : 
     337                 :            :   module_cu_cache_t module_cu_cache;
     338                 :            :   module_tus_read_t module_tus_read;
     339                 :            :   mod_cu_function_cache_t cu_function_cache;
     340                 :            :   mod_function_cache_t mod_function_cache;
     341                 :            : 
     342                 :            :   std::set<void*> cu_inl_function_cache_done; // CUs that are already cached
     343                 :            :   cu_inl_function_cache_t cu_inl_function_cache;
     344                 :            :   void cache_inline_instances (Dwarf_Die* die);
     345                 :            : 
     346                 :            :   mod_cu_die_parent_cache_t cu_die_parent_cache;
     347                 :            :   void cache_die_parents(cu_die_parent_cache_t* parents, Dwarf_Die* die);
     348                 :            :   cu_die_parent_cache_t *get_die_parents();
     349                 :            : 
     350                 :            :   Dwarf_Die* get_parent_scope(Dwarf_Die* die);
     351                 :            : 
     352                 :            :   /* The global alias cache is used to resolve any DIE found in a
     353                 :            :    * module that is stubbed out with DW_AT_declaration with a defining
     354                 :            :    * DIE found in a different module.  The current assumption is that
     355                 :            :    * this only applies to structures and unions, which have a global
     356                 :            :    * namespace (it deliberately only traverses program scope), so this
     357                 :            :    * cache is indexed by name.  If other declaration lookups were
     358                 :            :    * added to it, it would have to be indexed by name and tag
     359                 :            :    */
     360                 :            :   mod_cu_type_cache_t global_alias_cache;
     361                 :            :   static int global_alias_caching_callback(Dwarf_Die *die, bool has_inner_types,
     362                 :            :                                            const std::string& prefix, void *arg);
     363                 :            :   static int global_alias_caching_callback_cus(Dwarf_Die *die, void *arg);
     364                 :            :   static int iterate_over_globals (Dwarf_Die *,
     365                 :            :                                    int (* callback)(Dwarf_Die *, bool,
     366                 :            :                                                     const std::string&, void *),
     367                 :            :                                    void * data);
     368                 :            :   static int iterate_over_types (Dwarf_Die *, bool, const std::string&,
     369                 :            :                                  int (* callback)(Dwarf_Die *, bool,
     370                 :            :                                                   const std::string&, void *),
     371                 :            :                                  void * data);
     372                 :            : 
     373                 :            :   static int mod_function_caching_callback (Dwarf_Die* func, void *arg);
     374                 :            :   static int cu_function_caching_callback (Dwarf_Die* func, void *arg);
     375                 :            : 
     376                 :            :   bool has_single_line_record (dwarf_query * q, char const * srcfile, int lineno);
     377                 :            : 
     378                 :            :   static void loc2c_error (void *, const char *fmt, ...) __attribute__ ((noreturn));
     379                 :            : 
     380                 :            :   // This function generates code used for addressing computations of
     381                 :            :   // target variables.
     382                 :            :   void emit_address (struct obstack *pool, Dwarf_Addr address);
     383                 :            :   static void loc2c_emit_address (void *arg, struct obstack *pool,
     384                 :            :                                   Dwarf_Addr address);
     385                 :            : 
     386                 :            :   void print_locals(std::vector<Dwarf_Die>& scopes, std::ostream &o);
     387                 :            :   void print_locals_die(Dwarf_Die &die, std::ostream &o);
     388                 :            :   void print_members(Dwarf_Die *vardie, std::ostream &o,
     389                 :            :                      std::set<std::string> &dupes);
     390                 :            : 
     391                 :            :   Dwarf_Attribute *find_variable_and_frame_base (std::vector<Dwarf_Die>& scopes,
     392                 :            :                                                  Dwarf_Addr pc,
     393                 :            :                                                  std::string const & local,
     394                 :            :                                                  const target_symbol *e,
     395                 :            :                                                  Dwarf_Die *vardie,
     396                 :            :                                                  Dwarf_Attribute *fb_attr_mem);
     397                 :            : 
     398                 :            :   struct location *translate_location(struct obstack *pool,
     399                 :            :                                       Dwarf_Attribute *attr,
     400                 :            :                                       Dwarf_Die *die,
     401                 :            :                                       Dwarf_Addr pc,
     402                 :            :                                       Dwarf_Attribute *fb_attr,
     403                 :            :                                       struct location **tail,
     404                 :            :                                       const target_symbol *e);
     405                 :            : 
     406                 :            :   bool find_struct_member(const target_symbol::component& c,
     407                 :            :                           Dwarf_Die *parentdie,
     408                 :            :                           Dwarf_Die *memberdie,
     409                 :            :                           std::vector<Dwarf_Die>& dies,
     410                 :            :                           std::vector<Dwarf_Attribute>& locs);
     411                 :            : 
     412                 :            :   void translate_components(struct obstack *pool,
     413                 :            :                             struct location **tail,
     414                 :            :                             Dwarf_Addr pc,
     415                 :            :                             const target_symbol *e,
     416                 :            :                             Dwarf_Die *vardie,
     417                 :            :                             Dwarf_Die *typedie,
     418                 :            :                             unsigned first=0);
     419                 :            : 
     420                 :            :   void translate_final_fetch_or_store (struct obstack *pool,
     421                 :            :                                        struct location **tail,
     422                 :            :                                        Dwarf_Addr module_bias,
     423                 :            :                                        Dwarf_Die *vardie,
     424                 :            :                                        Dwarf_Die *typedie,
     425                 :            :                                        bool lvalue,
     426                 :            :                                        const target_symbol *e,
     427                 :            :                                        std::string &,
     428                 :            :                                        std::string &,
     429                 :            :                                        exp_type & ty);
     430                 :            : 
     431                 :            :   std::string express_as_string (std::string prelude,
     432                 :            :                                  std::string postlude,
     433                 :            :                                  struct location *head);
     434                 :            : 
     435                 :            :   regex_t blacklist_func; // function/statement probes
     436                 :            :   regex_t blacklist_func_ret; // only for .return probes
     437                 :            :   regex_t blacklist_file; // file name
     438                 :            :   regex_t blacklist_section; // init/exit sections
     439                 :            :   bool blacklist_enabled;
     440                 :            :   void build_blacklist();
     441                 :            :   std::string get_blacklist_section(Dwarf_Addr addr);
     442                 :            : 
     443                 :            :   // Returns the call frame address operations for the given program counter.
     444                 :            :   Dwarf_Op *get_cfa_ops (Dwarf_Addr pc);
     445                 :            : 
     446                 :            :   Dwarf_Addr vardie_from_symtable(Dwarf_Die *vardie, Dwarf_Addr *addr);
     447                 :            : 
     448                 :            :   static int add_module_build_id_to_hash (Dwfl_Module *m,
     449                 :            :                  void **userdata __attribute__ ((unused)),
     450                 :            :                  const char *name,
     451                 :            :                  Dwarf_Addr base,
     452                 :            :                  void *arg);
     453                 :            : 
     454                 :            : public:
     455                 :            :   Dwarf_Addr pr15123_retry_addr (Dwarf_Addr pc, Dwarf_Die* var);
     456                 :            : };
     457                 :            : 
     458                 :            : #endif // DWFLPP_H
     459                 :            : 
     460                 :            : /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */

Generated by: LCOV version 1.9