Enable layout checks for all types again.

Not just the region layout

Bug: 79602833
Test: local
Change-Id: I21c5ddce451ecf9e6e15bfe17cd97708da086cd9
diff --git a/common/vsoc/lib/vsoc_memory.cpp b/common/vsoc/lib/vsoc_memory.cpp
index f05b0b8..f82b072 100644
--- a/common/vsoc/lib/vsoc_memory.cpp
+++ b/common/vsoc/lib/vsoc_memory.cpp
@@ -20,44 +20,25 @@
 #include <type_traits>
 
 #include "common/vsoc/shm/audio_data_layout.h"
+#include "common/vsoc/shm/base.h"
 #include "common/vsoc/shm/e2e_test_region_layout.h"
 #include "common/vsoc/shm/gralloc_layout.h"
 #include "common/vsoc/shm/input_events_layout.h"
 #include "common/vsoc/shm/ril_layout.h"
 #include "common/vsoc/shm/screen_layout.h"
 #include "common/vsoc/shm/socket_forward_layout.h"
-#include "common/vsoc/shm/version.h"
 #include "common/vsoc/shm/wifi_exchange_layout.h"
 
 namespace vsoc {
 
-// ShmTypeValidator provides meaningful information about the type size
-// mismatch in compilation error messages, eg.
-//
-// error:
-//    static_assert failed "Class size changed, update version.h"
-//    static_assert(Current == Expected,
-// note: in instantiation of template class
-//    'ShmTypeValidator<vsoc::layout::myclass::ClassName, 1232, 1240>'
-//    requested here ASSERT_SHM_COMPATIBLE(ClassName, myclass);
-//
-template <typename Type, size_t Current, size_t Expected>
-struct ShmTypeValidator {
-  static_assert(Current == Expected, "Class size changed, update version.h");
-  static_assert(std::is_trivial<Type>(), "Class uses features that are unsafe");
-  static constexpr bool valid =
-      (Current == Expected) && std::is_trivial<Type>();
-};
-
 namespace {
 template <class R>
 RegionMemoryLayout ValidateAndBuildLayout(int region_size,
                                           int g_to_h_signal_table_log_size,
                                           int h_to_g_signal_table_log_size,
                                           const char* managed_by = nullptr) {
-  static_assert(
-      ShmTypeValidator<R, sizeof(R), vsoc::layout::VersionInfo<R>::size>::valid,
-      "Compilation error. Please fix above errors and retry.");
+  // Double check that the Layout is a valid shm type.
+  ASSERT_SHM_COMPATIBLE(R);
   return RegionMemoryLayout(R::region_name, region_size,
                             g_to_h_signal_table_log_size,
                             h_to_g_signal_table_log_size, managed_by);
diff --git a/common/vsoc/shm/audio_data_layout.h b/common/vsoc/shm/audio_data_layout.h
index 30df4f8..3991ea0 100644
--- a/common/vsoc/shm/audio_data_layout.h
+++ b/common/vsoc/shm/audio_data_layout.h
@@ -26,10 +26,12 @@
 
 struct AudioDataLayout : public RegionLayout {
     static const char *const region_name;
+    static constexpr size_t layout_size = 16396;
 
     // size = 2^14 = 16384, packets are up to 4KB bytes each.
     CircularPacketQueue<14, 4096> audio_queue;
 };
+ASSERT_SHM_COMPATIBLE(AudioDataLayout);
 
 }  // namespace audio_data
 }  // namespace layout
diff --git a/common/vsoc/shm/base.h b/common/vsoc/shm/base.h
index 7bbaeb9..f5abec8 100644
--- a/common/vsoc/shm/base.h
+++ b/common/vsoc/shm/base.h
@@ -16,8 +16,31 @@
  */
 
 #include <stdint.h>
+#include <type_traits>
 
 // Base macros for all layout structures.
+// ShmTypeValidator provides meaningful information about the type size
+// mismatch in compilation error messages, eg.
+//
+// error:
+//    static_assert failed "Class size changed, update the layout_size field"
+//    static_assert(Current == Expected,
+// note: in instantiation of template class
+//    'ShmTypeValidator<vsoc::layout::myclass::ClassName>'
+//    requested here ASSERT_SHM_COMPATIBLE(ClassName);
+//
+template <typename Type, size_t expected_size = Type::layout_size>
+struct ShmTypeValidator {
+  static_assert(sizeof(Type) == expected_size,
+                "Class size changed, update the layout_size field");
+  static_assert(std::is_trivial<Type>(), "Class uses features that are unsafe");
+  static constexpr bool valid =
+      sizeof(Type) == expected_size && std::is_trivial<Type>();
+};
+
+#define ASSERT_SHM_COMPATIBLE(T)            \
+  static_assert(ShmTypeValidator<T>::valid, \
+                "Compilation error. Please fix above errors and retry.")
 
 namespace vsoc {
 namespace layout {
@@ -42,12 +65,18 @@
   Peer = Host
 #endif
 };
+// Enums can't have static members, so can't use the macro here.
+  static_assert(ShmTypeValidator<Sides, 4>::valid,
+              "Compilation error. Please fix above errors and retry.");
 
 /**
  * Base class for all region layout structures.
  */
 class RegionLayout {
+public:
+  static constexpr size_t layout_size = 1;
 };
+ASSERT_SHM_COMPATIBLE(RegionLayout);
 
 }  // namespace layout
 }  // namespace vsoc
