summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike McLaughlin <mikem@microsoft.com>2018-07-24 12:19:59 -0700
committerGitHub <noreply@github.com>2018-07-24 12:19:59 -0700
commite6ada167d7991b1ab6e1ea921c521a691610e269 (patch)
tree5da0a060e589d3b4b15c102baeee0d5b538d6166
parentc72f69b878cc071b6bf9b9c0764159b48be8a8ee (diff)
downloadcoreclr-e6ada167d7991b1ab6e1ea921c521a691610e269.tar.gz
coreclr-e6ada167d7991b1ab6e1ea921c521a691610e269.tar.bz2
coreclr-e6ada167d7991b1ab6e1ea921c521a691610e269.zip
Fix mscordbi metadata reader alignment bug on Linux. (#19070)
Works fine on Windows minidumps, but on Linux (via OpenVirtualProcess for production breakpoints and future core dumps) the compiler's struct alignment rules are different. On Windows, classes/structs are aligned based on the largest field. On Linux, they are 4 byte aligned regardless of the field sizes. https://github.com/dotnet/coreclr/issues/17692
-rw-r--r--src/md/datasource/datatargetreader.cpp6
-rw-r--r--src/md/datasource/targettypes.cpp3
2 files changed, 9 insertions, 0 deletions
diff --git a/src/md/datasource/datatargetreader.cpp b/src/md/datasource/datatargetreader.cpp
index 03b9811e4a..3c32f61bce 100644
--- a/src/md/datasource/datatargetreader.cpp
+++ b/src/md/datasource/datatargetreader.cpp
@@ -163,7 +163,13 @@ void DataTargetReader::Align(DWORD alignmentBytes)
void DataTargetReader::AlignBase()
{
+#ifdef _MSC_VER
+ // Windows MSVC compiler aligns structs based on the largest field size
Align(m_currentStructureAlign);
+#else
+ // clang (on all platforms) aligns structs always on 4 byte boundaries
+ Align(4);
+#endif
}
HRESULT DataTargetReader::GetRemotePointerSize(ULONG32* pPointerSize)
diff --git a/src/md/datasource/targettypes.cpp b/src/md/datasource/targettypes.cpp
index 9af7dd15da..cb6b8a168b 100644
--- a/src/md/datasource/targettypes.cpp
+++ b/src/md/datasource/targettypes.cpp
@@ -134,9 +134,12 @@ m_tableMax(0)
HRESULT Target_MapSHash::ReadFrom(DataTargetReader & reader)
{
HRESULT hr = S_OK;
+ // Only the Windows MSVC compiler does this; not clang on Linux
+#ifdef _MSC_VER
IfFailRet(reader.Skip8()); // this byte gets used by the base class even though it has no members
// I'm guessing this is so the 2nd base class (noncopyable) doesn't start at the same
// location, but I can't be sure. Whatever the cause, the layout skips a byte.
+#endif // _MSC_VER
IfFailRet(reader.ReadPointer(&m_table));
IfFailRet(reader.Read32(&m_tableSize));
IfFailRet(reader.Read32(&m_tableCount));