[build] Fix build failures with random versions of gcc

For unknown reasons, miscellaneous versions of gcc seem to struggle
with the static assertions used to ensure the correct layout of the
GCM structures.

Adjust the assertions to use offsetof() rather than direct pointer
comparison, on the basis that offsetof() must be a compile-time
constant value.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
diff --git a/src/crypto/gcm.c b/src/crypto/gcm.c
index a32890d..b93925d 100644
--- a/src/crypto/gcm.c
+++ b/src/crypto/gcm.c
@@ -109,6 +109,9 @@
  */
 static uint16_t gcm_cached_reduce[256];
 
+/** Offset of a field within GCM context */
+#define gcm_offset( field ) offsetof ( struct gcm_context, field )
+
 /**
  * Reverse bits in a byte
  *
@@ -470,17 +473,13 @@
  */
 void gcm_setiv ( struct gcm_context *context, const void *iv, size_t ivlen ) {
 
-	/* Sanity check: ensure that memset()s will clear expected state */
-	build_assert ( &context->hash < &context->ctr );
-	build_assert ( &context->len < &context->ctr );
-	build_assert ( &context->ctr < &context->key );
-	build_assert ( ( ( void * ) &context->raw_cipher ) >
-		       ( ( void * ) &context->key ) );
-	build_assert ( ( ( void * ) context->raw_ctx ) >
-		       ( ( void * ) &context->key ) );
-
 	/* Reset non-key state */
-	memset ( context, 0, offsetof ( typeof ( *context ), key ) );
+	memset ( context, 0, gcm_offset ( key ) );
+	build_assert ( gcm_offset ( key ) > gcm_offset ( hash ) );
+	build_assert ( gcm_offset ( key ) > gcm_offset ( len ) );
+	build_assert ( gcm_offset ( key ) > gcm_offset ( ctr ) );
+	build_assert ( gcm_offset ( key ) < gcm_offset ( raw_cipher ) );
+	build_assert ( gcm_offset ( key ) < gcm_offset ( raw_ctx ) );
 
 	/* Reset counter */
 	context->ctr.ctr.value = cpu_to_be32 ( 1 );
@@ -499,7 +498,12 @@
 		assert ( context->len.len.add == 0 );
 
 		/* Reset non-key, non-counter state */
-		memset ( context, 0, offsetof ( typeof ( *context ), ctr ) );
+		memset ( context, 0, gcm_offset ( ctr ) );
+		build_assert ( gcm_offset ( ctr ) > gcm_offset ( hash ) );
+		build_assert ( gcm_offset ( ctr ) > gcm_offset ( len ) );
+		build_assert ( gcm_offset ( ctr ) < gcm_offset ( key ) );
+		build_assert ( gcm_offset ( ctr ) < gcm_offset ( raw_cipher ) );
+		build_assert ( gcm_offset ( ctr ) < gcm_offset ( raw_ctx ) );
 	}
 
 	DBGC2 ( context, "GCM %p Y[0]:\n", context );
diff --git a/src/include/ipxe/gcm.h b/src/include/ipxe/gcm.h
index 4864445..2c785a9 100644
--- a/src/include/ipxe/gcm.h
+++ b/src/include/ipxe/gcm.h
@@ -89,10 +89,9 @@
 				  size_t keylen ) {			\
 	struct _gcm_name ## _context *context = ctx;			\
 	build_assert ( _blocksize == sizeof ( context->gcm.key ) );	\
-	build_assert ( ( ( void * ) &context->gcm ) ==			\
-		       ( ( void * ) context ) );			\
-	build_assert ( ( ( void * ) &context->raw ) ==			\
-		       ( ( void * ) context->gcm.raw_ctx ) );		\
+	build_assert ( offsetof ( typeof ( *context ), gcm ) == 0 );	\
+	build_assert ( offsetof ( typeof ( *context ), raw ) ==		\
+		       offsetof ( typeof ( *context ), gcm.raw_ctx ) );	\
 	return gcm_setkey ( &context->gcm, key, keylen, &_raw_cipher );	\
 }									\
 static void _gcm_name ## _setiv ( void *ctx, const void *iv,		\