diff --git a/common/vsoc/shm/circqueue.h b/common/vsoc/shm/circqueue.h
index aacdd2b..05893bf 100644
--- a/common/vsoc/shm/circqueue.h
+++ b/common/vsoc/shm/circqueue.h
@@ -36,6 +36,10 @@
  */
 template <uint32_t SizeLog2>
 class CircularQueueBase {
+ public:
+  static constexpr size_t layout_size = (1 << SizeLog2) + 12;
+
+ private:
   CircularQueueBase() = delete;
   CircularQueueBase(const CircularQueueBase&) = delete;
   CircularQueueBase& operator=(const CircularQueueBase&) = delete;
@@ -101,6 +105,7 @@
   char buffer_[BufferSize];
 };
 using CircularQueueBase64k = CircularQueueBase<16>;
+ASSERT_SHM_COMPATIBLE(CircularQueueBase64k);
 
 /**
  * Byte oriented circular queue. Reads will always return some data, but
@@ -110,6 +115,8 @@
 template <uint32_t SizeLog2>
 class CircularByteQueue : public CircularQueueBase<SizeLog2> {
  public:
+  static constexpr size_t layout_size =
+      CircularQueueBase<SizeLog2>::layout_size;
   /**
    * Read at most max_size bytes from the qeueue, placing them in buffer_out
    */
@@ -134,6 +141,7 @@
   using Range = typename CircularQueueBase<SizeLog2>::Range;
 };
 using CircularByteQueue64k = CircularByteQueue<16>;
+ASSERT_SHM_COMPATIBLE(CircularByteQueue64k);
 
 /**
  * Packet oriented circular queue. Reads will either return data or an error.
@@ -143,6 +151,9 @@
 template <uint32_t SizeLog2, uint32_t MaxPacketSize>
 class CircularPacketQueue : public CircularQueueBase<SizeLog2> {
  public:
+  static constexpr size_t layout_size =
+      CircularQueueBase<SizeLog2>::layout_size;
+
   /**
    * Read a single packet from the queue, placing its data into buffer_out.
    * If max_size indicates that buffer_out cannot hold the entire packet
@@ -186,6 +197,7 @@
   intptr_t CalculateBufferedSize(size_t payload);
 };
 using CircularPacketQueue64k = CircularPacketQueue<16, 1024>;
+ASSERT_SHM_COMPATIBLE(CircularPacketQueue64k);
 
 }  // namespace layout
 }  // namespace vsoc
diff --git a/common/vsoc/shm/e2e_test_region_layout.h b/common/vsoc/shm/e2e_test_region_layout.h
index 8853211..2c2670b 100644
--- a/common/vsoc/shm/e2e_test_region_layout.h
+++ b/common/vsoc/shm/e2e_test_region_layout.h
@@ -43,7 +43,7 @@
  * Flags that are used to indicate test status. Some of the latter testing
  * stages rely on initializion that must be done on the peer.
  */
