Home | History | Annotate | Download | only in cc
      1 /*
      2  * Copyright (c) 2016 GitHub, Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 #pragma once
     17 
     18 #include <algorithm>
     19 #include <memory>
     20 #include <string>
     21 #include <sys/types.h>
     22 #include <unordered_map>
     23 #include <unordered_set>
     24 #include <vector>
     25 
     26 #include "bcc_syms.h"
     27 #include "file_desc.h"
     28 #include "ns_guard.h"
     29 
     30 class ProcStat {
     31   std::string procfs_;
     32   ino_t inode_;
     33   ino_t getinode_();
     34 
     35 public:
     36   ProcStat(int pid);
     37   bool is_stale();
     38   void reset() { inode_ = getinode_(); }
     39 };
     40 
     41 class SymbolCache {
     42 public:
     43   virtual ~SymbolCache() = default;
     44 
     45   virtual void refresh() = 0;
     46   virtual bool resolve_addr(uint64_t addr, struct bcc_symbol *sym, bool demangle = true) = 0;
     47   virtual bool resolve_name(const char *module, const char *name,
     48                             uint64_t *addr) = 0;
     49 };
     50 
     51 class KSyms : SymbolCache {
     52   struct Symbol {
     53     Symbol(const char *name, uint64_t addr) : name(name), addr(addr) {}
     54     std::string name;
     55     uint64_t addr;
     56 
     57     bool operator<(const Symbol &rhs) const { return addr < rhs.addr; }
     58   };
     59 
     60   std::vector<Symbol> syms_;
     61   std::unordered_map<std::string, uint64_t> symnames_;
     62   static void _add_symbol(const char *, uint64_t, void *);
     63 
     64 public:
     65   virtual bool resolve_addr(uint64_t addr, struct bcc_symbol *sym, bool demangle = true);
     66   virtual bool resolve_name(const char *unused, const char *name,
     67                             uint64_t *addr);
     68   virtual void refresh();
     69 };
     70 
     71 class ProcSyms : SymbolCache {
     72   struct Symbol {
     73     Symbol(const std::string *name, uint64_t start, uint64_t size)
     74         : name(name), start(start), size(size) {}
     75     const std::string *name;
     76     uint64_t start;
     77     uint64_t size;
     78 
     79     bool operator<(const struct Symbol& rhs) const {
     80       return start < rhs.start;
     81     }
     82   };
     83 
     84   enum class ModuleType {
     85     UNKNOWN,
     86     EXEC,
     87     SO,
     88     PERF_MAP,
     89     VDSO
     90   };
     91 
     92   struct Module {
     93     struct Range {
     94       uint64_t start;
     95       uint64_t end;
     96       uint64_t file_offset;
     97       Range(uint64_t s, uint64_t e, uint64_t f)
     98           : start(s), end(e), file_offset(f) {}
     99     };
    100 
    101     Module(const char *name, ProcMountNS *mount_ns,
    102            struct bcc_symbol_option *option);
    103 
    104     std::string name_;
    105     std::vector<Range> ranges_;
    106     bool loaded_;
    107     ProcMountNS *mount_ns_;
    108     bcc_symbol_option *symbol_option_;
    109     ModuleType type_;
    110 
    111     // The file offset within the ELF of the SO's first text section.
    112     uint64_t elf_so_offset_;
    113     uint64_t elf_so_addr_;
    114 
    115     std::unordered_set<std::string> symnames_;
    116     std::vector<Symbol> syms_;
    117 
    118     void load_sym_table();
    119 
    120     bool contains(uint64_t addr, uint64_t &offset) const;
    121     uint64_t start() const { return ranges_.begin()->start; }
    122 
    123     bool find_addr(uint64_t offset, struct bcc_symbol *sym);
    124     bool find_name(const char *symname, uint64_t *addr);
    125 
    126     static int _add_symbol(const char *symname, uint64_t start, uint64_t size,
    127                            void *p);
    128   };
    129 
    130   int pid_;
    131   std::vector<Module> modules_;
    132   ProcStat procstat_;
    133   std::unique_ptr<ProcMountNS> mount_ns_instance_;
    134   bcc_symbol_option symbol_option_;
    135 
    136   static int _add_load_sections(uint64_t v_addr, uint64_t mem_sz,
    137                                 uint64_t file_offset, void *payload);
    138   static int _add_module(const char *, uint64_t, uint64_t, uint64_t, bool,
    139                          void *);
    140   void load_exe();
    141   void load_modules();
    142 
    143 public:
    144   ProcSyms(int pid, struct bcc_symbol_option *option = nullptr);
    145   virtual void refresh();
    146   virtual bool resolve_addr(uint64_t addr, struct bcc_symbol *sym, bool demangle = true);
    147   virtual bool resolve_name(const char *module, const char *name,
    148                             uint64_t *addr);
    149 };
    150