add support for sorting, print enums in declaration list

This commit is contained in:
Petr Benes
2018-08-20 01:26:16 +02:00
parent 7194353d0e
commit 97ec118e9c
7 changed files with 235 additions and 21 deletions
+29 -6
View File
@@ -2,6 +2,7 @@
#include "PDBHeaderReconstructor.h"
#include "PDBSymbolVisitor.h"
#include "PDBSymbolSorter.h"
#include "PDBSymbolSorterAlphabetical.h"
#include "UdtFieldDefinition.h"
#include <iostream>
@@ -147,6 +148,7 @@ PDBExtractor::PrintUsage()
printf(" -n Print declarations. (T)\n");
printf(" -l Print definitions. (T)\n");
printf(" -z Print #pragma pack directives. (T)\n");
printf(" -y Sort declarations and definitions. (F)\n");
printf("\n");
}
@@ -354,6 +356,10 @@ PDBExtractor::ParseParameters(
m_Settings.PrintPragmaPack = !OffSwitch;
break;
case 'y':
m_Settings.Sort = !OffSwitch;
break;
default:
throw PDBDumperException(MESSAGE_INVALID_PARAMETERS);
}
@@ -368,7 +374,14 @@ PDBExtractor::ParseParameters(
&m_Settings.UdtFieldDefinitionSettings
);
m_SymbolSorter = std::make_unique<PDBSymbolSorter>();
if (m_Settings.Sort)
{
m_SymbolSorter = std::make_unique<PDBSymbolSorterAlphabetical>();
}
else
{
m_SymbolSorter = std::make_unique<PDBSymbolSorter>();
}
}
void
@@ -440,12 +453,22 @@ PDBExtractor::PrintPDBDeclarations()
{
for (auto&& e : m_SymbolSorter->GetSortedSymbols())
{
if (e->Tag == SymTagUDT && !PDB::IsUnnamedSymbol(e))
if (!PDB::IsUnnamedSymbol(e))
{
*m_Settings.PdbHeaderReconstructorSettings.OutputFile
<< PDB::GetUdtKindString(e->u.Udt.Kind)
<< " " << m_HeaderReconstructor->GetCorrectedSymbolName(e) << ";"
<< std::endl;
if (e->Tag == SymTagUDT)
{
*m_Settings.PdbHeaderReconstructorSettings.OutputFile
<< PDB::GetUdtKindString(e->u.Udt.Kind)
<< " " << m_HeaderReconstructor->GetCorrectedSymbolName(e) << ";"
<< std::endl;
}
else if (e->Tag == SymTagEnum)
{
*m_Settings.PdbHeaderReconstructorSettings.OutputFile
<< "enum"
<< " " << m_HeaderReconstructor->GetCorrectedSymbolName(e) << ";"
<< std::endl;
}
}
}
+3 -2
View File
@@ -1,5 +1,5 @@
#pragma once
#include "PDBSymbolSorter.h"
#include "PDBSymbolSorterBase.h"
#include "PDBHeaderReconstructor.h"
#include "PDBSymbolVisitor.h"
#include "UdtFieldDefinition.h"
@@ -31,6 +31,7 @@ class PDBExtractor
bool PrintDeclarations = true;
bool PrintDefinitions = true;
bool PrintPragmaPack = true;
bool Sort = false;
};
int Run(
@@ -79,7 +80,7 @@ class PDBExtractor
PDB m_PDB;
Settings m_Settings;
std::unique_ptr<PDBSymbolSorter> m_SymbolSorter;
std::unique_ptr<PDBSymbolSorterBase> m_SymbolSorter;
std::unique_ptr<PDBHeaderReconstructor> m_HeaderReconstructor;
std::unique_ptr<PDBSymbolVisitor<UdtFieldDefinition>> m_SymbolVisitor;
};
+5 -13
View File
@@ -1,37 +1,29 @@
#pragma once
#include "PDB.h"
#include "PDBSymbolVisitorBase.h"
#include "PDBSymbolSorterBase.h"
#include <cassert>
#include <string>
#include <vector>
#include <map>
enum class ImageArchitecture
{
None,
x86,
x64,
};
class PDBSymbolSorter
: public PDBSymbolVisitorBase
: public PDBSymbolSorterBase
{
public:
std::vector<const SYMBOL*>&
GetSortedSymbols()
GetSortedSymbols() override
{
return m_SortedSymbols;
}
ImageArchitecture
GetImageArchitecture() const
GetImageArchitecture() const override
{
return m_Architecture;
}
void
Clear()
Clear() override
{
ImageArchitecture m_Architecture = ImageArchitecture::None;
+161
View File
@@ -0,0 +1,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;
};
+29
View File
@@ -0,0 +1,29 @@
#pragma once
#include "PDB.h"
#include "PDBSymbolVisitorBase.h"
#include <vector>
class PDBSymbolSorterBase
: public PDBSymbolVisitorBase
{
public:
enum class ImageArchitecture
{
None,
x86,
x64,
};
virtual
std::vector<const SYMBOL*>&
GetSortedSymbols() = 0;
virtual
ImageArchitecture
GetImageArchitecture() const = 0;
virtual
void
Clear() = 0;
};
+2
View File
@@ -170,6 +170,8 @@
<ClInclude Include="PDBExtractor.h" />
<ClInclude Include="PDBHeaderReconstructor.h" />
<ClInclude Include="PDBReconstructorBase.h" />
<ClInclude Include="PDBSymbolSorterAlphabetical.h" />
<ClInclude Include="PDBSymbolSorterBase.h" />
<ClInclude Include="PDBSymbolVisitorBase.h" />
<ClInclude Include="PDBSymbolVisitor.h" />
<ClInclude Include="PDBSymbolSorter.h" />
+6
View File
@@ -56,6 +56,12 @@
<ClInclude Include="UdtFieldDefinitionBase.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PDBSymbolSorterAlphabetical.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PDBSymbolSorterBase.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="PDBSymbolVisitor.inl">