-enum E2ETestStage {
+  enum E2ETestStage : uint32_t {
   // No tests have passed
   E2E_STAGE_NONE = 0,
   // This side has finished writing its pattern to the region
@@ -51,12 +51,16 @@
   // This side has confirmed that it can see its peer's writes to the region
   E2E_PEER_MEMORY_READ = 2,
 };
+static_assert(ShmTypeValidator<E2ETestStage, 4>::valid,
+              "Compilation error. Please fix above errors and retry.");
 
 /**
  * Structure that grants permission to write in the region to either the guest
  * or the host. This size of these fields is arbitrary.
  */
 struct E2EMemoryFill {
+  static constexpr size_t layout_size = 64;
+
   static const std::size_t kOwnedFieldSize = 32;
 
   // The compiler must not attempt to optimize away reads and writes to the
@@ -65,6 +69,7 @@
   char host_writable[kOwnedFieldSize];
   char guest_writable[kOwnedFieldSize];
 };
+ASSERT_SHM_COMPATIBLE(E2EMemoryFill);
 
 /**
  * Structure that grants permission to write in the region to either the guest
@@ -72,9 +77,10 @@
  */
 class E2ETestStageRegister {
  public:
+  static constexpr size_t layout_size = 4;
+
   E2ETestStage value() const {
-    E2ETestStage rval = static_cast<E2ETestStage>(value_);
-    return rval;
+    return value_;
   }
 
   void set_value(E2ETestStage new_value) { value_ = new_value; }
@@ -83,8 +89,9 @@
   // The compiler must not attempt to optimize away reads and writes to the
   // shared memory window. This is pretty typical when dealing with devices
   // doing memory mapped I/O.
-  uint32_t value_;
+  E2ETestStage value_;
 };
+ASSERT_SHM_COMPATIBLE(E2ETestStageRegister);
 
 /**
  * Describes the layout of the regions used for the end-to-end test. There
@@ -93,6 +100,9 @@
  */
 class E2ETestRegionLayout : public ::vsoc::layout::RegionLayout {
  public:
+  static constexpr size_t layout_size = 2 * E2ETestStageRegister::layout_size +
+                                        3 * 4 + E2EMemoryFill::layout_size;
+
   /**
    * Computes how many E2EMemoryFill records we need to cover the region.
    * Covering the entire region during the test ensures that everything is
@@ -123,36 +133,52 @@
   // until we examine the region.
   E2EMemoryFill data[1];
 };
+ASSERT_SHM_COMPATIBLE(E2ETestRegionLayout);
 
 struct E2EPrimaryTestRegionLayout : public E2ETestRegionLayout {
+  static constexpr size_t layout_size = E2ETestRegionLayout::layout_size;
+
   static const char* region_name;
   static const char guest_pattern[E2EMemoryFill::kOwnedFieldSize];
   static const char host_pattern[E2EMemoryFill::kOwnedFieldSize];
 };
+ASSERT_SHM_COMPATIBLE(E2EPrimaryTestRegionLayout);
 
 struct E2ESecondaryTestRegionLayout : public E2ETestRegionLayout {
+  static constexpr size_t layout_size = E2ETestRegionLayout::layout_size;
+
   static const char* region_name;
   static const char guest_pattern[E2EMemoryFill::kOwnedFieldSize];
   static const char host_pattern[E2EMemoryFill::kOwnedFieldSize];
 };
+ASSERT_SHM_COMPATIBLE(E2ESecondaryTestRegionLayout);
 
 /**
  * Defines an end-to-end region with a name that should never be configured.
  */
 struct E2EUnfindableRegionLayout : public E2ETestRegionLayout {
+  static constexpr size_t layout_size = E2ETestRegionLayout::layout_size;
+
   static const char* region_name;
 };
+ASSERT_SHM_COMPATIBLE(E2EUnfindableRegionLayout);
 
 struct E2EManagedTestRegionLayout : public RegionLayout {
+  static constexpr size_t layout_size = 4;
+
   static const char* region_name;
   uint32_t val;  // Not needed, here only to avoid an empty struct.
 };
+ASSERT_SHM_COMPATIBLE(E2EManagedTestRegionLayout);
 
 struct E2EManagerTestRegionLayout : public RegionLayout {
+  static constexpr size_t layout_size = 4 * 4;
+
   static const char* region_name;
   typedef E2EManagedTestRegionLayout ManagedRegion;
   uint32_t data[4];  // We don't need more than 4 for the tests
 };
+ASSERT_SHM_COMPATIBLE(E2EManagerTestRegionLayout);
 
 }  // namespace e2e_test
 }  // namespace layout
