Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp
35271 views
1
//===- DebugCrossImpSubsection.cpp ----------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h"
10
#include "llvm/ADT/ArrayRef.h"
11
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
12
#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
13
#include "llvm/Support/BinaryStreamReader.h"
14
#include "llvm/Support/BinaryStreamWriter.h"
15
#include "llvm/Support/Endian.h"
16
#include "llvm/Support/Error.h"
17
#include <algorithm>
18
#include <cstdint>
19
#include <utility>
20
#include <vector>
21
22
using namespace llvm;
23
using namespace llvm::codeview;
24
25
Error VarStreamArrayExtractor<CrossModuleImportItem>::
26
operator()(BinaryStreamRef Stream, uint32_t &Len,
27
codeview::CrossModuleImportItem &Item) {
28
BinaryStreamReader Reader(Stream);
29
if (Reader.bytesRemaining() < sizeof(CrossModuleImport))
30
return make_error<CodeViewError>(
31
cv_error_code::insufficient_buffer,
32
"Not enough bytes for a Cross Module Import Header!");
33
if (auto EC = Reader.readObject(Item.Header))
34
return EC;
35
if (Reader.bytesRemaining() < Item.Header->Count * sizeof(uint32_t))
36
return make_error<CodeViewError>(
37
cv_error_code::insufficient_buffer,
38
"Not enough to read specified number of Cross Module References!");
39
if (auto EC = Reader.readArray(Item.Imports, Item.Header->Count))
40
return EC;
41
return Error::success();
42
}
43
44
Error DebugCrossModuleImportsSubsectionRef::initialize(
45
BinaryStreamReader Reader) {
46
return Reader.readArray(References, Reader.bytesRemaining());
47
}
48
49
Error DebugCrossModuleImportsSubsectionRef::initialize(BinaryStreamRef Stream) {
50
BinaryStreamReader Reader(Stream);
51
return initialize(Reader);
52
}
53
54
void DebugCrossModuleImportsSubsection::addImport(StringRef Module,
55
uint32_t ImportId) {
56
Strings.insert(Module);
57
std::vector<support::ulittle32_t> Targets = {support::ulittle32_t(ImportId)};
58
auto Result = Mappings.insert(std::make_pair(Module, Targets));
59
if (!Result.second)
60
Result.first->getValue().push_back(Targets[0]);
61
}
62
63
uint32_t DebugCrossModuleImportsSubsection::calculateSerializedSize() const {
64
uint32_t Size = 0;
65
for (const auto &Item : Mappings) {
66
Size += sizeof(CrossModuleImport);
67
Size += sizeof(support::ulittle32_t) * Item.second.size();
68
}
69
return Size;
70
}
71
72
Error DebugCrossModuleImportsSubsection::commit(
73
BinaryStreamWriter &Writer) const {
74
using T = decltype(&*Mappings.begin());
75
std::vector<T> Ids;
76
Ids.reserve(Mappings.size());
77
78
for (const auto &M : Mappings)
79
Ids.push_back(&M);
80
81
llvm::sort(Ids, [this](const T &L1, const T &L2) {
82
return Strings.getIdForString(L1->getKey()) <
83
Strings.getIdForString(L2->getKey());
84
});
85
86
for (const auto &Item : Ids) {
87
CrossModuleImport Imp;
88
Imp.ModuleNameOffset = Strings.getIdForString(Item->getKey());
89
Imp.Count = Item->getValue().size();
90
if (auto EC = Writer.writeObject(Imp))
91
return EC;
92
if (auto EC = Writer.writeArray(ArrayRef(Item->getValue())))
93
return EC;
94
}
95
return Error::success();
96
}
97
98