1 | #pragma once |
2 | |
3 | #if defined(__ELF__) && !defined(__FreeBSD__) |
4 | |
5 | #include <vector> |
6 | #include <string> |
7 | #include <Common/Elf.h> |
8 | #include <boost/noncopyable.hpp> |
9 | |
10 | |
11 | namespace DB |
12 | { |
13 | |
14 | /** Allow to quickly find symbol name from address. |
15 | * Used as a replacement for "dladdr" function which is extremely slow. |
16 | * It works better than "dladdr" because it also allows to search private symbols, that are not participated in shared linking. |
17 | */ |
18 | class SymbolIndex : private boost::noncopyable |
19 | { |
20 | protected: |
21 | SymbolIndex() { update(); } |
22 | |
23 | public: |
24 | static SymbolIndex & instance(); |
25 | |
26 | struct Symbol |
27 | { |
28 | const void * address_begin; |
29 | const void * address_end; |
30 | const char * name; |
31 | }; |
32 | |
33 | struct Object |
34 | { |
35 | const void * address_begin; |
36 | const void * address_end; |
37 | std::string name; |
38 | std::unique_ptr<Elf> elf; |
39 | }; |
40 | |
41 | /// Address in virtual memory should be passed. These addresses include offset where the object is loaded in memory. |
42 | const Symbol * findSymbol(const void * address) const; |
43 | const Object * findObject(const void * address) const; |
44 | |
45 | const std::vector<Symbol> & symbols() const { return data.symbols; } |
46 | const std::vector<Object> & objects() const { return data.objects; } |
47 | |
48 | struct Data |
49 | { |
50 | std::vector<Symbol> symbols; |
51 | std::vector<Object> objects; |
52 | }; |
53 | private: |
54 | Data data; |
55 | |
56 | void update(); |
57 | }; |
58 | |
59 | } |
60 | |
61 | #endif |
62 | |