1 //===- StringsAndChecksums.h ------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_DEBUGINFO_CODEVIEW_STRINGS_AND_CHECKSUMS_H 11 #define LLVM_DEBUGINFO_CODEVIEW_STRINGS_AND_CHECKSUMS_H 12 13 #include "llvm/DebugInfo/CodeView/CodeView.h" 14 #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" 15 16 #include <memory> 17 18 namespace llvm { 19 namespace codeview { 20 21 class DebugSubsectionRecord; 22 class DebugChecksumsSubsectionRef; 23 class DebugStringTableSubsectionRef; 24 class DebugChecksumsSubsection; 25 class DebugStringTableSubsection; 26 27 class StringsAndChecksumsRef { 28 public: 29 // If no subsections are known about initially, we find as much as we can. 30 StringsAndChecksumsRef(); 31 32 // If only a string table subsection is given, we find a checksums subsection. 33 explicit StringsAndChecksumsRef(const DebugStringTableSubsectionRef &Strings); 34 35 // If both subsections are given, we don't need to find anything. 36 StringsAndChecksumsRef(const DebugStringTableSubsectionRef &Strings, 37 const DebugChecksumsSubsectionRef &Checksums); 38 39 void setChecksums(const DebugChecksumsSubsectionRef &CS); 40 41 template <typename T> void initialize(T &&FragmentRange) { 42 for (const DebugSubsectionRecord &R : FragmentRange) { 43 if (Strings && Checksums) 44 return; 45 if (R.kind() == DebugSubsectionKind::FileChecksums) { 46 initializeChecksums(R); 47 continue; 48 } 49 if (R.kind() == DebugSubsectionKind::StringTable && !Strings) { 50 // While in practice we should never encounter a string table even 51 // though the string table is already initialized, in theory it's 52 // possible. PDBs are supposed to have one global string table and 53 // then this subsection should not appear. Whereas object files are 54 // supposed to have this subsection appear exactly once. However, 55 // for testing purposes it's nice to be able to test this subsection 56 // independently of one format or the other, so for some tests we 57 // manually construct a PDB that contains this subsection in addition 58 // to a global string table. 59 initializeStrings(R); 60 continue; 61 } 62 } 63 } 64 65 const DebugStringTableSubsectionRef &strings() const { return *Strings; } 66 const DebugChecksumsSubsectionRef &checksums() const { return *Checksums; } 67 68 bool hasStrings() const { return Strings != nullptr; } 69 bool hasChecksums() const { return Checksums != nullptr; } 70 71 private: 72 void initializeStrings(const DebugSubsectionRecord &SR); 73 void initializeChecksums(const DebugSubsectionRecord &FCR); 74 75 std::unique_ptr<DebugStringTableSubsectionRef> OwnedStrings; 76 std::unique_ptr<DebugChecksumsSubsectionRef> OwnedChecksums; 77 78 const DebugStringTableSubsectionRef *Strings = nullptr; 79 const DebugChecksumsSubsectionRef *Checksums = nullptr; 80 }; 81 82 class StringsAndChecksums { 83 public: 84 using StringsPtr = std::shared_ptr<DebugStringTableSubsection>; 85 using ChecksumsPtr = std::shared_ptr<DebugChecksumsSubsection>; 86 // If no subsections are known about initially, we find as much as we can. 87 StringsAndChecksums() {} 88 89 void setStrings(const StringsPtr &SP) { Strings = SP; } 90 void setChecksums(const ChecksumsPtr &CP) { Checksums = CP; } 91 92 const StringsPtr &strings() const { return Strings; } 93 const ChecksumsPtr &checksums() const { return Checksums; } 94 95 bool hasStrings() const { return Strings != nullptr; } 96 bool hasChecksums() const { return Checksums != nullptr; } 97 98 private: 99 StringsPtr Strings; 100 ChecksumsPtr Checksums; 101 }; 102 103 } // namespace codeview 104 } // namespace llvm 105 106 #endif 107