-
Notifications
You must be signed in to change notification settings - Fork 163
/
Copy pathPDBSymbolSorterAlphabetical.h
161 lines (138 loc) · 2.93 KB
/
PDBSymbolSorterAlphabetical.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
#pragma once
#include "PDBSymbolSorterBase.h"
#include <cassert>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
class PDBSymbolSorterAlphabetical
: public PDBSymbolSorterBase
{
public:
std::vector<const SYMBOL*>&
GetSortedSymbols() override
{
if (m_Dirty)
{
std::sort(
m_SortedSymbols.begin(),
m_SortedSymbols.end(),
[](const SYMBOL* lhs, const SYMBOL* rhs) {
return strcmp(lhs->Name, rhs->Name) < 0;
});
m_Dirty = false;
}
return m_SortedSymbols;
}
ImageArchitecture
GetImageArchitecture() const override
{
return m_Architecture;
}
void
Clear() override
{
ImageArchitecture m_Architecture = ImageArchitecture::None;
m_VisitedUdts.clear();
m_SortedSymbols.clear();
}
protected:
void
VisitEnumType(
const SYMBOL* Symbol
) override
{
if (HasBeenVisited(Symbol)) return;
AddSymbol(Symbol);
}
void
VisitPointerType(
const SYMBOL* Symbol
) override
{
if (m_Architecture == ImageArchitecture::None)
{
switch (Symbol->Size)
{
case 4:
m_Architecture = ImageArchitecture::x86;
break;
case 8:
m_Architecture = ImageArchitecture::x64;
break;
default:
assert(0);
break;
}
}
}
void
VisitUdt(
const SYMBOL* Symbol
) override
{
if (HasBeenVisited(Symbol)) return;
PDBSymbolVisitorBase::VisitUdt(Symbol);
AddSymbol(Symbol);
}
void
VisitUdtField(
const SYMBOL_UDT_FIELD* UdtField
) override
{
Visit(UdtField->Type);
}
private:
bool
HasBeenVisited(
const SYMBOL* Symbol
)
{
static DWORD UnnamedCounter = 0;
//
// In one PDB there can be more than one symbol
// with same name (and different definitions),
// which would result into redefinitions of types
// during the printing.
//
// Problem is solved by taking into account
// and printing only the first definition of the symbol.
//
// Another solution could be appending a suffix (_1, _2, ...)
// to the symbol names, but then it wouldn't reflect the real names.
// So let's just assume all definitions are same
// and/or the first one is the most correct one.
//
// Also, unnamed symbols must be handled as a special case.
//
std::string Key = Symbol->Name;
if (m_VisitedUdts.find(Key) != m_VisitedUdts.end())
{
return true;
}
else
{
if (PDB::IsUnnamedSymbol(Symbol))
{
Key += std::to_string(++UnnamedCounter);
}
m_VisitedUdts[Key] = Symbol;
return false;
}
}
void
AddSymbol(
const SYMBOL* Symbol
)
{
if (std::find(m_SortedSymbols.begin(), m_SortedSymbols.end(), Symbol) == m_SortedSymbols.end())
{
m_SortedSymbols.push_back(Symbol);
m_Dirty = true;
}
}
ImageArchitecture m_Architecture = ImageArchitecture::None;
std::map<std::string, const SYMBOL*> m_VisitedUdts;
std::vector<const SYMBOL*> m_SortedSymbols;
bool m_Dirty = true;
};