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