llvm.org GIT mirror llvm / b478109
[PDB] Add support for dumping Typedef records. These work a little differently because they are actually in the globals stream and are treated as symbol records, even though DIA presents them as types. So this also adds the necessary infrastructure to cache records that live somewhere other than the TPI stream as well. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@343507 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 11 months ago
13 changed file(s) with 275 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
0 //==- NativeEnumGlobals.h - Native Global Enumerator impl --------*- C++ -*-==//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMGLOBALS_H
10 #define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMGLOBALS_H
11
12 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
13 #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
14 #include "llvm/DebugInfo/PDB/PDBSymbol.h"
15
16 #include
17
18 namespace llvm {
19 namespace pdb {
20
21 class NativeSession;
22
23 class NativeEnumGlobals : public IPDBEnumChildren {
24 public:
25 NativeEnumGlobals(NativeSession &Session,
26 std::vector Kinds);
27
28 uint32_t getChildCount() const override;
29 std::unique_ptr getChildAtIndex(uint32_t Index) const override;
30 std::unique_ptr getNext() override;
31 void reset() override;
32
33 private:
34 std::vector MatchOffsets;
35 uint32_t Index;
36 NativeSession &Session;
37 };
38
39 } // namespace pdb
40 } // namespace llvm
41
42 #endif
0 //===- NativeTypeTypedef.h - info about typedef ------------------*- C++-*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPETYPEDEF_H
10 #define LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPETYPEDEF_H
11
12 #include "llvm/DebugInfo/CodeView/CodeView.h"
13 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
14 #include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
15 #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
16
17 namespace llvm {
18 namespace pdb {
19
20 class NativeTypeTypedef : public NativeRawSymbol {
21 public:
22 // Create a pointer record for a non-simple type.
23 NativeTypeTypedef(NativeSession &Session, SymIndexId Id,
24 codeview::UDTSym Typedef);
25
26 ~NativeTypeTypedef() override;
27
28 void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields,
29 PdbSymbolIdField RecurseIdFields) const override;
30
31 std::string getName() const override;
32 SymIndexId getTypeId() const override;
33
34 protected:
35 codeview::UDTSym Record;
36 };
37
38 } // namespace pdb
39 } // namespace llvm
40
41 #endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEPOINTER_H
4242 } // namespace pdb
4343 } // namespace llvm
4444
45 #endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEPOINTER_H
45 #endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEVTSHAPE_H
2828 NativeSession &Session;
2929 DbiStream *Dbi = nullptr;
3030
31 /// Cache of all stable symbols, indexed by SymIndexId. Just because a
32 /// symbol has been parsed does not imply that it will be stable and have
33 /// an Id. Id allocation is an implementation, with the only guarantee
34 /// being that once an Id is allocated, the symbol can be assumed to be
35 /// cached.
3136 std::vector> Cache;
37
38 /// For type records from the TPI stream which have been paresd and cached,
39 /// stores a mapping to SymIndexId of the cached symbol.
3240 DenseMap TypeIndexToSymbolId;
41
42 /// For field list members which have been parsed and cached, stores a mapping
43 /// from (IndexOfClass, MemberIndex) to the corresponding SymIndexId of the
44 /// cached symbol.
3345 DenseMap, SymIndexId>
3446 FieldListMembersToSymbolId;
47
48 /// List of SymIndexIds for each compiland, indexed by compiland index as they
49 /// appear in the PDB file.
3550 std::vector Compilands;
51
52 /// Map from global symbol offset to SymIndexId.
53 DenseMap GlobalOffsetToSymbolId;
3654
3755 SymIndexId createSymbolPlaceholder() {
3856 SymIndexId Id = Cache.size();
88106 std::unique_ptr
89107 createTypeEnumerator(std::vector Kinds);
90108
109 std::unique_ptr
110 createGlobalsEnumerator(codeview::SymbolKind Kind);
111
91112 SymIndexId findSymbolByTypeIndex(codeview::TypeIndex TI);
92113
93114 template
104125 SymId = Result.first->second;
105126 return SymId;
106127 }
128
129 SymIndexId getOrCreateGlobalSymbolByOffset(uint32_t Offset);
107130
108131 std::unique_ptr getOrCreateCompiland(uint32_t Index);
109132 uint32_t getNumCompilands() const;
4646 Native/InfoStreamBuilder.cpp
4747 Native/ModuleDebugStream.cpp
4848 Native/NativeCompilandSymbol.cpp
49 Native/NativeEnumGlobals.cpp
4950 Native/NativeEnumModules.cpp
5051 Native/NativeEnumTypes.cpp
5152 Native/NativeExeSymbol.cpp
5657 Native/NativeTypeEnum.cpp
5758 Native/NativeTypeFunctionSig.cpp
5859 Native/NativeTypePointer.cpp
60 Native/NativeTypeTypedef.cpp
5961 Native/NativeTypeUDT.cpp
6062 Native/NativeTypeVTShape.cpp
6163 Native/NamedStreamMap.cpp
0 //==- NativeEnumGlobals.cpp - Native Global Enumerator impl ------*- C++ -*-==//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/DebugInfo/PDB/Native/NativeEnumGlobals.h"
10
11 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
12 #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
13 #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
14 #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
15 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
16 #include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
17 #include "llvm/DebugInfo/PDB/PDBSymbol.h"
18
19 using namespace llvm;
20 using namespace llvm::codeview;
21 using namespace llvm::pdb;
22
23 NativeEnumGlobals::NativeEnumGlobals(NativeSession &PDBSession,
24 std::vector Kinds)
25 : Index(0), Session(PDBSession) {
26 GlobalsStream &GS = cantFail(Session.getPDBFile().getPDBGlobalsStream());
27 SymbolStream &SS = cantFail(Session.getPDBFile().getPDBSymbolStream());
28 for (uint32_t Off : GS.getGlobalsTable()) {
29 CVSymbol S = SS.readRecord(Off);
30 if (!llvm::is_contained(Kinds, S.kind()))
31 continue;
32 MatchOffsets.push_back(Off);
33 }
34 }
35
36 uint32_t NativeEnumGlobals::getChildCount() const {
37 return static_cast(MatchOffsets.size());
38 }
39
40 std::unique_ptr
41 NativeEnumGlobals::getChildAtIndex(uint32_t N) const {
42 if (N >= MatchOffsets.size())
43 return nullptr;
44
45 SymIndexId Id =
46 Session.getSymbolCache().getOrCreateGlobalSymbolByOffset(MatchOffsets[N]);
47 return Session.getSymbolCache().getSymbolById(Id);
48 }
49
50 std::unique_ptr NativeEnumGlobals::getNext() {
51 return getChildAtIndex(Index++);
52 }
53
54 void NativeEnumGlobals::reset() { Index = 0; }
5555 case PDB_SymType::FunctionSig:
5656 return Session.getSymbolCache().createTypeEnumerator(
5757 {codeview::LF_PROCEDURE, codeview::LF_MFUNCTION});
58 case PDB_SymType::Typedef:
59 return Session.getSymbolCache().createGlobalsEnumerator(codeview::S_UDT);
5860
5961 default:
6062 break;
0 #include "llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h"
1
2 using namespace llvm;
3 using namespace llvm::codeview;
4 using namespace llvm::pdb;
5
6 NativeTypeTypedef::NativeTypeTypedef(NativeSession &Session, SymIndexId Id,
7 codeview::UDTSym Typedef)
8 : NativeRawSymbol(Session, PDB_SymType::Typedef, Id),
9 Record(std::move(Typedef)) {}
10
11 NativeTypeTypedef::~NativeTypeTypedef() {}
12
13 void NativeTypeTypedef::dump(raw_ostream &OS, int Indent,
14 PdbSymbolIdField ShowIdFields,
15 PdbSymbolIdField RecurseIdFields) const {
16 NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
17 dumpSymbolField(OS, "name", getName(), Indent);
18 dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
19 PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
20 }
21
22 std::string NativeTypeTypedef::getName() const { return Record.Name; }
23
24 SymIndexId NativeTypeTypedef::getTypeId() const {
25 return Session.getSymbolCache().findSymbolByTypeIndex(Record.Type);
26 }
0 #include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
11
2 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
23 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
34 #include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
45 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
6 #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
57 #include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
8 #include "llvm/DebugInfo/PDB/Native/NativeEnumGlobals.h"
69 #include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
710 #include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
811 #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
1114 #include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
1215 #include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h"
1316 #include "llvm/DebugInfo/PDB/Native/NativeTypePointer.h"
17 #include "llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h"
1418 #include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h"
1519 #include "llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h"
1620 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
21 #include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
1722 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
1823 #include "llvm/DebugInfo/PDB/PDBSymbol.h"
1924 #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
8489 new NativeEnumTypes(Session, Types, std::move(Kinds)));
8590 }
8691
92 std::unique_ptr
93 SymbolCache::createGlobalsEnumerator(codeview::SymbolKind Kind) {
94 return std::unique_ptr(
95 new NativeEnumGlobals(Session, {Kind}));
96 }
97
8798 SymIndexId SymbolCache::createSimpleType(TypeIndex Index,
8899 ModifierOptions Mods) {
89100 if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct)
246257 return Dbi->modules().getModuleCount();
247258 }
248259
260 SymIndexId SymbolCache::getOrCreateGlobalSymbolByOffset(uint32_t Offset) {
261 auto Iter = GlobalOffsetToSymbolId.find(Offset);
262 if (Iter != GlobalOffsetToSymbolId.end())
263 return Iter->second;
264
265 SymbolStream &SS = cantFail(Session.getPDBFile().getPDBSymbolStream());
266 CVSymbol CVS = SS.readRecord(Offset);
267 SymIndexId Id = 0;
268 switch (CVS.kind()) {
269 case SymbolKind::S_UDT: {
270 UDTSym US = cantFail(SymbolDeserializer::deserializeAs(CVS));
271 Id = createSymbol(std::move(US));
272 break;
273 }
274 default:
275 Id = createSymbolPlaceholder();
276 break;
277 }
278 if (Id != 0) {
279 assert(GlobalOffsetToSymbolId.count(Offset) == 0);
280 GlobalOffsetToSymbolId[Offset] = Id;
281 }
282
283 return Id;
284 }
285
249286 std::unique_ptr
250287 SymbolCache::getOrCreateCompiland(uint32_t Index) {
251288 if (!Dbi)
0 ; Test that the native PDB reader can enumerate typedefs. The output being
1 ; checked against is golden output generated by llvm-pdbutil without the
2 ; -native flag. Then we check that we generate the same output.
3
4 ; RUN: llvm-pdbutil pretty -native -typedefs %p/../Inputs/symbolformat.pdb \
5 ; RUN: | FileCheck -check-prefix=PRETTY %s
6
7 ; RUN: llvm-pdbutil diadump -native -typedefs %p/../Inputs/symbolformat.pdb \
8 ; RUN: | FileCheck -check-prefix=DUMP %s
9
10 PRETTY: Typedefs: (3 items)
11 PRETTY-NEXT: typedef int IntType
12 PRETTY-NEXT: typedef class A ClassAType
13 PRETTY-NEXT: typedef int[3] int_array
14
15 DUMP: {
16 DUMP-NEXT: symIndexId: 2
17 DUMP-NEXT: symTag: Typedef
18 DUMP-NEXT: name: IntType
19 DUMP-NEXT: typeId: 3
20 DUMP-NEXT: }
21 DUMP-NEXT: {
22 DUMP-NEXT: symIndexId: 4
23 DUMP-NEXT: symTag: Typedef
24 DUMP-NEXT: name: ClassAType
25 DUMP-NEXT: typeId: 5
26 DUMP-NEXT: }
27 DUMP-NEXT: {
28 DUMP-NEXT: symIndexId: 6
29 DUMP-NEXT: symTag: Typedef
30 DUMP-NEXT: name: int_array
31 DUMP-NEXT: typeId: 7
32 DUMP-NEXT: }
1515 ; GLOBALS_DATA-DAG: static volatile int* __restrict NS::p_data_member
1616
1717 ; QUALS: ---TYPES---
18 ; QUALS-DAG: typedef RankNArray
18 ; QUALS-DAG: typedef volatile int*[100][10] RankNArray
1919 ; QUALS-DAG: typedef long* __restrict RestrictTypedef
2020 ; QUALS: union Union
2121 ; QUALS-DAG: int* __restrict x_member
1111 #include "LinePrinter.h"
1212 #include "PrettyBuiltinDumper.h"
1313 #include "PrettyFunctionDumper.h"
14 #include "PrettyTypeDumper.h"
1415
1516 #include "llvm/DebugInfo/PDB/IPDBSession.h"
1617 #include "llvm/DebugInfo/PDB/PDBExtras.h"
3435 << Symbol.getName();
3536 }
3637
37 void TypedefDumper::dump(const PDBSymbolTypeArray &Symbol) {}
38 void TypedefDumper::dump(const PDBSymbolTypeArray &Symbol) {
39 TypeDumper Dumper(Printer);
40 Dumper.dump(Symbol);
41 }
3842
3943 void TypedefDumper::dump(const PDBSymbolTypeBuiltin &Symbol) {
4044 BuiltinDumper Dumper(Printer);
196196 cl::sub(DiaDumpSubcommand));
197197 static cl::opt VTShapes("vtshapes", cl::desc("Dump virtual table shapes"),
198198 cl::sub(DiaDumpSubcommand));
199 static cl::opt Typedefs("typedefs", cl::desc("Dump typedefs"),
200 cl::sub(DiaDumpSubcommand));
199201 } // namespace diadump
200202
201203 namespace pretty {
10261028 SymTypes.push_back(PDB_SymType::ArrayType);
10271029 if (opts::diadump::VTShapes)
10281030 SymTypes.push_back(PDB_SymType::VTableShape);
1031 if (opts::diadump::Typedefs)
1032 SymTypes.push_back(PDB_SymType::Typedef);
10291033 PdbSymbolIdField Ids = opts::diadump::NoSymIndexIds ? PdbSymbolIdField::None
10301034 : PdbSymbolIdField::All;
10311035