summaryrefslogtreecommitdiff
path: root/compiler/nativeGen
diff options
context:
space:
mode:
authorBen Gamari <bgamari.foss@gmail.com>2017-10-29 20:46:45 -0400
committerBen Gamari <ben@smart-cactus.org>2017-10-29 20:47:05 -0400
commitcecd2f2d708d419878205ddd8b87bba18e6483d9 (patch)
tree72837286086fb64d3b458d14cb95c13425cca8ea /compiler/nativeGen
parent3b784d440d4b01b4c549df7c9a3ed2058edfc780 (diff)
downloadhaskell-cecd2f2d708d419878205ddd8b87bba18e6483d9.tar.gz
Add -falignment-sanitization flag
Here we add a flag to instruct the native code generator to add alignment checks in all info table dereferences. This is helpful in catching pointer tagging issues. Thanks to @jrtc27 for uncovering the tagging issues on Sparc which inspired this flag. Test Plan: Validate Reviewers: simonmar, austin, erikd Reviewed By: simonmar Subscribers: rwbarton, trofi, thomie, jrtc27 Differential Revision: https://phabricator.haskell.org/D4101
Diffstat (limited to 'compiler/nativeGen')
-rw-r--r--compiler/nativeGen/X86/CodeGen.hs18
1 files changed, 18 insertions, 0 deletions
diff --git a/compiler/nativeGen/X86/CodeGen.hs b/compiler/nativeGen/X86/CodeGen.hs
index 029b8e8336..d6ef6d3b65 100644
--- a/compiler/nativeGen/X86/CodeGen.hs
+++ b/compiler/nativeGen/X86/CodeGen.hs
@@ -502,6 +502,9 @@ getRegister' dflags is32Bit (CmmReg reg)
getRegister' dflags is32Bit (CmmRegOff r n)
= getRegister' dflags is32Bit $ mangleIndexTree dflags r n
+getRegister' dflags is32Bit (CmmMachOp (MO_AlignmentCheck align _) [e])
+ = addAlignmentCheck align <$> getRegister' dflags is32Bit e
+
-- for 32-bit architectuers, support some 64 -> 32 bit conversions:
-- TO_W_(x), TO_W_(x >> 32)
@@ -1254,6 +1257,21 @@ isOperand is32Bit (CmmLit lit) = is32BitLit is32Bit lit
|| isSuitableFloatingPointLit lit
isOperand _ _ = False
+-- | Given a 'Register', produce a new 'Register' with an instruction block
+-- which will check the value for alignment. Used for @-falignment-sanitisation@.
+addAlignmentCheck :: Int -> Register -> Register
+addAlignmentCheck align reg =
+ case reg of
+ Fixed fmt reg code -> Fixed fmt reg (code `appOL` check fmt reg)
+ Any fmt f -> Any fmt (\reg -> f reg `appOL` check fmt reg)
+ where
+ check :: Format -> Reg -> InstrBlock
+ check fmt reg =
+ ASSERT(not $ isFloatFormat fmt)
+ toOL [ TEST fmt (OpImm $ ImmInt $ align-1) (OpReg reg)
+ , JXX_GBL NE $ ImmCLbl mkBadAlignmentLabel
+ ]
+
memConstant :: Int -> CmmLit -> NatM Amode
memConstant align lit = do
lbl <- getNewLabelNat