9
9
10
10
#include " binary/elf.hpp"
11
11
#include " binary/mach-o.hpp"
12
+ #include " cpptrace/utils.hpp"
12
13
13
14
using namespace std ::literals;
14
15
using namespace cpptrace ::detail;
15
16
16
17
template <> struct fmt ::formatter<lyra::cli> : ostream_formatter {};
17
18
19
+ struct options {
20
+ std::filesystem::path path;
21
+ bool demangle = false ;
22
+ bool prune = false ;
23
+ };
24
+
18
25
#if IS_LINUX
19
- void dump_symtab_result (const Result<optional<std::vector<elf::symbol_entry>>, internal_error>& res) {
26
+ void dump_symtab_result (
27
+ const Result<optional<std::vector<elf::symbol_entry>>, internal_error>& res,
28
+ const options& options
29
+ ) {
20
30
if (!res) {
21
31
fmt::println (stderr, " Error loading: {}" , res.unwrap_error ().what ());
22
32
}
@@ -27,7 +37,16 @@ void dump_symtab_result(const Result<optional<std::vector<elf::symbol_entry>>, i
27
37
const auto & entries = entries_.unwrap ();
28
38
fmt::println (" {:16} {:16} {:4} {}" , " value" , " size" , " shdx" , " symbol" );
29
39
for (const auto & entry : entries) {
30
- fmt::println (" {:016x} {:016x} {:04x} {}" , entry.st_value , entry.st_size , entry.st_shndx , entry.st_name );
40
+ std::string name;
41
+ if (options.demangle ) {
42
+ name = cpptrace::demangle (entry.st_name );
43
+ if (options.prune ) {
44
+ name = cpptrace::prune_symbol (name);
45
+ }
46
+ } else {
47
+ name = entry.st_name ;
48
+ }
49
+ fmt::println (" {:016x} {:016x} {:04x} {}" , entry.st_value , entry.st_size , entry.st_shndx , name);
31
50
}
32
51
}
33
52
@@ -39,17 +58,17 @@ auto get_elf(const std::filesystem::path& path) {
39
58
return std::move (elf_).unwrap_value ();
40
59
}
41
60
42
- void dump_symbols (const std::filesystem::path& path ) {
43
- auto elf = get_elf (path);
61
+ void dump_symbols (const options& options ) {
62
+ auto elf = get_elf (options. path );
44
63
fmt::println (" Symtab:" );
45
- dump_symtab_result (elf.get_symtab_entries ());
64
+ dump_symtab_result (elf.get_symtab_entries (), options );
46
65
fmt::println (" Dynamic symtab:" );
47
- dump_symtab_result (elf.get_dynamic_symtab_entries ());
66
+ dump_symtab_result (elf.get_dynamic_symtab_entries (), options );
48
67
}
49
- void lookup_symbol (const std::filesystem::path& path , cpptrace::frame_ptr address) {
50
- auto elf = get_elf (path);
68
+ void lookup_symbol (const options& options , cpptrace::frame_ptr address) {
69
+ auto elf = get_elf (options. path );
51
70
if (auto symbol = elf.lookup_symbol (address)) {
52
- fmt::println (" Symbol: {}" , symbol.unwrap ());
71
+ fmt::println (" Symbol: {}" , options. demangle ? cpptrace::demangle (symbol. unwrap ()) : symbol.unwrap ());
53
72
} else {
54
73
fmt::println (" Could not find symbol" );
55
74
}
@@ -72,12 +91,14 @@ void lookup_symbol(const std::filesystem::path&, cpptrace::frame_ptr) {
72
91
73
92
int symbol_tables (int argc, char ** argv) {
74
93
bool show_help = false ;
75
- std::filesystem::path path;
76
94
std::optional<std::string> lookup;
95
+ options options;
77
96
auto cli = lyra::cli ()
78
97
| lyra::help (show_help)
79
98
| lyra::opt (lookup, " address" )[" --lookup" ](" address in hex to lookup" )
80
- | lyra::arg (path, " binary path" )(" binary to dump symbol tables for" ).required ();
99
+ | lyra::opt (options.demangle )[" --demangle" ](" demangle the symbol" )
100
+ | lyra::opt (options.prune )[" --prune" ](" prune the symbol" )
101
+ | lyra::arg (options.path , " binary path" )(" binary to dump symbol tables for" ).required ();
81
102
if (auto result = cli.parse ({ argc, argv }); !result) {
82
103
fmt::println (stderr, " Error in command line: {}" , result.message ());
83
104
fmt::println (" {}" , cli);
@@ -87,21 +108,21 @@ int symbol_tables(int argc, char** argv) {
87
108
fmt::println (" {}" , cli);
88
109
return 0 ;
89
110
}
90
- if (!std::filesystem::exists (path)) {
91
- fmt::println (stderr, " Error: Path doesn't exist {}" , path);
111
+ if (!std::filesystem::exists (options. path )) {
112
+ fmt::println (stderr, " Error: Path doesn't exist {}" , options. path );
92
113
return 1 ;
93
114
}
94
- if (!std::filesystem::is_regular_file (path)) {
95
- fmt::println (stderr, " Error: Path isn't a regular file {}" , path);
115
+ if (!std::filesystem::is_regular_file (options. path )) {
116
+ fmt::println (stderr, " Error: Path isn't a regular file {}" , options. path );
96
117
return 1 ;
97
118
}
98
119
if (lookup) {
99
120
auto address = std::stoull (*lookup, nullptr , 16 );
100
121
fmt::println (stderr, " Looking up address {:016x}" , address);
101
- lookup_symbol (path , address);
122
+ lookup_symbol (options , address);
102
123
return 0 ;
103
124
}
104
- dump_symbols (path );
125
+ dump_symbols (options );
105
126
return 0 ;
106
127
}
107
128
0 commit comments