Commit ade1a461 authored by Sergei Trofimovich's avatar Sergei Trofimovich Committed by Sergei Trofimovich

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: default avatarSergei 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
parent bd681bce
......@@ -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
--
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment