summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <bgamari.foss@gmail.com>2015-10-30 20:49:35 +0100
committerBen Gamari <ben@smart-cactus.org>2015-11-01 15:19:47 +0100
commit6fb0ba65d27602ae9a81fe142936b06d54b20b2e (patch)
tree223208e34e9d6d70b0232a5c56f3d8c8be6539e6
parent3431ad6faeb2b74e10c8ac4d42bdbc4521e07e33 (diff)
downloadhaskell-6fb0ba65d27602ae9a81fe142936b06d54b20b2e.tar.gz
Dwarf: Preserve stack pointer register
Here we add a `same_value $sp` instruction to our default unwinding rules to ensure that the implicit `$sp = CFA` rule (which `libdw` appears to exhibit on x86_64) doesn't overwrite it (necessary since we don't use $sp to track our call stack). See Phab Diff D1189 for details on how we arrived at this resolution. Reviewers: scpmw, austin, simonmar Reviewed By: austin, simonmar Subscribers: thomie, simonmar Differential Revision: https://phabricator.haskell.org/D1224
-rw-r--r--compiler/nativeGen/Dwarf/Types.hs12
1 files changed, 11 insertions, 1 deletions
diff --git a/compiler/nativeGen/Dwarf/Types.hs b/compiler/nativeGen/Dwarf/Types.hs
index a2d07b87ba..d558c2d1fa 100644
--- a/compiler/nativeGen/Dwarf/Types.hs
+++ b/compiler/nativeGen/Dwarf/Types.hs
@@ -231,6 +231,13 @@ pprDwarfFrame DwarfFrame{dwCieLabel=cieLabel,dwCieInit=cieInit,dwCieProcs=procs}
retReg = dwarfReturnRegNo plat
wordSize = platformWordSize plat
pprInit (g, uw) = pprSetUnwind plat g (Nothing, uw)
+
+ -- Preserve C stack pointer: This necessary to override that default
+ -- unwinding behavior of setting $sp = CFA.
+ preserveSp = case platformArch plat of
+ ArchX86 -> pprByte dW_CFA_same_value $$ pprLEBWord 4
+ ArchX86_64 -> pprByte dW_CFA_same_value $$ pprLEBWord 7
+ _ -> empty
in vcat [ ppr cieLabel <> colon
, pprData4' length -- Length of CIE
, ppr cieStartLabel <> colon
@@ -250,8 +257,11 @@ pprDwarfFrame DwarfFrame{dwCieLabel=cieLabel,dwCieInit=cieInit,dwCieProcs=procs}
pprByte (dW_CFA_offset+retReg)
, pprByte 0
+ -- Preserve C stack pointer
+ , preserveSp
+
-- Sp' = CFA
- -- (we need to set this manually as our Sp register is
+ -- (we need to set this manually as our (STG) Sp register is
-- often not the architecture's default stack register)
, pprByte dW_CFA_val_offset
, pprLEBWord (fromIntegral spReg)