diff --git a/common/vsoc/shm/gralloc_layout.h b/common/vsoc/shm/gralloc_layout.h
index 3e0c883..4da740f 100644
--- a/common/vsoc/shm/gralloc_layout.h
+++ b/common/vsoc/shm/gralloc_layout.h
@@ -27,6 +27,9 @@
 namespace gralloc {
 
 struct BufferEntry {
+  static constexpr size_t layout_size =
+      7 * 4 + PixelFormatRegister::layout_size;
+
   uint32_t owned_by;
   uint32_t buffer_begin;
   uint32_t buffer_end;
@@ -44,12 +47,17 @@
     return buffer_end - buffer_begin;
   }
 };
+ASSERT_SHM_COMPATIBLE(BufferEntry);
 
 struct GrallocBufferLayout : public RegionLayout {
+  static constexpr size_t layout_size = 1;
   static const char* region_name;
 };
+ASSERT_SHM_COMPATIBLE(GrallocBufferLayout);
 
 struct GrallocManagerLayout : public RegionLayout {
+  static constexpr size_t layout_size =
+      8 + GuestLock::layout_size + BufferEntry::layout_size;
   static const char* region_name;
   typedef GrallocBufferLayout ManagedRegion;
 
@@ -60,6 +68,7 @@
   // Needs to be last field
   BufferEntry buffers_table[1];
 };
+ASSERT_SHM_COMPATIBLE(GrallocManagerLayout);
 
 } // namespace gralloc
 } // namespace layout
diff --git a/common/vsoc/shm/graphics.h b/common/vsoc/shm/graphics.h
index f29e0cf..0aa7875 100644
--- a/common/vsoc/shm/graphics.h
+++ b/common/vsoc/shm/graphics.h
@@ -68,7 +68,7 @@
 //   * Observant reviewers can verify that the same pixel value is not assigned
 //     to multiple formats. Keep the enums in numerical order below to
 //     make this easier.
