1 //===- DebugCrossImpSubsection.cpp ----------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
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"
23 using namespace llvm::codeview
;
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
))
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
))
41 return Error::success();
44 Error
DebugCrossModuleImportsSubsectionRef::initialize(
45 BinaryStreamReader Reader
) {
46 return Reader
.readArray(References
, Reader
.bytesRemaining());
49 Error
DebugCrossModuleImportsSubsectionRef::initialize(BinaryStreamRef Stream
) {
50 BinaryStreamReader
Reader(Stream
);
51 return initialize(Reader
);
54 void DebugCrossModuleImportsSubsection::addImport(StringRef Module
,
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
));
60 Result
.first
->getValue().push_back(Targets
[0]);
63 uint32_t DebugCrossModuleImportsSubsection::calculateSerializedSize() const {
65 for (const auto &Item
: Mappings
) {
66 Size
+= sizeof(CrossModuleImport
);
67 Size
+= sizeof(support::ulittle32_t
) * Item
.second
.size();
72 Error
DebugCrossModuleImportsSubsection::commit(
73 BinaryStreamWriter
&Writer
) const {
74 using T
= decltype(&*Mappings
.begin());
76 Ids
.reserve(Mappings
.size());
78 for (const auto &M
: Mappings
)
81 llvm::sort(Ids
, [this](const T
&L1
, const T
&L2
) {
82 return Strings
.getIdForString(L1
->getKey()) <
83 Strings
.getIdForString(L2
->getKey());
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
))
92 if (auto EC
= Writer
.writeArray(makeArrayRef(Item
->getValue())))
95 return Error::success();