Line data Source code
1 : //===- ModuleDebugFileChecksumFragment.cpp ----------------------*- 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 : #include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
11 :
12 : #include "llvm/DebugInfo/CodeView/CodeViewError.h"
13 : #include "llvm/DebugInfo/CodeView/StringTable.h"
14 : #include "llvm/Support/BinaryStreamReader.h"
15 :
16 : using namespace llvm;
17 : using namespace llvm::codeview;
18 :
19 2 : struct FileChecksumEntryHeader {
20 : using ulittle32_t = support::ulittle32_t;
21 :
22 : ulittle32_t FileNameOffset; // Byte offset of filename in global string table.
23 : uint8_t ChecksumSize; // Number of bytes of checksum.
24 : uint8_t ChecksumKind; // FileChecksumKind
25 : // Checksum bytes follow.
26 : };
27 :
28 249 : Error llvm::VarStreamArrayExtractor<FileChecksumEntry>::extract(
29 : BinaryStreamRef Stream, uint32_t &Len, FileChecksumEntry &Item) {
30 747 : BinaryStreamReader Reader(Stream);
31 :
32 : const FileChecksumEntryHeader *Header;
33 747 : if (auto EC = Reader.readObject(Header))
34 0 : return EC;
35 :
36 498 : Item.FileNameOffset = Header->FileNameOffset;
37 249 : Item.Kind = static_cast<FileChecksumKind>(Header->ChecksumKind);
38 747 : if (auto EC = Reader.readBytes(Item.Checksum, Header->ChecksumSize))
39 0 : return EC;
40 :
41 498 : Len = alignTo(Header->ChecksumSize + sizeof(FileChecksumEntryHeader), 4);
42 747 : return Error::success();
43 : }
44 :
45 68 : Error ModuleDebugFileChecksumFragmentRef::initialize(
46 : BinaryStreamReader Reader) {
47 204 : if (auto EC = Reader.readArray(Checksums, Reader.bytesRemaining()))
48 0 : return EC;
49 :
50 204 : return Error::success();
51 : }
52 :
53 1 : ModuleDebugFileChecksumFragment::ModuleDebugFileChecksumFragment(
54 1 : StringTable &Strings)
55 : : ModuleDebugFragment(ModuleDebugFragmentKind::FileChecksums),
56 5 : Strings(Strings) {}
57 :
58 2 : void ModuleDebugFileChecksumFragment::addChecksum(StringRef FileName,
59 : FileChecksumKind Kind,
60 : ArrayRef<uint8_t> Bytes) {
61 2 : FileChecksumEntry Entry;
62 2 : if (!Bytes.empty()) {
63 4 : uint8_t *Copy = Storage.Allocate<uint8_t>(Bytes.size());
64 2 : ::memcpy(Copy, Bytes.data(), Bytes.size());
65 4 : Entry.Checksum = makeArrayRef(Copy, Bytes.size());
66 : }
67 :
68 2 : Entry.FileNameOffset = Strings.insert(FileName);
69 2 : Entry.Kind = Kind;
70 2 : Checksums.push_back(Entry);
71 :
72 : // This maps the offset of this string in the string table to the offset
73 : // of this checksum entry in the checksum buffer.
74 4 : OffsetMap[Entry.FileNameOffset] = SerializedSize;
75 : assert(SerializedSize % 4 == 0);
76 :
77 4 : uint32_t Len = alignTo(sizeof(FileChecksumEntryHeader) + Bytes.size(), 4);
78 2 : SerializedSize += Len;
79 2 : }
80 :
81 3 : uint32_t ModuleDebugFileChecksumFragment::calculateSerializedLength() {
82 3 : return SerializedSize;
83 : }
84 :
85 1 : Error ModuleDebugFileChecksumFragment::commit(BinaryStreamWriter &Writer) {
86 6 : for (const auto &FC : Checksums) {
87 2 : FileChecksumEntryHeader Header;
88 2 : Header.ChecksumKind = uint8_t(FC.Kind);
89 2 : Header.ChecksumSize = FC.Checksum.size();
90 4 : Header.FileNameOffset = FC.FileNameOffset;
91 6 : if (auto EC = Writer.writeObject(Header))
92 0 : return EC;
93 8 : if (auto EC = Writer.writeArray(makeArrayRef(FC.Checksum)))
94 0 : return EC;
95 6 : if (auto EC = Writer.padToAlignment(4))
96 0 : return EC;
97 : }
98 3 : return Error::success();
99 : }
100 :
101 : uint32_t
102 2 : ModuleDebugFileChecksumFragment::mapChecksumOffset(StringRef FileName) const {
103 2 : uint32_t Offset = Strings.getStringId(FileName);
104 2 : auto Iter = OffsetMap.find(Offset);
105 : assert(Iter != OffsetMap.end());
106 2 : return Iter->second;
107 : }
|