Fix alignment of generated UNWIND_INFO structures

I missed a few parts of the Windows documentation:

> The UNWIND_INFO structure must be DWORD aligned in memory.

> For alignment purposes, this array [unwind codes] always has an even
> number of entries, and the final entry is potentially unused. In that
> case, the array is one longer than indicated by the count of unwind
> codes field.

https://learn.microsoft.com/en-us/cpp/build/exception-handling-x64?view=msvc-170

This didn't seem to have any practical effect (unwinding tests worked
as-is), but I noticed this while rewriting some handwritten codes.

Bug: 259
Change-Id: I655f3a7f3a907797e7665a276f4926a31a1e1639
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/68407
Reviewed-by: Adam Langley <agl@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: Adam Langley <agl@google.com>
diff --git a/crypto/perlasm/x86_64-xlate.pl b/crypto/perlasm/x86_64-xlate.pl
index 5b7705d..3011c91 100755
--- a/crypto/perlasm/x86_64-xlate.pl
+++ b/crypto/perlasm/x86_64-xlate.pl
@@ -903,6 +903,16 @@
 $info{unwind_codes}
 ____
 
+	# UNWIND_INFOs must be 4-byte aligned. If needed, we must add an extra
+	# unwind code. This does not change the unwind code count. Windows
+	# documentation says "For alignment purposes, this array always has an
+	# even number of entries, and the final entry is potentially unused. In
+	# that case, the array is one longer than indicated by the count of
+	# unwind codes field."
+	if ($info{num_codes} & 1) {
+	    $xdata .= "\t.value\t0\n";
+	}
+
 	%info = ();
 	return $end_label;
     }
diff --git a/gen/bcm/aesni-gcm-x86_64-win.asm b/gen/bcm/aesni-gcm-x86_64-win.asm
index 7564a1c..e8324d2 100644
--- a/gen/bcm/aesni-gcm-x86_64-win.asm
+++ b/gen/bcm/aesni-gcm-x86_64-win.asm
@@ -1039,6 +1039,7 @@
 	DB	$L$SEH_prologue_aesni_gcm_decrypt_2-$L$SEH_begin_aesni_gcm_decrypt_1
 	DB	80
 
+	DW	0
 $L$SEH_info_aesni_gcm_encrypt_0:
 	DB	1
 	DB	$L$SEH_endprologue_aesni_gcm_encrypt_22-$L$SEH_begin_aesni_gcm_encrypt_1
@@ -1097,6 +1098,8 @@
 	DB	48
 	DB	$L$SEH_prologue_aesni_gcm_encrypt_2-$L$SEH_begin_aesni_gcm_encrypt_1
 	DB	80
+
+	DW	0
 %else
 ; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738
 ret
diff --git a/gen/bcm/ghash-ssse3-x86_64-win.asm b/gen/bcm/ghash-ssse3-x86_64-win.asm
index a8be60e..e0de962 100644
--- a/gen/bcm/ghash-ssse3-x86_64-win.asm
+++ b/gen/bcm/ghash-ssse3-x86_64-win.asm
@@ -477,6 +477,7 @@
 	DB	$L$SEH_prologue_gcm_gmult_ssse3_2-$L$SEH_begin_gcm_gmult_ssse3_1
 	DB	66
 
+	DW	0
 $L$SEH_info_gcm_ghash_ssse3_0:
 	DB	1
 	DB	$L$SEH_endprologue_gcm_ghash_ssse3_6-$L$SEH_begin_gcm_ghash_ssse3_1
@@ -493,6 +494,8 @@
 	DW	0
 	DB	$L$SEH_prologue_gcm_ghash_ssse3_2-$L$SEH_begin_gcm_ghash_ssse3_1
 	DB	98
+
+	DW	0
 %else
 ; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738
 ret
diff --git a/gen/bcm/ghash-x86_64-win.asm b/gen/bcm/ghash-x86_64-win.asm
index bd4d691..b5416b3 100644
--- a/gen/bcm/ghash-x86_64-win.asm
+++ b/gen/bcm/ghash-x86_64-win.asm
@@ -1246,6 +1246,7 @@
 	DB	$L$SEH_prologue_gcm_init_clmul_2-$L$SEH_begin_gcm_init_clmul_1
 	DB	34
 
+	DW	0
 $L$SEH_info_gcm_ghash_clmul_0:
 	DB	1
 	DB	$L$SEH_endprologue_gcm_ghash_clmul_13-$L$SEH_begin_gcm_ghash_clmul_1
@@ -1296,6 +1297,7 @@
 	DB	$L$SEH_prologue_gcm_init_avx_2-$L$SEH_begin_gcm_init_avx_1
 	DB	34
 
+	DW	0
 $L$SEH_info_gcm_ghash_avx_0:
 	DB	1
 	DB	$L$SEH_endprologue_gcm_ghash_avx_13-$L$SEH_begin_gcm_ghash_avx_1
diff --git a/gen/test_support/trampoline-x86_64-win.asm b/gen/test_support/trampoline-x86_64-win.asm
index dca3957..7c7d3c3 100644
--- a/gen/test_support/trampoline-x86_64-win.asm
+++ b/gen/test_support/trampoline-x86_64-win.asm
@@ -698,6 +698,7 @@
 	DB	$L$SEH_prologue_abi_test_bad_unwind_wrong_register_2-$L$SEH_begin_abi_test_bad_unwind_wrong_register_1
 	DB	208
 
+	DW	0
 $L$SEH_info_abi_test_bad_unwind_temporary_0:
 	DB	1
 	DB	$L$SEH_endprologue_abi_test_bad_unwind_temporary_3-$L$SEH_begin_abi_test_bad_unwind_temporary_1
@@ -706,6 +707,7 @@
 	DB	$L$SEH_prologue_abi_test_bad_unwind_temporary_2-$L$SEH_begin_abi_test_bad_unwind_temporary_1
 	DB	192
 
+	DW	0
 $L$SEH_info_abi_test_bad_unwind_epilog_0:
 	DB	1
 	DB	$L$SEH_endprologue_abi_test_bad_unwind_epilog_3-$L$SEH_begin_abi_test_bad_unwind_epilog_1
@@ -713,6 +715,8 @@
 	DB	0
 	DB	$L$SEH_prologue_abi_test_bad_unwind_epilog_2-$L$SEH_begin_abi_test_bad_unwind_epilog_1
 	DB	192
+
+	DW	0
 %else
 ; Work around https://bugzilla.nasm.us/show_bug.cgi?id=3392738
 ret