From 12e26d1b1eb4aa557b5554a461eaa9ef1d75484a Mon Sep 17 00:00:00 2001 From: Thomas Fransham Date: Tue, 15 Oct 2024 22:05:40 +0100 Subject: [PATCH 1/2] [Minidump] Add extern template declarations for MinidumpFile::getListStream Add extern template defs along with visibility macros to MinidumpFile::getListStream thats needed by MinidumpTest.cpp when llvm is built as shared library on windows with explicit visibility macros enabled. This is part of the work to enable LLVM_BUILD_LLVM_DYLIB and LLVM plugins on window. --- llvm/include/llvm/Object/Minidump.h | 14 ++++++++++++++ llvm/lib/Object/Minidump.cpp | 6 +++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/Object/Minidump.h b/llvm/include/llvm/Object/Minidump.h index e6b21979ccaa1d..5002a2a54c7555 100644 --- a/llvm/include/llvm/Object/Minidump.h +++ b/llvm/include/llvm/Object/Minidump.h @@ -15,9 +15,15 @@ #include "llvm/ADT/iterator.h" #include "llvm/BinaryFormat/Minidump.h" #include "llvm/Object/Binary.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/Error.h" namespace llvm { +namespace minidump { +struct Module; +struct Thread; +struct MemoryDescriptor; +} // namespace minidump namespace object { /// A class providing access to the contents of a minidump file. @@ -371,6 +377,14 @@ Expected> MinidumpFile::getDataSliceAs(ArrayRef Data, return ArrayRef(reinterpret_cast(Slice->data()), Count); } +// Needed by MinidumpTest.cpp +extern template LLVM_TEMPLATE_ABI Expected> + MinidumpFile::getListStream(minidump::StreamType) const; +extern template LLVM_TEMPLATE_ABI Expected> + MinidumpFile::getListStream(minidump::StreamType) const; +extern template LLVM_TEMPLATE_ABI Expected> + MinidumpFile::getListStream(minidump::StreamType) const; + } // end namespace object } // end namespace llvm diff --git a/llvm/lib/Object/Minidump.cpp b/llvm/lib/Object/Minidump.cpp index fe768c4c90711b..50d4c608456900 100644 --- a/llvm/lib/Object/Minidump.cpp +++ b/llvm/lib/Object/Minidump.cpp @@ -98,11 +98,11 @@ Expected> MinidumpFile::getListStream(StreamType Type) const { return getDataSliceAs(*Stream, ListOffset, ListSize); } -template Expected> +template LLVM_EXPORT_TEMPLATE Expected> MinidumpFile::getListStream(StreamType) const; -template Expected> +template LLVM_EXPORT_TEMPLATE Expected> MinidumpFile::getListStream(StreamType) const; -template Expected> +template LLVM_EXPORT_TEMPLATE Expected> MinidumpFile::getListStream(StreamType) const; Expected> MinidumpFile::getDataSlice(ArrayRef Data, From 1f548107f40289520ebe7e17a95bace3a7b5328c Mon Sep 17 00:00:00 2001 From: Thomas Fransham Date: Fri, 1 Nov 2024 06:49:02 +0000 Subject: [PATCH 2/2] Just declare MinidumpFile::getListStream in the header instead of extern template --- llvm/include/llvm/Object/Minidump.h | 34 ++++++++++++++++++----------- llvm/lib/Object/Minidump.cpp | 27 ----------------------- 2 files changed, 21 insertions(+), 40 deletions(-) diff --git a/llvm/include/llvm/Object/Minidump.h b/llvm/include/llvm/Object/Minidump.h index 5002a2a54c7555..831be1c51d5748 100644 --- a/llvm/include/llvm/Object/Minidump.h +++ b/llvm/include/llvm/Object/Minidump.h @@ -15,15 +15,9 @@ #include "llvm/ADT/iterator.h" #include "llvm/BinaryFormat/Minidump.h" #include "llvm/Object/Binary.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/Error.h" namespace llvm { -namespace minidump { -struct Module; -struct Thread; -struct MemoryDescriptor; -} // namespace minidump namespace object { /// A class providing access to the contents of a minidump file. @@ -377,13 +371,27 @@ Expected> MinidumpFile::getDataSliceAs(ArrayRef Data, return ArrayRef(reinterpret_cast(Slice->data()), Count); } -// Needed by MinidumpTest.cpp -extern template LLVM_TEMPLATE_ABI Expected> - MinidumpFile::getListStream(minidump::StreamType) const; -extern template LLVM_TEMPLATE_ABI Expected> - MinidumpFile::getListStream(minidump::StreamType) const; -extern template LLVM_TEMPLATE_ABI Expected> - MinidumpFile::getListStream(minidump::StreamType) const; +template +Expected> +MinidumpFile::getListStream(minidump::StreamType Type) const { + std::optional> Stream = getRawStream(Type); + if (!Stream) + return createError("No such stream"); + auto ExpectedSize = getDataSliceAs(*Stream, 0, 1); + if (!ExpectedSize) + return ExpectedSize.takeError(); + + size_t ListSize = ExpectedSize.get()[0]; + + size_t ListOffset = 4; + // Some producers insert additional padding bytes to align the list to an + // 8-byte boundary. Check for that by comparing the list size with the overall + // stream size. + if (ListOffset + sizeof(T) * ListSize < Stream->size()) + ListOffset = 8; + + return getDataSliceAs(*Stream, ListOffset, ListSize); +} } // end namespace object } // end namespace llvm diff --git a/llvm/lib/Object/Minidump.cpp b/llvm/lib/Object/Minidump.cpp index 50d4c608456900..83c527e84365f8 100644 --- a/llvm/lib/Object/Minidump.cpp +++ b/llvm/lib/Object/Minidump.cpp @@ -78,33 +78,6 @@ MinidumpFile::getMemoryInfoList() const { MemoryInfoIterator({}, H.SizeOfEntry)); } -template -Expected> MinidumpFile::getListStream(StreamType Type) const { - std::optional> Stream = getRawStream(Type); - if (!Stream) - return createError("No such stream"); - auto ExpectedSize = getDataSliceAs(*Stream, 0, 1); - if (!ExpectedSize) - return ExpectedSize.takeError(); - - size_t ListSize = ExpectedSize.get()[0]; - - size_t ListOffset = 4; - // Some producers insert additional padding bytes to align the list to an - // 8-byte boundary. Check for that by comparing the list size with the overall - // stream size. - if (ListOffset + sizeof(T) * ListSize < Stream->size()) - ListOffset = 8; - - return getDataSliceAs(*Stream, ListOffset, ListSize); -} -template LLVM_EXPORT_TEMPLATE Expected> - MinidumpFile::getListStream(StreamType) const; -template LLVM_EXPORT_TEMPLATE Expected> - MinidumpFile::getListStream(StreamType) const; -template LLVM_EXPORT_TEMPLATE Expected> - MinidumpFile::getListStream(StreamType) const; - Expected> MinidumpFile::getDataSlice(ArrayRef Data, uint64_t Offset, uint64_t Size) {