-enum PixelFormat {
+enum PixelFormat : uint32_t {
   VSOC_PIXEL_FORMAT_UNINITIALIZED = PixelFormatBuilder<1,0>::value,
   VSOC_PIXEL_FORMAT_BLOB =          PixelFormatBuilder<1,1>::value,
 
@@ -129,25 +129,34 @@
   //   VSOC_PIXEL_FORMAT_sRGB_X_8888
   //   VSOC_PIXEL_FORMAT_sRGB_A_8888
 };
+// Enums can't have static members, so can't use the macro here.
+static_assert(ShmTypeValidator<PixelFormat, 4>::valid,
+              "Compilation error. Please fix above errors and retry.");
 
 namespace layout {
 
 // VSoC memory layout for a register that accepts a single pixel format.
 // The value is volatile to ensure that the compiler does not eliminate stores.
 struct PixelFormatRegister {
+  static constexpr size_t layout_size = 4;
+
   volatile PixelFormat value_;
 };
+ASSERT_SHM_COMPATIBLE(PixelFormatRegister);
 
 // Register layout for a mask giving different PixelFormats. Reserve enough
 // space to allow for future expansion. For example, we may well end with
 // a 12 bit per channel format in the future.
 struct PixelFormatMaskRegister {
+  static constexpr size_t layout_size = 8;
+
   volatile uint64_t value_;
 
   bool HasValue(PixelFormat in) {
     return !!(value_ & (uint64_t(1) << in));
   }
 };
+ASSERT_SHM_COMPATIBLE(PixelFormatMaskRegister);
 
 // Ensure that the mask is large enough to hold the highest encodable
 // pixel format.
diff --git a/common/vsoc/shm/input_events_layout.h b/common/vsoc/shm/input_events_layout.h
index 7cb4654..737c903 100644
--- a/common/vsoc/shm/input_events_layout.h
+++ b/common/vsoc/shm/input_events_layout.h
@@ -26,6 +26,10 @@
 namespace input_events {
 
 struct InputEventsLayout : public RegionLayout {
+  static constexpr size_t layout_size =
+      CircularPacketQueue<10, 256>::layout_size +
+      2 * CircularPacketQueue<10, 16>::layout_size;
+
   static const char* region_name;
   // Event queues for the different input devices supported. Both the power
   // button and the keyboard need only generate 2 input events for every
@@ -35,6 +39,7 @@
   CircularPacketQueue<10, 16> keyboard_queue;
   CircularPacketQueue<10, 16> power_button_queue;
 };
+ASSERT_SHM_COMPATIBLE(InputEventsLayout);
 
 }  // namespace input_events
 }  // namespace layout
diff --git a/common/vsoc/shm/lock.h b/common/vsoc/shm/lock.h
index 6ebdaa2..cc86add 100644
--- a/common/vsoc/shm/lock.h
+++ b/common/vsoc/shm/lock.h
@@ -50,6 +50,8 @@
  */
 class SpinLock {
  public:
+  static constexpr size_t layout_size = 4;
+
   /**
    * Acquire the spinlock on the queue. This will effectively block all
    * readers and writers.
@@ -87,12 +89,16 @@
  protected:
   std::atomic<uint32_t> lock_;
 };
+ASSERT_SHM_COMPATIBLE(SpinLock);
 
 /**
  * This is a generic synchronization primitive that provides space for the
  * owner of the lock to write platform-specific information.
  */
 class WaitingLockBase {
+ public:
+  static constexpr size_t layout_size = 40;
+
  protected:
   // Common code to handle locking
   // Must be called with the kernel's thread id
@@ -137,6 +143,7 @@
   int64_t owner_scratch_[2];
 #pragma clang diagnostic pop
 };
+ASSERT_SHM_COMPATIBLE(WaitingLockBase);
 
 /**
  * GuestLocks can be acquired and released only on the guest. They reside
@@ -148,6 +155,8 @@
  */
 class GuestLock : public WaitingLockBase {
  public:
+  static constexpr size_t layout_size = WaitingLockBase::layout_size;
+
 #ifndef CUTTLEFISH_HOST
   void Lock();
   void Unlock();
@@ -161,6 +170,7 @@
   bool Recover();
 #endif
 };
+ASSERT_SHM_COMPATIBLE(GuestLock);
 
 /**
  * HostLocks can be acquired and released only on the host. They reside
@@ -172,6 +182,8 @@
  */
 class HostLock : public WaitingLockBase {
  public:
+  static constexpr size_t layout_size = WaitingLockBase::layout_size;
+
 #ifdef CUTTLEFISH_HOST
   void Lock();
   void Unlock();
@@ -186,6 +198,7 @@
   bool Recover();
 #endif
 };
+ASSERT_SHM_COMPATIBLE(HostLock);
 
 /**
  * GuestAndHostLocks can be acquired and released on either side of the
@@ -213,6 +226,8 @@
  */
 class GuestAndHostLock : public WaitingLockBase {
  public:
+  static constexpr size_t layout_size = WaitingLockBase::layout_size;
+
   void Lock(RegionView*);
   void Unlock(RegionView*);
   /**
@@ -225,6 +240,7 @@
    */
   bool Recover(RegionView*);
 };
+ASSERT_SHM_COMPATIBLE(GuestAndHostLock);
 
 }  // namespace layout
 }  // namespace vsoc
