1 //===- DebugCrossImpSubsection.cpp ----------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h"
11 #include "llvm/ADT/ArrayRef.h"
12 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
13 #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
14 #include "llvm/Support/BinaryStreamReader.h"
15 #include "llvm/Support/BinaryStreamWriter.h"
16 #include "llvm/Support/Endian.h"
17 #include "llvm/Support/Error.h"
24 using namespace llvm::codeview
;
26 Error VarStreamArrayExtractor
<CrossModuleImportItem
>::
27 operator()(BinaryStreamRef Stream
, uint32_t &Len
,
28 codeview::CrossModuleImportItem
&Item
) {
29 BinaryStreamReader
Reader(Stream
);
30 if (Reader
.bytesRemaining() < sizeof(CrossModuleImport
))
31 return make_error
<CodeViewError
>(
32 cv_error_code::insufficient_buffer
,
33 "Not enough bytes for a Cross Module Import Header!");
34 if (auto EC
= Reader
.readObject(Item
.Header
))
36 if (Reader
.bytesRemaining() < Item
.Header
->Count
* sizeof(uint32_t))
37 return make_error
<CodeViewError
>(
38 cv_error_code::insufficient_buffer
,
39 "Not enough to read specified number of Cross Module References!");
40 if (auto EC
= Reader
.readArray(Item
.Imports
, Item
.Header
->Count
))
42 return Error::success();
45 Error
DebugCrossModuleImportsSubsectionRef::initialize(
46 BinaryStreamReader Reader
) {
47 return Reader
.readArray(References
, Reader
.bytesRemaining());
50 Error
DebugCrossModuleImportsSubsectionRef::initialize(BinaryStreamRef Stream
) {
51 BinaryStreamReader
Reader(Stream
);
52 return initialize(Reader
);
55 void DebugCrossModuleImportsSubsection::addImport(StringRef Module
,
57 Strings
.insert(Module
);
58 std::vector
<support::ulittle32_t
> Targets
= {support::ulittle32_t(ImportId
)};
59 auto Result
= Mappings
.insert(std::make_pair(Module
, Targets
));
61 Result
.first
->getValue().push_back(Targets
[0]);
64 uint32_t DebugCrossModuleImportsSubsection::calculateSerializedSize() const {
66 for (const auto &Item
: Mappings
) {
67 Size
+= sizeof(CrossModuleImport
);
68 Size
+= sizeof(support::ulittle32_t
) * Item
.second
.size();
73 Error
DebugCrossModuleImportsSubsection::commit(
74 BinaryStreamWriter
&Writer
) const {
75 using T
= decltype(&*Mappings
.begin());
77 Ids
.reserve(Mappings
.size());
79 for (const auto &M
: Mappings
)
82 llvm::sort(Ids
, [this](const T
&L1
, const T
&L2
) {
83 return Strings
.getIdForString(L1
->getKey()) <
84 Strings
.getIdForString(L2
->getKey());
87 for (const auto &Item
: Ids
) {
88 CrossModuleImport Imp
;
89 Imp
.ModuleNameOffset
= Strings
.getIdForString(Item
->getKey());
90 Imp
.Count
= Item
->getValue().size();
91 if (auto EC
= Writer
.writeObject(Imp
))
93 if (auto EC
= Writer
.writeArray(makeArrayRef(Item
->getValue())))
96 return Error::success();