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