Commit 6fb0ba65 authored by Ben Gamari's avatar Ben Gamari Committed by Ben Gamari

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
parent 3431ad6f
......@@ -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)
......
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