forked from jeremy-rifkin/cpptrace
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathelf.hpp
More file actions
129 lines (106 loc) · 3.99 KB
/
Copy pathelf.hpp
File metadata and controls
129 lines (106 loc) · 3.99 KB
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
#ifndef ELF_HPP
#define ELF_HPP
#include "utils/common.hpp"
#include "utils/utils.hpp"
#if IS_LINUX
#include <cstdint>
#include <string>
#include <unordered_map>
namespace cpptrace {
namespace detail {
class elf {
file_wrapper file;
std::string object_path;
bool is_little_endian;
bool is_64;
struct header_info {
uint64_t e_phoff;
uint32_t e_phnum;
uint32_t e_phentsize;
uint64_t e_shoff;
uint32_t e_shnum;
uint32_t e_shentsize;
};
bool tried_to_load_header = false;
optional<header_info> header;
struct section_info {
uint32_t sh_type;
uint64_t sh_addr;
uint64_t sh_offset;
uint64_t sh_size;
uint64_t sh_entsize;
uint32_t sh_link;
};
bool tried_to_load_sections = false;
bool did_load_sections = false;
std::vector<section_info> sections;
struct strtab_entry {
bool tried_to_load_strtab = false;
bool did_load_strtab = false;
std::vector<char> data;
};
std::unordered_map<std::size_t, strtab_entry> strtab_entries;
struct symtab_entry {
uint32_t st_name;
unsigned char st_info;
unsigned char st_other;
uint16_t st_shndx;
uint64_t st_value;
uint64_t st_size;
};
struct symtab_info {
std::vector<symtab_entry> entries;
std::size_t strtab_link = 0;
};
bool tried_to_load_symtab = false;
bool did_load_symtab = false;
optional<symtab_info> symtab;
bool tried_to_load_dynamic_symtab = false;
bool did_load_dynamic_symtab = false;
optional<symtab_info> dynamic_symtab;
elf(file_wrapper file, const std::string& object_path, bool is_little_endian, bool is_64);
public:
static NODISCARD Result<elf, internal_error> open_elf(const std::string& object_path);
elf(elf&&) = default;
public:
Result<std::uintptr_t, internal_error> get_module_image_base();
private:
template<std::size_t Bits>
Result<std::uintptr_t, internal_error> get_module_image_base_impl();
public:
optional<std::string> lookup_symbol(frame_ptr pc);
private:
optional<std::string> lookup_symbol(frame_ptr pc, const optional<symtab_info>& maybe_symtab);
public:
struct symbol_entry {
std::string st_name;
uint16_t st_shndx;
uint64_t st_value;
uint64_t st_size;
};
Result<optional<std::vector<symbol_entry>>, internal_error> get_symtab_entries();
Result<optional<std::vector<symbol_entry>>, internal_error> get_dynamic_symtab_entries();
private:
Result<optional<std::vector<symbol_entry>>, internal_error> resolve_symtab_entries(
const Result<const optional<symtab_info> &, internal_error>&
);
private:
template<typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
T byteswap_if_needed(T value);
Result<const header_info&, internal_error> get_header_info();
template<std::size_t Bits>
Result<const header_info&, internal_error> get_header_info_impl();
Result<const std::vector<section_info>&, internal_error> get_sections();
template<std::size_t Bits>
Result<const std::vector<section_info>&, internal_error> get_sections_impl();
Result<const std::vector<char>&, internal_error> get_strtab(std::size_t index);
Result<const optional<symtab_info>&, internal_error> get_symtab();
Result<const optional<symtab_info>&, internal_error> get_dynamic_symtab();
template<std::size_t Bits>
Result<optional<symtab_info>, internal_error> get_symtab_impl(bool dynamic);
};
NODISCARD Result<maybe_owned<elf>, internal_error> open_elf_cached(const std::string& object_path);
}
}
#endif
#endif