1*349c18f8SZachary Turner //===- DebugCrossImpSubsection.cpp ------------------------------*- C++ -*-===// 2*349c18f8SZachary Turner // 3*349c18f8SZachary Turner // The LLVM Compiler Infrastructure 4*349c18f8SZachary Turner // 5*349c18f8SZachary Turner // This file is distributed under the University of Illinois Open Source 6*349c18f8SZachary Turner // License. See LICENSE.TXT for details. 7*349c18f8SZachary Turner // 8*349c18f8SZachary Turner //===----------------------------------------------------------------------===// 9*349c18f8SZachary Turner 10*349c18f8SZachary Turner #include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h" 11*349c18f8SZachary Turner 12*349c18f8SZachary Turner #include "llvm/DebugInfo/CodeView/CodeViewError.h" 13*349c18f8SZachary Turner #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" 14*349c18f8SZachary Turner 15*349c18f8SZachary Turner using namespace llvm; 16*349c18f8SZachary Turner using namespace llvm::codeview; 17*349c18f8SZachary Turner 18*349c18f8SZachary Turner namespace llvm { 19*349c18f8SZachary Turner Error VarStreamArrayExtractor<CrossModuleImportItem>::extract( 20*349c18f8SZachary Turner BinaryStreamRef Stream, uint32_t &Len, 21*349c18f8SZachary Turner codeview::CrossModuleImportItem &Item) { 22*349c18f8SZachary Turner BinaryStreamReader Reader(Stream); 23*349c18f8SZachary Turner if (Reader.bytesRemaining() < sizeof(CrossModuleImport)) 24*349c18f8SZachary Turner return make_error<CodeViewError>( 25*349c18f8SZachary Turner cv_error_code::insufficient_buffer, 26*349c18f8SZachary Turner "Not enough bytes for a Cross Module Import Header!"); 27*349c18f8SZachary Turner if (auto EC = Reader.readObject(Item.Header)) 28*349c18f8SZachary Turner return EC; 29*349c18f8SZachary Turner if (Reader.bytesRemaining() < Item.Header->Count * sizeof(uint32_t)) 30*349c18f8SZachary Turner return make_error<CodeViewError>( 31*349c18f8SZachary Turner cv_error_code::insufficient_buffer, 32*349c18f8SZachary Turner "Not enough to read specified number of Cross Module References!"); 33*349c18f8SZachary Turner if (auto EC = Reader.readArray(Item.Imports, Item.Header->Count)) 34*349c18f8SZachary Turner return EC; 35*349c18f8SZachary Turner return Error::success(); 36*349c18f8SZachary Turner } 37*349c18f8SZachary Turner } 38*349c18f8SZachary Turner 39*349c18f8SZachary Turner Error DebugCrossModuleImportsSubsectionRef::initialize( 40*349c18f8SZachary Turner BinaryStreamReader Reader) { 41*349c18f8SZachary Turner return Reader.readArray(References, Reader.bytesRemaining()); 42*349c18f8SZachary Turner } 43*349c18f8SZachary Turner 44*349c18f8SZachary Turner Error DebugCrossModuleImportsSubsectionRef::initialize(BinaryStreamRef Stream) { 45*349c18f8SZachary Turner BinaryStreamReader Reader(Stream); 46*349c18f8SZachary Turner return initialize(Reader); 47*349c18f8SZachary Turner } 48*349c18f8SZachary Turner 49*349c18f8SZachary Turner void DebugCrossModuleImportsSubsection::addImport(StringRef Module, 50*349c18f8SZachary Turner uint32_t ImportId) { 51*349c18f8SZachary Turner Strings.insert(Module); 52*349c18f8SZachary Turner std::vector<support::ulittle32_t> Targets = {support::ulittle32_t(ImportId)}; 53*349c18f8SZachary Turner auto Result = Mappings.insert(std::make_pair(Module, Targets)); 54*349c18f8SZachary Turner if (!Result.second) 55*349c18f8SZachary Turner Result.first->getValue().push_back(Targets[0]); 56*349c18f8SZachary Turner } 57*349c18f8SZachary Turner 58*349c18f8SZachary Turner uint32_t DebugCrossModuleImportsSubsection::calculateSerializedSize() const { 59*349c18f8SZachary Turner uint32_t Size = 0; 60*349c18f8SZachary Turner for (const auto &Item : Mappings) { 61*349c18f8SZachary Turner Size += sizeof(CrossModuleImport); 62*349c18f8SZachary Turner Size += sizeof(support::ulittle32_t) * Item.second.size(); 63*349c18f8SZachary Turner } 64*349c18f8SZachary Turner return Size; 65*349c18f8SZachary Turner } 66*349c18f8SZachary Turner 67*349c18f8SZachary Turner Error DebugCrossModuleImportsSubsection::commit( 68*349c18f8SZachary Turner BinaryStreamWriter &Writer) const { 69*349c18f8SZachary Turner using T = decltype(&*Mappings.begin()); 70*349c18f8SZachary Turner std::vector<T> Ids; 71*349c18f8SZachary Turner Ids.reserve(Mappings.size()); 72*349c18f8SZachary Turner 73*349c18f8SZachary Turner for (const auto &M : Mappings) 74*349c18f8SZachary Turner Ids.push_back(&M); 75*349c18f8SZachary Turner 76*349c18f8SZachary Turner std::sort(Ids.begin(), Ids.end(), [this](const T &L1, const T &L2) { 77*349c18f8SZachary Turner return Strings.getStringId(L1->getKey()) < 78*349c18f8SZachary Turner Strings.getStringId(L2->getKey()); 79*349c18f8SZachary Turner }); 80*349c18f8SZachary Turner 81*349c18f8SZachary Turner for (const auto &Item : Ids) { 82*349c18f8SZachary Turner CrossModuleImport Imp; 83*349c18f8SZachary Turner Imp.ModuleNameOffset = Strings.getStringId(Item->getKey()); 84*349c18f8SZachary Turner Imp.Count = Item->getValue().size(); 85*349c18f8SZachary Turner if (auto EC = Writer.writeObject(Imp)) 86*349c18f8SZachary Turner return EC; 87*349c18f8SZachary Turner if (auto EC = Writer.writeArray(makeArrayRef(Item->getValue()))) 88*349c18f8SZachary Turner return EC; 89*349c18f8SZachary Turner } 90*349c18f8SZachary Turner return Error::success(); 91*349c18f8SZachary Turner } 92