diff --git a/common/vsoc/shm/ril_layout.h b/common/vsoc/shm/ril_layout.h
index 8910bde..33348e2 100644
--- a/common/vsoc/shm/ril_layout.h
+++ b/common/vsoc/shm/ril_layout.h
@@ -24,6 +24,7 @@
 namespace ril {
 
 struct RilLayout : public RegionLayout {
+  static constexpr size_t layout_size = 4 * 16 + 4;
   static const char* region_name;
 
   char ipaddr[16]; // xxx.xxx.xxx.xxx\0 = 16 bytes
@@ -32,6 +33,7 @@
   char broadcast[16];
   uint32_t prefixlen;
 };
+ASSERT_SHM_COMPATIBLE(RilLayout);
 }  // namespace ril
 }  // namespace layout
 }  // namespace vsoc
diff --git a/common/vsoc/shm/screen_layout.h b/common/vsoc/shm/screen_layout.h
index 3e54c6c..7ad0ca3 100644
--- a/common/vsoc/shm/screen_layout.h
+++ b/common/vsoc/shm/screen_layout.h
@@ -15,8 +15,6 @@
  * limitations under the License.
  */
 
-#include <vector>
-
 #include "common/vsoc/shm/base.h"
 #include "common/vsoc/shm/lock.h"
 
@@ -27,13 +25,19 @@
 
 namespace screen {
 struct TimeSpec {
+  static constexpr size_t layout_size = 16;
+
   int64_t ts_sec;
   uint32_t ts_nsec;
   // Host and guest compilers are giving the structure different sizes without
   // this field.
   uint32_t reserved;
 };
+ASSERT_SHM_COMPATIBLE(TimeSpec);
+
 struct CompositionStats {
+  static constexpr size_t layout_size = 4 + 2 * 2 + 5 * TimeSpec::layout_size;
+
   uint32_t num_prepare_calls;
   uint16_t num_layers;
   uint16_t num_hwcomposited_layers;
@@ -43,8 +47,10 @@
   TimeSpec set_start;
   TimeSpec set_end;
 };
+ASSERT_SHM_COMPATIBLE(CompositionStats);
 
 struct ScreenLayout : public RegionLayout {
+  static constexpr size_t layout_size = 24 + CompositionStats::layout_size;
   static const char* region_name;
   // Display properties
   uint32_t x_res;
@@ -62,6 +68,7 @@
   CompositionStats stats;
   uint8_t buffer[0];
 };
+ASSERT_SHM_COMPATIBLE(ScreenLayout);
 
 }  // namespace screen
 
diff --git a/common/vsoc/shm/socket_forward_layout.h b/common/vsoc/shm/socket_forward_layout.h
index 69d4ae2..5c78f21 100644
--- a/common/vsoc/shm/socket_forward_layout.h
+++ b/common/vsoc/shm/socket_forward_layout.h
@@ -36,8 +36,13 @@
   // If both are closed then the queue goes back to INACTIVE
   // BOTH_CLOSED = 0,
 };
