diff options
author | Ben Gamari <bgamari.foss@gmail.com> | 2017-10-29 20:46:45 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2017-10-29 20:47:05 -0400 |
commit | cecd2f2d708d419878205ddd8b87bba18e6483d9 (patch) | |
tree | 72837286086fb64d3b458d14cb95c13425cca8ea /compiler/nativeGen | |
parent | 3b784d440d4b01b4c549df7c9a3ed2058edfc780 (diff) | |
download | haskell-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.hs | 18 |
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 |