1349c18f8SZachary Turner //===- DebugCrossImpSubsection.cpp ------------------------------*- C++ -*-===// 2349c18f8SZachary Turner // 3349c18f8SZachary Turner // The LLVM Compiler Infrastructure 4349c18f8SZachary Turner // 5349c18f8SZachary Turner // This file is distributed under the University of Illinois Open Source 6349c18f8SZachary Turner // License. See LICENSE.TXT for details. 7349c18f8SZachary Turner // 8349c18f8SZachary Turner //===----------------------------------------------------------------------===// 9349c18f8SZachary Turner 10349c18f8SZachary Turner #include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h" 11349c18f8SZachary Turner 12349c18f8SZachary Turner #include "llvm/DebugInfo/CodeView/CodeViewError.h" 13349c18f8SZachary Turner #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" 14349c18f8SZachary Turner 15349c18f8SZachary Turner using namespace llvm; 16349c18f8SZachary Turner using namespace llvm::codeview; 17349c18f8SZachary Turner 18349c18f8SZachary Turner namespace llvm { 19*7e62cd17SZachary Turner Error VarStreamArrayExtractor<CrossModuleImportItem>:: 20*7e62cd17SZachary Turner operator()(BinaryStreamRef Stream, uint32_t &Len, 21349c18f8SZachary Turner codeview::CrossModuleImportItem &Item) { 22349c18f8SZachary Turner BinaryStreamReader Reader(Stream); 23349c18f8SZachary Turner if (Reader.bytesRemaining() < sizeof(CrossModuleImport)) 24349c18f8SZachary Turner return make_error<CodeViewError>( 25349c18f8SZachary Turner cv_error_code::insufficient_buffer, 26349c18f8SZachary Turner "Not enough bytes for a Cross Module Import Header!"); 27349c18f8SZachary Turner if (auto EC = Reader.readObject(Item.Header)) 28349c18f8SZachary Turner return EC; 29349c18f8SZachary Turner if (Reader.bytesRemaining() < Item.Header->Count * sizeof(uint32_t)) 30349c18f8SZachary Turner return make_error<CodeViewError>( 31349c18f8SZachary Turner cv_error_code::insufficient_buffer, 32349c18f8SZachary Turner "Not enough to read specified number of Cross Module References!"); 33349c18f8SZachary Turner if (auto EC = Reader.readArray(Item.Imports, Item.Header->Count)) 34349c18f8SZachary Turner return EC; 35349c18f8SZachary Turner return Error::success(); 36349c18f8SZachary Turner } 37349c18f8SZachary Turner } 38349c18f8SZachary Turner 39349c18f8SZachary Turner Error DebugCrossModuleImportsSubsectionRef::initialize( 40349c18f8SZachary Turner BinaryStreamReader Reader) { 41349c18f8SZachary Turner return Reader.readArray(References, Reader.bytesRemaining()); 42349c18f8SZachary Turner } 43349c18f8SZachary Turner 44349c18f8SZachary Turner Error DebugCrossModuleImportsSubsectionRef::initialize(BinaryStreamRef Stream) { 45349c18f8SZachary Turner BinaryStreamReader Reader(Stream); 46349c18f8SZachary Turner return initialize(Reader); 47349c18f8SZachary Turner } 48349c18f8SZachary Turner 49349c18f8SZachary Turner void DebugCrossModuleImportsSubsection::addImport(StringRef Module, 50349c18f8SZachary Turner uint32_t ImportId) { 51349c18f8SZachary Turner Strings.insert(Module); 52349c18f8SZachary Turner std::vector<support::ulittle32_t> Targets = {support::ulittle32_t(ImportId)}; 53349c18f8SZachary Turner auto Result = Mappings.insert(std::make_pair(Module, Targets)); 54349c18f8SZachary Turner if (!Result.second) 55349c18f8SZachary Turner Result.first->getValue().push_back(Targets[0]); 56349c18f8SZachary Turner } 57349c18f8SZachary Turner 58349c18f8SZachary Turner uint32_t DebugCrossModuleImportsSubsection::calculateSerializedSize() const { 59349c18f8SZachary Turner uint32_t Size = 0; 60349c18f8SZachary Turner for (const auto &Item : Mappings) { 61349c18f8SZachary Turner Size += sizeof(CrossModuleImport); 62349c18f8SZachary Turner Size += sizeof(support::ulittle32_t) * Item.second.size(); 63349c18f8SZachary Turner } 64349c18f8SZachary Turner return Size; 65349c18f8SZachary Turner } 66349c18f8SZachary Turner 67349c18f8SZachary Turner Error DebugCrossModuleImportsSubsection::commit( 68349c18f8SZachary Turner BinaryStreamWriter &Writer) const { 69349c18f8SZachary Turner using T = decltype(&*Mappings.begin()); 70349c18f8SZachary Turner std::vector<T> Ids; 71349c18f8SZachary Turner Ids.reserve(Mappings.size()); 72349c18f8SZachary Turner 73349c18f8SZachary Turner for (const auto &M : Mappings) 74349c18f8SZachary Turner Ids.push_back(&M); 75349c18f8SZachary Turner 76349c18f8SZachary Turner std::sort(Ids.begin(), Ids.end(), [this](const T &L1, const T &L2) { 77349c18f8SZachary Turner return Strings.getStringId(L1->getKey()) < 78349c18f8SZachary Turner Strings.getStringId(L2->getKey()); 79349c18f8SZachary Turner }); 80349c18f8SZachary Turner 81349c18f8SZachary Turner for (const auto &Item : Ids) { 82349c18f8SZachary Turner CrossModuleImport Imp; 83349c18f8SZachary Turner Imp.ModuleNameOffset = Strings.getStringId(Item->getKey()); 84349c18f8SZachary Turner Imp.Count = Item->getValue().size(); 85349c18f8SZachary Turner if (auto EC = Writer.writeObject(Imp)) 86349c18f8SZachary Turner return EC; 87349c18f8SZachary Turner if (auto EC = Writer.writeArray(makeArrayRef(Item->getValue()))) 88349c18f8SZachary Turner return EC; 89349c18f8SZachary Turner } 90349c18f8SZachary Turner return Error::success(); 91349c18f8SZachary Turner } 92