+static_assert(ShmTypeValidator<QueueState, 4>::valid,
+              "Compilation error. Please fix above errors and retry.");
 
 struct Queue {
+  static constexpr size_t layout_size =
+      CircularPacketQueue<16, kMaxPacketSize>::layout_size + 4;
+
   CircularPacketQueue<16, kMaxPacketSize> queue;
 
   QueueState queue_state_;
@@ -46,8 +51,11 @@
     return queue.Recover();
   }
 };
+ASSERT_SHM_COMPATIBLE(Queue);
 
 struct QueuePair {
+  static constexpr size_t layout_size = 2 * Queue::layout_size + 8;
+
   // Traffic originating from host that proceeds towards guest.
   Queue host_to_guest;
   // Traffic originating from guest that proceeds towards host.
@@ -67,8 +75,11 @@
     return recovered;
   }
 };
+ASSERT_SHM_COMPATIBLE(QueuePair);
 
 struct SocketForwardLayout : public RegionLayout {
+  static constexpr size_t layout_size = QueuePair::layout_size * kNumQueues + 8;
+
   bool Recover() {
     bool recovered = false;
     for (auto& i : queues_) {
@@ -85,6 +96,8 @@
   static const char* region_name;
 };
 
+ASSERT_SHM_COMPATIBLE(SocketForwardLayout);
+
 }  // namespace socket_forward
 }  // namespace layout
 }  // namespace vsoc
