forked from iovisor/bcc
-
Notifications
You must be signed in to change notification settings - Fork 2
/
syms.h
209 lines (177 loc) · 5.94 KB
/
syms.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/*
* Copyright (c) 2016 GitHub, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http:https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <algorithm>
#include <memory>
#include <string>
#include <sys/types.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "bcc_proc.h"
#include "bcc_syms.h"
#include "file_desc.h"
class ProcStat {
std::string procfs_;
ino_t inode_;
ino_t getinode_();
public:
ProcStat(int pid);
bool is_stale();
void reset() { inode_ = getinode_(); }
};
class SymbolCache {
public:
virtual ~SymbolCache() = default;
virtual void refresh() = 0;
virtual bool resolve_addr(uint64_t addr, struct bcc_symbol *sym, bool demangle = true) = 0;
virtual bool resolve_name(const char *module, const char *name,
uint64_t *addr) = 0;
};
class KSyms : SymbolCache {
struct Symbol {
Symbol(const char *name, uint64_t addr) : name(name), addr(addr) {}
std::string name;
uint64_t addr;
bool operator<(const Symbol &rhs) const { return addr < rhs.addr; }
};
std::vector<Symbol> syms_;
std::unordered_map<std::string, uint64_t> symnames_;
static void _add_symbol(const char *, uint64_t, void *);
public:
virtual bool resolve_addr(uint64_t addr, struct bcc_symbol *sym, bool demangle = true) override;
virtual bool resolve_name(const char *unused, const char *name,
uint64_t *addr) override;
virtual void refresh() override;
};
class ProcSyms : SymbolCache {
struct NameIdx {
size_t section_idx;
size_t str_table_idx;
size_t str_len;
bool debugfile;
};
struct Symbol {
Symbol(const std::string *name, uint64_t start, uint64_t size)
: is_name_resolved(true), start(start), size(size) {
data.name = name;
}
Symbol(size_t section_idx, size_t str_table_idx, size_t str_len, uint64_t start,
uint64_t size, bool debugfile)
: is_name_resolved(false), start(start), size(size) {
data.name_idx.section_idx = section_idx;
data.name_idx.str_table_idx = str_table_idx;
data.name_idx.str_len = str_len;
data.name_idx.debugfile = debugfile;
}
bool is_name_resolved;
union {
struct NameIdx name_idx;
const std::string *name{nullptr};
} data;
uint64_t start;
uint64_t size;
bool operator<(const struct Symbol& rhs) const {
return start < rhs.start;
}
};
enum class ModuleType {
UNKNOWN,
EXEC,
SO,
PERF_MAP,
VDSO
};
struct Module {
struct Range {
uint64_t start;
uint64_t end;
uint64_t file_offset;
Range(uint64_t s, uint64_t e, uint64_t f)
: start(s), end(e), file_offset(f) {}
};
Module(const char *name, const char *path, struct bcc_symbol_option *option);
std::string name_;
std::string path_;
std::vector<Range> ranges_;
bool loaded_;
bcc_symbol_option *symbol_option_;
ModuleType type_;
// The file offset within the ELF of the SO's first text section.
uint64_t elf_so_offset_;
uint64_t elf_so_addr_;
std::unordered_set<std::string> symnames_;
std::vector<Symbol> syms_;
void load_sym_table();
bool contains(uint64_t addr, uint64_t &offset) const;
uint64_t start() const { return ranges_.begin()->start; }
bool find_addr(uint64_t offset, struct bcc_symbol *sym);
bool find_name(const char *symname, uint64_t *addr);
static int _add_symbol(const char *symname, uint64_t start, uint64_t size,
void *p);
static int _add_symbol_lazy(size_t section_idx, size_t str_table_idx,
size_t str_len, uint64_t start, uint64_t size,
int debugfile, void *p);
};
int pid_;
std::vector<Module> modules_;
ProcStat procstat_;
bcc_symbol_option symbol_option_;
static int _add_load_sections(uint64_t v_addr, uint64_t mem_sz,
uint64_t file_offset, void *payload);
static int _add_module(mod_info *, int, void *);
void load_exe();
void load_modules();
public:
ProcSyms(int pid, struct bcc_symbol_option *option = nullptr);
virtual void refresh() override;
virtual bool resolve_addr(uint64_t addr, struct bcc_symbol *sym, bool demangle = true) override;
virtual bool resolve_name(const char *module, const char *name,
uint64_t *addr) override;
};
class BuildSyms {
struct Symbol {
Symbol(const std::string *name, uint64_t start, uint64_t size)
:name(name), start(start), size(size) {}
const std::string *name;
uint64_t start;
uint64_t size;
bool operator<(const struct Symbol &rhs) const {
return start < rhs.start;
}
};
struct Module {
Module(const char *module_name):
module_name_(module_name),
loaded_(false) {}
const std::string module_name_;
const std::string build_id_;
bool loaded_;
std::unordered_set<std::string> symnames_;
std::vector<Symbol> syms_;
bcc_symbol_option symbol_option_;
bool load_sym_table();
static int _add_symbol(const char *symname, uint64_t start, uint64_t size,
void *p);
bool resolve_addr(uint64_t offset, struct bcc_symbol*, bool demangle=true);
};
std::unordered_map<std::string, std::unique_ptr<Module> > buildmap_;
public:
BuildSyms() {}
virtual ~BuildSyms() = default;
virtual bool add_module(const std::string module_name);
virtual bool resolve_addr(std::string build_id, uint64_t offset, struct bcc_symbol *sym, bool demangle = true);
};