From f77369b9e71e9a200177f02260a14f29b6f725da Mon Sep 17 00:00:00 2001
From: Cheng Shao <terrorjack@type.dance>
Date: Mon, 27 May 2024 17:09:14 +0000
Subject: [PATCH] rts: ensure gc_thread/gen_workspace is allocated with proper
 alignment

gc_thread/gen_workspace are required to be aligned by 64 bytes.
However, this property has not been properly enforced before, and
numerous alignment violations at runtime has been caught by
UndefinedBehaviorSanitizer that look like:

```
rts/sm/GC.c:1167:8: runtime error: member access within misaligned address 0x0000027a3390 for type 'gc_thread' (aka 'struct gc_thread_'), which requires 64 byte alignment
0x0000027a3390: note: pointer points here
 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00
              ^
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/sm/GC.c:1167:8

rts/sm/GC.c:1184:13: runtime error: member access within misaligned address 0x0000027a3450 for type 'gen_workspace' (aka 'struct gen_workspace_'), which requires 64 byte alignment
0x0000027a3450: note: pointer points here
 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00
              ^
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/sm/GC.c:1184:13
```

This patch fixes the gc_thread/gen_workspace misalignment issue by
explicitly allocating them with alignment constraint.

(cherry picked from commit 7a660042395614e4b19534baf5b779f65059861e)
---
 rts/sm/GC.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/rts/sm/GC.c b/rts/sm/GC.c
index 90afde90fac..24bdb9eafdf 100644
--- a/rts/sm/GC.c
+++ b/rts/sm/GC.c
@@ -55,6 +55,7 @@
 #include "NonMoving.h"
 #include "Ticky.h"
 
+#include <stdalign.h>
 #include <string.h> // for memset()
 #include <unistd.h>
 
@@ -1242,8 +1243,9 @@ initGcThreads (uint32_t from USED_IF_THREADS, uint32_t to USED_IF_THREADS)
 
     for (i = from; i < to; i++) {
         gc_threads[i] =
-            stgMallocBytes(sizeof(gc_thread) +
+            stgMallocAlignedBytes(sizeof(gc_thread) +
                            RtsFlags.GcFlags.generations * sizeof(gen_workspace),
+                           alignof(gc_thread),
                            "alloc_gc_threads");
 
         new_gc_thread(i, gc_threads[i]);
@@ -1268,7 +1270,7 @@ freeGcThreads (void)
             {
                 freeWSDeque(gc_threads[i]->gens[g].todo_q);
             }
-            stgFree (gc_threads[i]);
+            stgFreeAligned (gc_threads[i]);
         }
         closeCondition(&gc_running_cv);
         closeMutex(&gc_running_mutex);
-- 
GitLab