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"
22 using namespace llvm::codeview
;
24 Error VarStreamArrayExtractor
<CrossModuleImportItem
>::
25 operator()(BinaryStreamRef Stream
, uint32_t &Len
,
26 codeview::CrossModuleImportItem
&Item
) {
27 BinaryStreamReader
Reader(Stream
);
28 if (Reader
.bytesRemaining() < sizeof(CrossModuleImport
))
29 return make_error
<CodeViewError
>(
30 cv_error_code::insufficient_buffer
,
31 "Not enough bytes for a Cross Module Import Header!");
32 if (auto EC
= Reader
.readObject(Item
.Header
))
34 if (Reader
.bytesRemaining() < Item
.Header
->Count
* sizeof(uint32_t))
35 return make_error
<CodeViewError
>(
36 cv_error_code::insufficient_buffer
,
37 "Not enough to read specified number of Cross Module References!");
38 if (auto EC
= Reader
.readArray(Item
.Imports
, Item
.Header
->Count
))
40 return Error::success();
43 Error
DebugCrossModuleImportsSubsectionRef::initialize(
44 BinaryStreamReader Reader
) {
45 return Reader
.readArray(References
, Reader
.bytesRemaining());
48 Error
DebugCrossModuleImportsSubsectionRef::initialize(BinaryStreamRef Stream
) {
49 BinaryStreamReader
Reader(Stream
);
50 return initialize(Reader
);
53 void DebugCrossModuleImportsSubsection::addImport(StringRef Module
,
55 Strings
.insert(Module
);
56 std::vector
<support::ulittle32_t
> Targets
= {support::ulittle32_t(ImportId
)};
57 auto Result
= Mappings
.insert(std::make_pair(Module
, Targets
));
59 Result
.first
->getValue().push_back(Targets
[0]);
62 uint32_t DebugCrossModuleImportsSubsection::calculateSerializedSize() const {
64 for (const auto &Item
: Mappings
) {
65 Size
+= sizeof(CrossModuleImport
);
66 Size
+= sizeof(support::ulittle32_t
) * Item
.second
.size();
71 Error
DebugCrossModuleImportsSubsection::commit(
72 BinaryStreamWriter
&Writer
) const {
73 using T
= decltype(&*Mappings
.begin());
75 Ids
.reserve(Mappings
.size());
77 for (const auto &M
: Mappings
)
80 llvm::sort(Ids
, [this](const T
&L1
, const T
&L2
) {
81 return Strings
.getIdForString(L1
->getKey()) <
82 Strings
.getIdForString(L2
->getKey());
85 for (const auto &Item
: Ids
) {
86 CrossModuleImport Imp
;
87 Imp
.ModuleNameOffset
= Strings
.getIdForString(Item
->getKey());
88 Imp
.Count
= Item
->getValue().size();
89 if (auto EC
= Writer
.writeObject(Imp
))
91 if (auto EC
= Writer
.writeArray(ArrayRef(Item
->getValue())))
94 return Error::success();