summaryrefslogtreecommitdiff
path: root/compiler/cmm/PprC.hs
diff options
context:
space:
mode:
authorSergei Trofimovich <slyfox@gentoo.org>2016-03-06 09:55:12 +0000
committerSergei Trofimovich <siarheit@google.com>2016-03-06 09:55:21 +0000
commitade1a461ab4ba3e6de3c4afe9fe9766b7b4e51b3 (patch)
tree726618be2610df530d458a5a61f3956bacc346b4 /compiler/cmm/PprC.hs
parentbd681bceba535d0e67e8182964dc167877e4756d (diff)
downloadhaskell-ade1a461ab4ba3e6de3c4afe9fe9766b7b4e51b3.tar.gz
Fix minimum alignment for StgClosure (Trac #11395)
The bug is observed on m68k-linux target as crash in RTS: -- a.hs: main = print 43 $ inplace/bin/ghc-stage1 --make -debug a.hs $ ./a Program terminated with signal SIGSEGV, Segmentation fault. #0 0x80463b0a in LOOKS_LIKE_INFO_PTR_NOT_NULL (p=32858) at includes/rts/storage/ClosureMacros.h:248 (gdb) bt #0 0x80463b0a in LOOKS_LIKE_INFO_PTR_NOT_NULL (p=32858) at includes/rts/storage/ClosureMacros.h:248 #1 0x80463b46 in LOOKS_LIKE_INFO_PTR (p=32858) at includes/rts/storage/ClosureMacros.h:253 #2 0x80463b6c in LOOKS_LIKE_CLOSURE_PTR ( p=0x805aac6e <stg_dummy_ret_closure>) at includes/rts/storage/ClosureMacros.h:258 #3 0x80463e4c in initStorage () at rts/sm/Storage.c:121 #4 0x8043ffb4 in hs_init_ghc (...) at rts/RtsStartup.c:181 #5 0x80455982 in hs_main (...) at rts/RtsMain.c:51 #6 0x80003c1c in main () GHC assumes last 2 pointer bits are tags on 32-bit targets. But here 'stg_dummy_ret_closure' address violates the assumption: LOOKS_LIKE_CLOSURE_PTR (p=0x805aac6e <stg_dummy_ret_closure>) I've added compiler hint for static StgClosure objects to align closures at least by their natural alignment (what GHC assumes). See Note [StgWord alignment]. Signed-off-by: Sergei Trofimovich <siarheit@google.com> Test Plan: ran basic test on m68k qemu, it got past ASSERTs Reviewers: simonmar, austin, bgamari Reviewed By: bgamari Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D1974 GHC Trac Issues: #11395
Diffstat (limited to 'compiler/cmm/PprC.hs')
-rw-r--r--compiler/cmm/PprC.hs26
1 files changed, 25 insertions, 1 deletions
diff --git a/compiler/cmm/PprC.hs b/compiler/cmm/PprC.hs
index e679d5516b..c269530409 100644
--- a/compiler/cmm/PprC.hs
+++ b/compiler/cmm/PprC.hs
@@ -148,10 +148,34 @@ pprWordArray :: CLabel -> [CmmStatic] -> SDoc
pprWordArray lbl ds
= sdocWithDynFlags $ \dflags ->
hcat [ pprLocalness lbl, text "StgWord"
- , space, ppr lbl, text "[] = {" ]
+ , space, ppr lbl, text "[]"
+ -- See Note [StgWord alignment]
+ , pprAlignment (wordWidth dflags)
+ , text "= {" ]
$$ nest 8 (commafy (pprStatics dflags ds))
$$ text "};"
+pprAlignment :: Width -> SDoc
+pprAlignment words =
+ text "__attribute__((aligned(" <> int (widthInBytes words) <> text ")))"
+
+-- Note [StgWord alignment]
+-- C codegen builds static closures as StgWord C arrays (pprWordArray).
+-- Their real C type is 'StgClosure'. Macros like UNTAG_CLOSURE assume
+-- pointers to 'StgClosure' are aligned at pointer size boundary:
+-- 4 byte boundary on 32 systems
+-- and 8 bytes on 64-bit systems
+-- see TAG_MASK and TAG_BITS definition and usage.
+--
+-- It's a reasonable assumption also known as natural alignment.
+-- Although some architectures have different alignment rules.
+-- One of known exceptions is m68k (Trac #11395, comment:16) where:
+-- __alignof__(StgWord) == 2, sizeof(StgWord) == 4
+--
+-- Thus we explicitly increase alignment by using
+-- __attribute__((aligned(4)))
+-- declaration.
+
--
-- has to be static, if it isn't globally visible
--