llvm.org GIT mirror llvm / 5c238d6
[codeview] Fix YAML for LF_TYPESERVER2 by hoisting PDB_UniqueId Summary: We were treating the GUIDs in TypeServer2Record as strings, and the non-ASCII bytes in the GUID would not round-trip through YAML. We already had the PDB_UniqueId type portably represent a Windows GUID, but we need to hoist that up to the DebugInfo/CodeView library so that we can use it in the TypeServer2Record as well as in PDB parsing code. Reviewers: inglorion, amccarth Subscribers: llvm-commits, hiraditya Differential Revision: https://reviews.llvm.org/D35495 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@308234 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Kleckner 2 years ago
28 changed file(s) with 183 addition(s) and 102 deletion(s). Raw diff Collapse all Expand all
8383 Error mapEncodedInteger(uint64_t &Value);
8484 Error mapEncodedInteger(APSInt &Value);
8585 Error mapStringZ(StringRef &Value);
86 Error mapGuid(StringRef &Guid);
86 Error mapGuid(GUID &Guid);
8787
8888 Error mapStringZVectorZ(std::vector &Value);
8989
1111
1212 #include "llvm/ADT/ArrayRef.h"
1313 #include "llvm/ADT/StringRef.h"
14 #include "llvm/DebugInfo/CodeView/GUID.h"
1415 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
1516 #include "llvm/Support/FormatAdapters.h"
1617 #include "llvm/Support/FormatVariadic.h"
3031 explicit GuidAdapter(ArrayRef Guid);
3132 explicit GuidAdapter(StringRef Guid);
3233
33 void format(raw_ostream &Stream, StringRef Style) override ;
34 void format(raw_ostream &Stream, StringRef Style) override;
3435 };
3536
3637 } // end namespace detail
5960 }
6061 };
6162
63 template <> struct format_provider {
64 static void format(const codeview::GUID &V, llvm::raw_ostream &Stream,
65 StringRef Style) {
66 Stream << V;
67 }
68 };
69
6270 } // end namespace llvm
6371
6472 #endif // LLVM_DEBUGINFO_CODEVIEW_FORMATTERS_H
0 //===- GUID.h ---------------------------------------------------*- 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_CODEVIEW_GUID_H
10 #define LLVM_DEBUGINFO_CODEVIEW_GUID_H
11
12 #include
13 #include
14
15 namespace llvm {
16 class raw_ostream;
17
18 namespace codeview {
19
20 /// This represents the 'GUID' type from windows.h.
21 struct GUID {
22 uint8_t Guid[16];
23 };
24
25 inline bool operator==(const GUID &LHS, const GUID &RHS) {
26 return 0 == ::memcmp(LHS.Guid, RHS.Guid, sizeof(LHS.Guid));
27 }
28
29 raw_ostream &operator<<(raw_ostream &OS, const GUID &Guid);
30
31 } // namespace codeview
32 } // namespace llvm
33
34 #endif
1717 #include "llvm/ADT/iterator_range.h"
1818 #include "llvm/DebugInfo/CodeView/CVRecord.h"
1919 #include "llvm/DebugInfo/CodeView/CodeView.h"
20 #include "llvm/DebugInfo/CodeView/GUID.h"
2021 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
2122 #include "llvm/Support/BinaryStreamArray.h"
2223 #include "llvm/Support/Endian.h"
538539 public:
539540 TypeServer2Record() = default;
540541 explicit TypeServer2Record(TypeRecordKind Kind) : TypeRecord(Kind) {}
541 TypeServer2Record(StringRef Guid, uint32_t Age, StringRef Name)
542 : TypeRecord(TypeRecordKind::TypeServer2), Guid(Guid), Age(Age),
543 Name(Name) {}
544
545 StringRef getGuid() const { return Guid; }
542 TypeServer2Record(StringRef GuidStr, uint32_t Age, StringRef Name)
543 : TypeRecord(TypeRecordKind::TypeServer2), Age(Age), Name(Name) {
544 assert(GuidStr.size() == 16 && "guid isn't 16 bytes");
545 ::memcpy(Guid.Guid, GuidStr.data(), 16);
546 }
547
548 const GUID &getGuid() const { return Guid; }
546549 uint32_t getAge() const { return Age; }
547550 StringRef getName() const { return Name; }
548551
549 StringRef Guid;
552 GUID Guid;
550553 uint32_t Age;
551554 StringRef Name;
552555 };
105105 getVirtualBaseTableType() const override;
106106 PDB_DataKind getDataKind() const override;
107107 PDB_SymType getSymTag() const override;
108 PDB_UniqueId getGuid() const override;
108 codeview::GUID getGuid() const override;
109109 int32_t getOffset() const override;
110110 int32_t getThisAdjust() const override;
111111 int32_t getVirtualBasePointerOffset() const override;
117117 virtual uint32_t getVirtualTableShapeId() const = 0;
118118 virtual PDB_DataKind getDataKind() const = 0;
119119 virtual PDB_SymType getSymTag() const = 0;
120 virtual PDB_UniqueId getGuid() const = 0;
120 virtual codeview::GUID getGuid() const = 0;
121121 virtual int32_t getOffset() const = 0;
122122 virtual int32_t getThisAdjust() const = 0;
123123 virtual int32_t getVirtualBasePointerOffset() const = 0;
2222 break;
2323
2424 namespace llvm {
25 template <> struct format_provider {
26 static void format(const pdb::PDB_UniqueId &V, llvm::raw_ostream &Stream,
27 StringRef Style) {
28 codeview::fmt_guid(V.Guid).format(Stream, Style);
29 }
30 };
31
3225 template <> struct format_provider {
3326 static void format(const pdb::PdbRaw_ImplVer &V, llvm::raw_ostream &Stream,
3427 StringRef Style) {
1111
1212 #include "llvm/ADT/BitmaskEnum.h"
1313 #include "llvm/ADT/StringMap.h"
14 #include "llvm/DebugInfo/CodeView/GUID.h"
1415 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
1516 #include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h"
1617 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
3839 PdbRaw_ImplVer getVersion() const;
3940 uint32_t getSignature() const;
4041 uint32_t getAge() const;
41 PDB_UniqueId getGuid() const;
42 codeview::GUID getGuid() const;
4243 uint32_t getNamedStreamMapByteSize() const;
4344
4445 PdbRaw_Features getFeatures() const;
7071 // Due to the aforementioned limitations with `Signature`, this is a new
7172 // signature present on VC70 and higher PDBs which is guaranteed to be
7273 // universally unique.
73 PDB_UniqueId Guid;
74 codeview::GUID Guid;
7475
7576 BinarySubstreamRef SubNamedStreams;
7677
3636 void setVersion(PdbRaw_ImplVer V);
3737 void setSignature(uint32_t S);
3838 void setAge(uint32_t A);
39 void setGuid(PDB_UniqueId G);
39 void setGuid(codeview::GUID G);
4040 void addFeature(PdbRaw_FeatureSig Sig);
4141
4242 uint32_t finalize();
5353 PdbRaw_ImplVer Ver;
5454 uint32_t Sig;
5555 uint32_t Age;
56 PDB_UniqueId Guid;
56 codeview::GUID Guid;
5757
5858 NamedStreamMap &NamedStreams;
5959 };
2626
2727 uint32_t getAge() const override;
2828 std::string getSymbolsFileName() const override;
29 PDB_UniqueId getGuid() const override;
29 codeview::GUID getGuid() const override;
3030 bool hasCTypes() const override;
3131 bool hasPrivateSymbols() const override;
3232
110110 getVirtualBaseTableType() const override;
111111 PDB_DataKind getDataKind() const override;
112112 PDB_SymType getSymTag() const override;
113 PDB_UniqueId getGuid() const override;
113 codeview::GUID getGuid() const override;
114114 int32_t getOffset() const override;
115115 int32_t getThisAdjust() const override;
116116 int32_t getVirtualBasePointerOffset() const override;
99 #ifndef LLVM_DEBUGINFO_PDB_RAW_RAWTYPES_H
1010 #define LLVM_DEBUGINFO_PDB_RAW_RAWTYPES_H
1111
12 #include "llvm/DebugInfo/CodeView/GUID.h"
1213 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
1314 #include "llvm/Support/Endian.h"
1415
267268 support::ulittle32_t NumSections;
268269 };
269270
270 /// Defines a 128-bit unique identifier. This maps to a GUID on Windows, but
271 /// is abstracted here for the purposes of non-Windows platforms that don't have
272 /// the GUID structure defined.
273 struct PDB_UniqueId {
274 uint8_t Guid[16];
275 };
276
277 inline bool operator==(const PDB_UniqueId &LHS, const PDB_UniqueId &RHS) {
278 return 0 == ::memcmp(LHS.Guid, RHS.Guid, sizeof(LHS.Guid));
279 }
280
281271 // The header preceeding the global TPI stream.
282272 // This corresponds to `HDR` in PDB/dbi/tpi.h.
283273 struct TpiStreamHeader {
311301 support::ulittle32_t Version;
312302 support::ulittle32_t Signature;
313303 support::ulittle32_t Age;
314 PDB_UniqueId Guid;
304 codeview::GUID Guid;
315305 };
316306
317307 /// The header preceeding the /names stream.
3131 raw_ostream &operator<<(raw_ostream &OS, const PDB_Lang &Lang);
3232 raw_ostream &operator<<(raw_ostream &OS, const PDB_SymType &Tag);
3333 raw_ostream &operator<<(raw_ostream &OS, const PDB_MemberAccess &Access);
34 raw_ostream &operator<<(raw_ostream &OS, const PDB_UniqueId &Guid);
3534 raw_ostream &operator<<(raw_ostream &OS, const PDB_UdtType &Type);
3635 raw_ostream &operator<<(raw_ostream &OS, const PDB_Machine &Machine);
3736
5959
6060 } // end namespace llvm
6161
62 LLVM_YAML_DECLARE_SCALAR_TRAITS(codeview::GUID, true)
63
6264 LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::LeafRecord)
6365 LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::MemberRecord)
6466
167167 return Error::success();
168168 }
169169
170 Error CodeViewRecordIO::mapGuid(StringRef &Guid) {
170 Error CodeViewRecordIO::mapGuid(GUID &Guid) {
171171 constexpr uint32_t GuidSize = 16;
172172 if (maxFieldLength() < GuidSize)
173173 return make_error(cv_error_code::insufficient_buffer);
174174
175175 if (isWriting()) {
176 assert(Guid.size() == 16 && "Invalid Guid Size!");
177 if (auto EC = Writer->writeFixedString(Guid))
178 return EC;
179 } else {
180 if (auto EC = Reader->readFixedString(Guid, 16))
181 return EC;
176 if (auto EC = Writer->writeBytes(Guid.Guid))
177 return EC;
178 } else {
179 ArrayRef GuidBytes;
180 if (auto EC = Reader->readBytes(GuidBytes, GuidSize))
181 return EC;
182 memcpy(Guid.Guid, GuidBytes.data(), GuidSize);
182183 }
183184 return Error::success();
184185 }
88
99 #include "llvm/DebugInfo/CodeView/Formatters.h"
1010 #include "llvm/ADT/ArrayRef.h"
11 #include "llvm/DebugInfo/CodeView/GUID.h"
1112 #include "llvm/Support/raw_ostream.h"
1213 #include
1314 #include
3839 }
3940 Stream << "}";
4041 }
42
43 raw_ostream &llvm::codeview::operator<<(raw_ostream &OS, const GUID &Guid) {
44 codeview::detail::GuidAdapter A(Guid.Guid);
45 A.format(OS, "");
46 return OS;
47 }
353353 }
354354
355355 Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, TypeServer2Record &TS) {
356 W->printString("Guid", formatv("{0}", fmt_guid(TS.getGuid())).str());
356 W->printString("Guid", formatv("{0}", TS.getGuid()).str());
357357 W->printNumber("Age", TS.getAge());
358358 W->printString("Name", TS.getName());
359359 return Error::success();
124124 return Result8;
125125 }
126126
127 PDB_UniqueId
127 codeview::GUID
128128 PrivateGetDIAValue(IDiaSymbol *Symbol,
129129 HRESULT (__stdcall IDiaSymbol::*Method)(GUID *)) {
130130 GUID Result;
131131 if (S_OK != (Symbol->*Method)(&Result))
132 return PDB_UniqueId();
133
134 static_assert(sizeof(PDB_UniqueId) == sizeof(GUID),
135 "PDB_UniqueId is the wrong size!");
136 PDB_UniqueId IdResult;
132 return codeview::GUID();
133
134 static_assert(sizeof(codeview::GUID) == sizeof(GUID),
135 "GUID is the wrong size!");
136 codeview::GUID IdResult;
137137 ::memcpy(&IdResult, &Result, sizeof(GUID));
138138 return IdResult;
139139 }
745745 &IDiaSymbol::get_symTag);
746746 }
747747
748 PDB_UniqueId DIARawSymbol::getGuid() const {
748 codeview::GUID DIARawSymbol::getGuid() const {
749749 return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_guid);
750750 }
751751
117117
118118 uint32_t InfoStream::getAge() const { return Age; }
119119
120 PDB_UniqueId InfoStream::getGuid() const { return Guid; }
120 GUID InfoStream::getGuid() const { return Guid; }
121121
122122 uint32_t InfoStream::getNamedStreamMapByteSize() const {
123123 return NamedStreamMapByteSize;
3333
3434 void InfoStreamBuilder::setAge(uint32_t A) { Age = A; }
3535
36 void InfoStreamBuilder::setGuid(PDB_UniqueId G) { Guid = G; }
36 void InfoStreamBuilder::setGuid(GUID G) { Guid = G; }
3737
3838 void InfoStreamBuilder::addFeature(PdbRaw_FeatureSig Sig) {
3939 Features.push_back(Sig);
5555 return File.getFilePath();
5656 }
5757
58 PDB_UniqueId NativeExeSymbol::getGuid() const {
58 codeview::GUID NativeExeSymbol::getGuid() const {
5959 auto IS = File.getPDBInfoStream();
6060 if (IS)
6161 return IS->getGuid();
6262 consumeError(IS.takeError());
63 return PDB_UniqueId{{0}};
63 return codeview::GUID{{0}};
6464 }
6565
6666 bool NativeExeSymbol::hasCTypes() const {
322322 return PDB_SymType::None;
323323 }
324324
325 PDB_UniqueId NativeRawSymbol::getGuid() const {
326 return PDB_UniqueId{{0}};
327 }
325 codeview::GUID NativeRawSymbol::getGuid() const { return codeview::GUID{{0}}; }
328326
329327 int32_t NativeRawSymbol::getOffset() const {
330328 return 0;
259259 return OS;
260260 }
261261
262 raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_UniqueId &Guid) {
263 codeview::detail::GuidAdapter A(Guid.Guid);
264 A.format(OS, "");
265 return OS;
266 }
267
268262 raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_UdtType &Type) {
269263 switch (Type) {
270264 CASE_OUTPUT_ENUM_CLASS_STR(PDB_UdtType, Class, "class", OS)
139139 } // end namespace detail
140140 } // end namespace CodeViewYAML
141141 } // end namespace llvm
142
143 void ScalarTraits::output(const GUID &G, void *, llvm::raw_ostream &OS) {
144 OS << G;
145 }
146
147 StringRef ScalarTraits::input(StringRef Scalar, void *Ctx, GUID &S) {
148 if (Scalar.size() != 38)
149 return "GUID strings are 38 characters long";
150 if (Scalar[0] != '{' || Scalar[37] != '}')
151 return "GUID is not enclosed in {}";
152 if (Scalar[9] != '-' || Scalar[14] != '-' || Scalar[19] != '-' ||
153 Scalar[24] != '-')
154 return "GUID sections are not properly delineated with dashes";
155
156 uint8_t *OutBuffer = S.Guid;
157 for (auto Iter = Scalar.begin(); Iter != Scalar.end();) {
158 if (*Iter == '-' || *Iter == '{' || *Iter == '}') {
159 ++Iter;
160 continue;
161 }
162 uint8_t Value = (llvm::hexDigitValue(*Iter++) << 4);
163 Value |= llvm::hexDigitValue(*Iter++);
164 *OutBuffer++ = Value;
165 }
166
167 return "";
168 }
142169
143170 void ScalarTraits::output(const TypeIndex &S, void *,
144171 raw_ostream &OS) {
0 # RUN: yaml2obj %s | obj2yaml | FileCheck %s
1
2 --- !COFF
3 header:
4 Machine: IMAGE_FILE_MACHINE_AMD64
5 Characteristics: [ ]
6 sections:
7 - Name: '.debug$T'
8 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
9 Alignment: 1
10 Types:
11 - Kind: LF_TYPESERVER2
12 TypeServer2:
13 Guid: '{01DF191B-22BF-6B42-96CE-5258B8329FE5}'
14 Age: 24
15 Name: 'C:\src\llvm-project\build\vc140.pdb'
16 symbols:
17 - Name: '.debug$T'
18 Value: 0
19 SectionNumber: 1
20 SimpleType: IMAGE_SYM_TYPE_NULL
21 ComplexType: IMAGE_SYM_DTYPE_NULL
22 StorageClass: IMAGE_SYM_CLASS_STATIC
23 SectionDefinition:
24 Length: 64
25 NumberOfRelocations: 0
26 NumberOfLinenumbers: 0
27 CheckSum: 0
28 Number: 0
29 ...
30
31 # CHECK: --- !COFF
32 # CHECK: header:
33 # CHECK: Machine: IMAGE_FILE_MACHINE_AMD64
34 # CHECK: Characteristics: [ ]
35 # CHECK: sections:
36 # CHECK: - Name: '.debug$T'
37 # CHECK: Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
38 # CHECK: Alignment: 1
39 # CHECK: Types:
40 # CHECK: - Kind: LF_TYPESERVER2
41 # CHECK: TypeServer2:
42 # CHECK: Guid: '{01DF191B-22BF-6B42-96CE-5258B8329FE5}'
43 # CHECK: Age: 24
44 # CHECK: Name: 'C:\src\llvm-project\build\vc140.pdb'
45 # CHECK: symbols:
46 # CHECK: - Name: '.debug$T'
47 # CHECK: Value: 0
48 # CHECK: SectionNumber: 1
49 # CHECK: SimpleType: IMAGE_SYM_TYPE_NULL
50 # CHECK: ComplexType: IMAGE_SYM_DTYPE_NULL
51 # CHECK: StorageClass: IMAGE_SYM_CLASS_STATIC
52 # CHECK: SectionDefinition:
53 # CHECK: Length: 64
54 # CHECK: NumberOfRelocations: 0
55 # CHECK: NumberOfLinenumbers: 0
56 # CHECK: CheckSum: 0
57 # CHECK: Number: 0
58 # CHECK: ...
394394
395395 Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
396396 TypeServer2Record &TS) {
397 P.formatLine("name = {0}, age = {1}, guid = {2}", TS.Name, TS.Age,
398 fmt_guid(TS.Guid));
397 P.formatLine("name = {0}, age = {1}, guid = {2}", TS.Name, TS.Age, TS.Guid);
399398 return Error::success();
400399 }
401400
3636
3737 namespace llvm {
3838 namespace yaml {
39
40 template <> struct ScalarTraits {
41 static void output(const llvm::pdb::PDB_UniqueId &S, void *,
42 llvm::raw_ostream &OS) {
43 OS << S;
44 }
45
46 static StringRef input(StringRef Scalar, void *Ctx,
47 llvm::pdb::PDB_UniqueId &S) {
48 if (Scalar.size() != 38)
49 return "GUID strings are 38 characters long";
50 if (Scalar[0] != '{' || Scalar[37] != '}')
51 return "GUID is not enclosed in {}";
52 if (Scalar[9] != '-' || Scalar[14] != '-' || Scalar[19] != '-' ||
53 Scalar[24] != '-')
54 return "GUID sections are not properly delineated with dashes";
55
56 uint8_t *OutBuffer = S.Guid;
57 for (auto Iter = Scalar.begin(); Iter != Scalar.end();) {
58 if (*Iter == '-' || *Iter == '{' || *Iter == '}') {
59 ++Iter;
60 continue;
61 }
62 uint8_t Value = (llvm::hexDigitValue(*Iter) << 4);
63 ++Iter;
64 Value |= llvm::hexDigitValue(*Iter);
65 ++Iter;
66 *OutBuffer++ = Value;
67 }
68
69 return "";
70 }
71
72 static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
73 };
7439
7540 template <> struct ScalarEnumerationTraits {
7641 static void enumeration(IO &io, llvm::pdb::PDB_Machine &Value) {
5656 PdbRaw_ImplVer Version = PdbImplVC70;
5757 uint32_t Signature = 0;
5858 uint32_t Age = 1;
59 PDB_UniqueId Guid;
59 codeview::GUID Guid;
6060 std::vector Features;
6161 std::vector NamedStreams;
6262 };