diff --git a/common/vsoc/shm/version.h b/common/vsoc/shm/version.h
deleted file mode 100644
index cc2e6b6..0000000
--- a/common/vsoc/shm/version.h
+++ /dev/null
@@ -1,175 +0,0 @@
-#pragma once
-
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Version information for structures that are present in VSoC shared memory
-// windows. The proper use of this file will:
-//
-//   * ensure that the guest and host builds agree on the sizes of the shared
-//     structures.
-//
-//   * provides a single version code for the entire vsoc layout, assuming
-//     that reviewers excercise some care.
-//
-//
-//  Use:
-//
-//    Every new class / structure in the shm folder needs to add a size
-//    entry here, #include the base.h file, and add a ASSERT_SHM_COMPATIBLE
-//    instantiation just below the class definition,
-//
-//    For templatized classes / structs the author should choose a fixed size,
-//    create a using alias, and instantiate the checks on the alias.
-//    See CircularByteQueue64k for an example of this usage.
-//
-//   Note to reviewers:
-//
-//     It is probably ok to approve new additions  here without forcing a
-//     a version change.
-//
-//     However, the version must increment for any change in the value of a
-//     constant.
-//
-//     #ifdef, etc is absolutely forbidden in this file and highly discouraged
-//     in the other vsoc/shm files.
-
-#include <cstdint>
-
-#include "common/vsoc/shm/audio_data_layout.h"
-#include "common/vsoc/shm/e2e_test_region_layout.h"
-#include "common/vsoc/shm/gralloc_layout.h"
-#include "common/vsoc/shm/input_events_layout.h"
-#include "common/vsoc/shm/ril_layout.h"
-#include "common/vsoc/shm/screen_layout.h"
-#include "common/vsoc/shm/socket_forward_layout.h"
-#include "common/vsoc/shm/wifi_exchange_layout.h"
-
-namespace vsoc {
-namespace layout {
-
-template <typename T>
-class VersionInfo {
- public:
-  constexpr static size_t size = -1;
-};
-
-// Versioning information for audio_data_layout.h
-// Changes to these structures will affect only the audio_data region
-template <>
-class VersionInfo<audio_data::AudioDataLayout> {
- public:
-  // One circular queue of with a 16KB buffer, a 32 bits spinlock and
-  // two 32 bits integers.
-  constexpr static size_t size = 16384 + 3 * 4;
-};
-
-// Versioning information for e2e_test_region.h
-// Changes to these structures will affect only the e2e_test_region
-template <>
-class VersionInfo<e2e_test::E2EManagerTestRegionLayout> {
- public:
-  constexpr static size_t size = 16;
-};
-template <>
-class VersionInfo<e2e_test::E2EPrimaryTestRegionLayout> {
- public:
-  constexpr static size_t size = 84;
-};
-template <>
-class VersionInfo<e2e_test::E2ESecondaryTestRegionLayout> {
- public:
-  constexpr static size_t size = 84;
-};
-template <>
-class VersionInfo<e2e_test::E2ETestRegionLayout> {
- public:
-  constexpr static size_t size = 84;
-};
-template <>
-class VersionInfo<e2e_test::E2EUnfindableRegionLayout> {
- public:
-  constexpr static size_t size = 84;
-};
-template <>
-class VersionInfo<e2e_test::E2EManagedTestRegionLayout> {
- public:
-  constexpr static size_t size = 4;
-};
-
-// Versioning information for gralloc_layout.h
-// Changes to these structures will affect only the gralloc region
-template <>
-class VersionInfo<gralloc::GrallocManagerLayout> {
- public:
-  constexpr static size_t size = 80;
-};
-template <>
-class VersionInfo<gralloc::GrallocBufferLayout> {
- public:
-  constexpr static size_t size = 1;
-};
-
-// Versioning information for input_events_layout.h
-// Changes to these structures will affect only the input_events region
-template <>
-class VersionInfo<input_events::InputEventsLayout> {
- public:
-  // Three circular queues, each with a 1024 bytes buffer, a 32 bits spinlock
-  // and two 32 bits integers.
-  constexpr static size_t size = 3 * (1024 + 3 * 4);
-};
-
-// Versioning information for ril_layout.h
-template <>
-class VersionInfo<ril::RilLayout> {
- public:
-  constexpr static size_t size = 68;
-};
-
-// Versioning information for screen_layout.h
-// Changes to these structures will affect only the screen region.
-template <>
-class VersionInfo<screen::ScreenLayout> {
- public:
-  constexpr static size_t size = 112;
-};
-
-// Versioning Information for socket_forward_layout.h
-template <>
-class VersionInfo<socket_forward::SocketForwardLayout> {
- public:
-  constexpr static size_t size = ((((65548 + 4)  // queue + state
-                                    * 2)     // host_to_guest and guest_to_host
-                                   + 4 + 4)  // port and state_lock
-                                  * socket_forward::kNumQueues) +
-                                 4     // seq_num
-                                 + 4;  // generation number
-};
-
-// Versioning information for wifi_layout.h
-template <>
-class VersionInfo<wifi::WifiExchangeLayout> {
- public:
-  constexpr static size_t size =
-      65548 +  // sizeof(CircularPacketQueue<16, 8192>) - forward
-      65548 +  // sizeof(CircularPacketQueue<16, 8192>) - reverse
-      6 +      // uint8_t[6] MAC address.
-      6;       // uint8_t[6] MAC address.
-};
-
-}  // namespace layout
-}  // namespace vsoc
diff --git a/common/vsoc/shm/wifi_exchange_layout.h b/common/vsoc/shm/wifi_exchange_layout.h
index 3eaa1b6..df4659e 100644
--- a/common/vsoc/shm/wifi_exchange_layout.h
+++ b/common/vsoc/shm/wifi_exchange_layout.h
@@ -25,6 +25,8 @@
 namespace wifi {
 
 struct WifiExchangeLayout : public RegionLayout {
+  static constexpr size_t layout_size = 2 * CircularPacketQueue<16, 8192>::layout_size + 12;
+
   // Traffic originating from host that proceeds towards guest.
   CircularPacketQueue<16, 8192> guest_ingress;
   // Traffic originating from guest that proceeds towards host.
@@ -38,6 +40,8 @@
   static const char* region_name;
 };
 
+ASSERT_SHM_COMPATIBLE(WifiExchangeLayout);
+
 }  // namespace wifi
 }  // namespace layout
 }  // namespace vsoc