module GHC.CmmToAsm.Dwarf (
  dwarfGen
  ) where
import GHC.Prelude
import GHC.Cmm.CLabel
import GHC.Cmm.Expr        ( GlobalReg(..) )
import GHC.Settings.Config ( cProjectName, cProjectVersion )
import GHC.Types.Tickish   ( CmmTickish, GenTickish(..) )
import GHC.Cmm.DebugBlock
import GHC.Unit.Module
import GHC.Utils.Outputable
import GHC.Platform
import GHC.Types.Unique
import GHC.Types.Unique.Supply
import GHC.CmmToAsm.Dwarf.Constants
import GHC.CmmToAsm.Dwarf.Types
import GHC.CmmToAsm.Config
import Control.Arrow    ( first )
import Control.Monad    ( mfilter )
import Data.Maybe
import Data.List        ( sortBy )
import Data.Ord         ( comparing )
import qualified Data.Map as Map
import System.FilePath
import System.Directory ( getCurrentDirectory )
import qualified GHC.Cmm.Dataflow.Label as H
import qualified GHC.Cmm.Dataflow.Collections as H
dwarfGen :: NCGConfig -> ModLocation -> UniqSupply -> [DebugBlock]
            -> IO (SDoc, UniqSupply)
dwarfGen :: NCGConfig
-> ModLocation
-> UniqSupply
-> [DebugBlock]
-> IO (SDoc, UniqSupply)
dwarfGen NCGConfig
_      ModLocation
_      UniqSupply
us []     = (SDoc, UniqSupply) -> IO (SDoc, UniqSupply)
forall (m :: * -> *) a. Monad m => a -> m a
return (SDoc
empty, UniqSupply
us)
dwarfGen NCGConfig
config ModLocation
modLoc UniqSupply
us [DebugBlock]
blocks = do
  let platform :: Platform
platform = NCGConfig -> Platform
ncgPlatform NCGConfig
config
  
  let procs :: [DebugBlock]
procs = [DebugBlock] -> [DebugBlock]
debugSplitProcs [DebugBlock]
blocks
      stripBlocks :: DebugBlock -> DebugBlock
stripBlocks DebugBlock
dbg
        | NCGConfig -> Bool
ncgDwarfStripBlockInfo NCGConfig
config = DebugBlock
dbg { dblBlocks :: [DebugBlock]
dblBlocks = [] }
        | Bool
otherwise                     = DebugBlock
dbg
  FilePath
compPath <- IO FilePath
getCurrentDirectory
  let lowLabel :: CLabel
lowLabel = DebugBlock -> CLabel
dblCLabel (DebugBlock -> CLabel) -> DebugBlock -> CLabel
forall a b. (a -> b) -> a -> b
$ [DebugBlock] -> DebugBlock
forall a. [a] -> a
head [DebugBlock]
procs
      highLabel :: CLabel
highLabel = CLabel -> CLabel
mkAsmTempProcEndLabel (CLabel -> CLabel) -> CLabel -> CLabel
forall a b. (a -> b) -> a -> b
$ DebugBlock -> CLabel
dblCLabel (DebugBlock -> CLabel) -> DebugBlock -> CLabel
forall a b. (a -> b) -> a -> b
$ [DebugBlock] -> DebugBlock
forall a. [a] -> a
last [DebugBlock]
procs
      dwarfUnit :: DwarfInfo
dwarfUnit = DwarfCompileUnit
        { dwChildren :: [DwarfInfo]
dwChildren = (DebugBlock -> DwarfInfo) -> [DebugBlock] -> [DwarfInfo]
forall a b. (a -> b) -> [a] -> [b]
map (NCGConfig -> DebugBlock -> DwarfInfo
procToDwarf NCGConfig
config) ((DebugBlock -> DebugBlock) -> [DebugBlock] -> [DebugBlock]
forall a b. (a -> b) -> [a] -> [b]
map DebugBlock -> DebugBlock
stripBlocks [DebugBlock]
procs)
        , dwName :: FilePath
dwName = FilePath -> Maybe FilePath -> FilePath
forall a. a -> Maybe a -> a
fromMaybe FilePath
"" (ModLocation -> Maybe FilePath
ml_hs_file ModLocation
modLoc)
        , dwCompDir :: FilePath
dwCompDir = FilePath -> FilePath
addTrailingPathSeparator FilePath
compPath
        , dwProducer :: FilePath
dwProducer = FilePath
cProjectName FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
" " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
cProjectVersion
        , dwLowLabel :: CLabel
dwLowLabel = CLabel
lowLabel
        , dwHighLabel :: CLabel
dwHighLabel = CLabel
highLabel
        , dwLineLabel :: PtrString
dwLineLabel = PtrString
dwarfLineLabel
        }
  
  
  
  let haveSrcIn :: DebugBlock -> Bool
haveSrcIn DebugBlock
blk = Maybe CmmTickish -> Bool
forall a. Maybe a -> Bool
isJust (DebugBlock -> Maybe CmmTickish
dblSourceTick DebugBlock
blk) Bool -> Bool -> Bool
&& Maybe Int -> Bool
forall a. Maybe a -> Bool
isJust (DebugBlock -> Maybe Int
dblPosition DebugBlock
blk)
                      Bool -> Bool -> Bool
|| (DebugBlock -> Bool) -> [DebugBlock] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any DebugBlock -> Bool
haveSrcIn (DebugBlock -> [DebugBlock]
dblBlocks DebugBlock
blk)
      haveSrc :: Bool
haveSrc = (DebugBlock -> Bool) -> [DebugBlock] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any DebugBlock -> Bool
haveSrcIn [DebugBlock]
procs
  
  let abbrevSct :: SDoc
abbrevSct = Platform -> Bool -> SDoc
pprAbbrevDecls Platform
platform Bool
haveSrc
  
  let 
      (Unique
unitU, UniqSupply
us') = UniqSupply -> (Unique, UniqSupply)
takeUniqFromSupply UniqSupply
us
      infoSct :: SDoc
infoSct = [SDoc] -> SDoc
vcat [ PtrString -> SDoc
ptext PtrString
dwarfInfoLabel SDoc -> SDoc -> SDoc
<> SDoc
colon
                     , Platform -> SDoc
dwarfInfoSection Platform
platform
                     , Platform -> Unique -> SDoc
compileUnitHeader Platform
platform Unique
unitU
                     , Platform -> Bool -> DwarfInfo -> SDoc
pprDwarfInfo Platform
platform Bool
haveSrc DwarfInfo
dwarfUnit
                     , Platform -> Unique -> SDoc
compileUnitFooter Platform
platform Unique
unitU
                     ]
  
  
  let lineSct :: SDoc
lineSct = Platform -> SDoc
dwarfLineSection Platform
platform SDoc -> SDoc -> SDoc
$$
                PtrString -> SDoc
ptext PtrString
dwarfLineLabel SDoc -> SDoc -> SDoc
<> SDoc
colon
  
  let (Unique
framesU, UniqSupply
us'') = UniqSupply -> (Unique, UniqSupply)
takeUniqFromSupply UniqSupply
us'
      frameSct :: SDoc
frameSct = Platform -> SDoc
dwarfFrameSection Platform
platform SDoc -> SDoc -> SDoc
$$
                 PtrString -> SDoc
ptext PtrString
dwarfFrameLabel SDoc -> SDoc -> SDoc
<> SDoc
colon SDoc -> SDoc -> SDoc
$$
                 Platform -> DwarfFrame -> SDoc
pprDwarfFrame Platform
platform (Unique -> [DebugBlock] -> DwarfFrame
debugFrame Unique
framesU [DebugBlock]
procs)
  
  let aranges' :: [DwarfARange]
aranges' | NCGConfig -> Bool
ncgSplitSections NCGConfig
config = (DebugBlock -> DwarfARange) -> [DebugBlock] -> [DwarfARange]
forall a b. (a -> b) -> [a] -> [b]
map DebugBlock -> DwarfARange
mkDwarfARange [DebugBlock]
procs
               | Bool
otherwise               = [CLabel -> CLabel -> DwarfARange
DwarfARange CLabel
lowLabel CLabel
highLabel]
  let aranges :: SDoc
aranges = Platform -> SDoc
dwarfARangesSection Platform
platform SDoc -> SDoc -> SDoc
$$ Platform -> [DwarfARange] -> Unique -> SDoc
pprDwarfARanges Platform
platform [DwarfARange]
aranges' Unique
unitU
  (SDoc, UniqSupply) -> IO (SDoc, UniqSupply)
forall (m :: * -> *) a. Monad m => a -> m a
return (SDoc
infoSct SDoc -> SDoc -> SDoc
$$ SDoc
abbrevSct SDoc -> SDoc -> SDoc
$$ SDoc
lineSct SDoc -> SDoc -> SDoc
$$ SDoc
frameSct SDoc -> SDoc -> SDoc
$$ SDoc
aranges, UniqSupply
us'')
mkDwarfARange :: DebugBlock -> DwarfARange
mkDwarfARange :: DebugBlock -> DwarfARange
mkDwarfARange DebugBlock
proc = CLabel -> CLabel -> DwarfARange
DwarfARange CLabel
lbl CLabel
end
  where
    lbl :: CLabel
lbl = DebugBlock -> CLabel
dblCLabel DebugBlock
proc
    end :: CLabel
end = CLabel -> CLabel
mkAsmTempProcEndLabel CLabel
lbl
compileUnitHeader :: Platform -> Unique -> SDoc
 Platform
platform Unique
unitU =
  let cuLabel :: CLabel
cuLabel = Unique -> CLabel
forall a. Uniquable a => a -> CLabel
mkAsmTempLabel Unique
unitU  
      length :: SDoc
length = Platform -> CLabel -> SDoc
forall env a. OutputableP env a => env -> a -> SDoc
pdoc Platform
platform (CLabel -> CLabel
mkAsmTempEndLabel CLabel
cuLabel) SDoc -> SDoc -> SDoc
<> Char -> SDoc
char Char
'-' SDoc -> SDoc -> SDoc
<> Platform -> CLabel -> SDoc
forall env a. OutputableP env a => env -> a -> SDoc
pdoc Platform
platform CLabel
cuLabel
               SDoc -> SDoc -> SDoc
<> FilePath -> SDoc
text FilePath
"-4"       
  in [SDoc] -> SDoc
vcat [ Platform -> CLabel -> SDoc
forall env a. OutputableP env a => env -> a -> SDoc
pdoc Platform
platform CLabel
cuLabel SDoc -> SDoc -> SDoc
<> SDoc
colon
          , FilePath -> SDoc
text FilePath
"\t.long " SDoc -> SDoc -> SDoc
<> SDoc
length  
          , Word16 -> SDoc
pprHalf Word16
3                          
          , Platform -> SDoc -> SDoc -> SDoc
sectionOffset Platform
platform (PtrString -> SDoc
ptext PtrString
dwarfAbbrevLabel) (PtrString -> SDoc
ptext PtrString
dwarfAbbrevLabel)
                                               
          , FilePath -> SDoc
text FilePath
"\t.byte " SDoc -> SDoc -> SDoc
<> Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Platform -> Int
platformWordSizeInBytes Platform
platform) 
          ]
compileUnitFooter :: Platform -> Unique -> SDoc
 Platform
platform Unique
unitU =
  let cuEndLabel :: CLabel
cuEndLabel = CLabel -> CLabel
mkAsmTempEndLabel (CLabel -> CLabel) -> CLabel -> CLabel
forall a b. (a -> b) -> a -> b
$ Unique -> CLabel
forall a. Uniquable a => a -> CLabel
mkAsmTempLabel Unique
unitU
  in Platform -> CLabel -> SDoc
forall env a. OutputableP env a => env -> a -> SDoc
pdoc Platform
platform CLabel
cuEndLabel SDoc -> SDoc -> SDoc
<> SDoc
colon
debugSplitProcs :: [DebugBlock] -> [DebugBlock]
debugSplitProcs :: [DebugBlock] -> [DebugBlock]
debugSplitProcs [DebugBlock]
b = [[DebugBlock]] -> [DebugBlock]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[DebugBlock]] -> [DebugBlock]) -> [[DebugBlock]] -> [DebugBlock]
forall a b. (a -> b) -> a -> b
$ LabelMap [DebugBlock] -> [[DebugBlock]]
forall (map :: * -> *) a. IsMap map => map a -> [a]
H.mapElems (LabelMap [DebugBlock] -> [[DebugBlock]])
-> LabelMap [DebugBlock] -> [[DebugBlock]]
forall a b. (a -> b) -> a -> b
$ [LabelMap [DebugBlock]] -> LabelMap [DebugBlock]
forall {a}. [LabelMap [a]] -> LabelMap [a]
mergeMaps ([LabelMap [DebugBlock]] -> LabelMap [DebugBlock])
-> [LabelMap [DebugBlock]] -> LabelMap [DebugBlock]
forall a b. (a -> b) -> a -> b
$ (DebugBlock -> LabelMap [DebugBlock])
-> [DebugBlock] -> [LabelMap [DebugBlock]]
forall a b. (a -> b) -> [a] -> [b]
map (Maybe DebugBlock -> DebugBlock -> LabelMap [DebugBlock]
split Maybe DebugBlock
forall a. Maybe a
Nothing) [DebugBlock]
b
  where mergeMaps :: [LabelMap [a]] -> LabelMap [a]
mergeMaps = (LabelMap [a] -> LabelMap [a] -> LabelMap [a])
-> LabelMap [a] -> [LabelMap [a]] -> LabelMap [a]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((KeyOf LabelMap -> [a] -> [a] -> [a])
-> LabelMap [a] -> LabelMap [a] -> LabelMap [a]
forall (map :: * -> *) a.
IsMap map =>
(KeyOf map -> a -> a -> a) -> map a -> map a -> map a
H.mapUnionWithKey (([a] -> [a] -> [a]) -> KeyOf LabelMap -> [a] -> [a] -> [a]
forall a b. a -> b -> a
const [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
(++))) LabelMap [a]
forall (map :: * -> *) a. IsMap map => map a
H.mapEmpty
        split :: Maybe DebugBlock -> DebugBlock -> H.LabelMap [DebugBlock]
        split :: Maybe DebugBlock -> DebugBlock -> LabelMap [DebugBlock]
split Maybe DebugBlock
parent DebugBlock
blk = KeyOf LabelMap
-> [DebugBlock] -> LabelMap [DebugBlock] -> LabelMap [DebugBlock]
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> a -> map a -> map a
H.mapInsert KeyOf LabelMap
Label
prc [DebugBlock
blk'] LabelMap [DebugBlock]
nested
          where prc :: Label
prc = DebugBlock -> Label
dblProcedure DebugBlock
blk
                blk' :: DebugBlock
blk' = DebugBlock
blk { dblBlocks :: [DebugBlock]
dblBlocks = [DebugBlock]
own_blks
                           , dblParent :: Maybe DebugBlock
dblParent = Maybe DebugBlock
parent
                           }
                own_blks :: [DebugBlock]
own_blks = [DebugBlock] -> Maybe [DebugBlock] -> [DebugBlock]
forall a. a -> Maybe a -> a
fromMaybe [] (Maybe [DebugBlock] -> [DebugBlock])
-> Maybe [DebugBlock] -> [DebugBlock]
forall a b. (a -> b) -> a -> b
$ KeyOf LabelMap -> LabelMap [DebugBlock] -> Maybe [DebugBlock]
forall (map :: * -> *) a.
IsMap map =>
KeyOf map -> map a -> Maybe a
H.mapLookup KeyOf LabelMap
Label
prc LabelMap [DebugBlock]
nested
                nested :: LabelMap [DebugBlock]
nested = [LabelMap [DebugBlock]] -> LabelMap [DebugBlock]
forall {a}. [LabelMap [a]] -> LabelMap [a]
mergeMaps ([LabelMap [DebugBlock]] -> LabelMap [DebugBlock])
-> [LabelMap [DebugBlock]] -> LabelMap [DebugBlock]
forall a b. (a -> b) -> a -> b
$ (DebugBlock -> LabelMap [DebugBlock])
-> [DebugBlock] -> [LabelMap [DebugBlock]]
forall a b. (a -> b) -> [a] -> [b]
map (Maybe DebugBlock -> DebugBlock -> LabelMap [DebugBlock]
split Maybe DebugBlock
parent') ([DebugBlock] -> [LabelMap [DebugBlock]])
-> [DebugBlock] -> [LabelMap [DebugBlock]]
forall a b. (a -> b) -> a -> b
$ DebugBlock -> [DebugBlock]
dblBlocks DebugBlock
blk
                
                
                
                parent' :: Maybe DebugBlock
parent'
                  | Maybe Int
Nothing <- DebugBlock -> Maybe Int
dblPosition DebugBlock
blk = Maybe DebugBlock
parent
                  | Bool
otherwise                  = DebugBlock -> Maybe DebugBlock
forall a. a -> Maybe a
Just DebugBlock
blk
procToDwarf :: NCGConfig -> DebugBlock -> DwarfInfo
procToDwarf :: NCGConfig -> DebugBlock -> DwarfInfo
procToDwarf NCGConfig
config DebugBlock
prc
  = DwarfSubprogram { dwChildren :: [DwarfInfo]
dwChildren = (DebugBlock -> DwarfInfo) -> [DebugBlock] -> [DwarfInfo]
forall a b. (a -> b) -> [a] -> [b]
map (NCGConfig -> DebugBlock -> DwarfInfo
blockToDwarf NCGConfig
config) (DebugBlock -> [DebugBlock]
dblBlocks DebugBlock
prc)
                    , dwName :: FilePath
dwName     = case DebugBlock -> Maybe CmmTickish
dblSourceTick DebugBlock
prc of
                         Just s :: CmmTickish
s@SourceNote{} -> CmmTickish -> FilePath
forall (pass :: TickishPass). GenTickish pass -> FilePath
sourceName CmmTickish
s
                         Maybe CmmTickish
_otherwise -> Label -> FilePath
forall a. Show a => a -> FilePath
show (DebugBlock -> Label
dblLabel DebugBlock
prc)
                    , dwLabel :: CLabel
dwLabel    = DebugBlock -> CLabel
dblCLabel DebugBlock
prc
                    , dwParent :: Maybe CLabel
dwParent   = (CLabel -> CLabel) -> Maybe CLabel -> Maybe CLabel
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CLabel -> CLabel
mkAsmTempDieLabel
                                   (Maybe CLabel -> Maybe CLabel) -> Maybe CLabel -> Maybe CLabel
forall a b. (a -> b) -> a -> b
$ (CLabel -> Bool) -> Maybe CLabel -> Maybe CLabel
forall (m :: * -> *) a. MonadPlus m => (a -> Bool) -> m a -> m a
mfilter CLabel -> Bool
goodParent
                                   (Maybe CLabel -> Maybe CLabel) -> Maybe CLabel -> Maybe CLabel
forall a b. (a -> b) -> a -> b
$ (DebugBlock -> CLabel) -> Maybe DebugBlock -> Maybe CLabel
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap DebugBlock -> CLabel
dblCLabel (DebugBlock -> Maybe DebugBlock
dblParent DebugBlock
prc)
                    }
  where
  goodParent :: CLabel -> Bool
goodParent CLabel
a | CLabel
a CLabel -> CLabel -> Bool
forall a. Eq a => a -> a -> Bool
== DebugBlock -> CLabel
dblCLabel DebugBlock
prc = Bool
False
               
  goodParent CLabel
a | Bool -> Bool
not (CLabel -> Bool
externallyVisibleCLabel CLabel
a)
               , NCGConfig -> Bool
ncgDwarfStripBlockInfo NCGConfig
config = Bool
False
               
               
  goodParent CLabel
_ = Bool
True
blockToDwarf :: NCGConfig -> DebugBlock -> DwarfInfo
blockToDwarf :: NCGConfig -> DebugBlock -> DwarfInfo
blockToDwarf NCGConfig
config DebugBlock
blk
  = DwarfBlock { dwChildren :: [DwarfInfo]
dwChildren = (DebugBlock -> DwarfInfo) -> [DebugBlock] -> [DwarfInfo]
forall a b. (a -> b) -> [a] -> [b]
map (NCGConfig -> DebugBlock -> DwarfInfo
blockToDwarf NCGConfig
config) (DebugBlock -> [DebugBlock]
dblBlocks DebugBlock
blk) [DwarfInfo] -> [DwarfInfo] -> [DwarfInfo]
forall a. [a] -> [a] -> [a]
++ [DwarfInfo]
srcNotes
               , dwLabel :: CLabel
dwLabel    = DebugBlock -> CLabel
dblCLabel DebugBlock
blk
               , dwMarker :: Maybe CLabel
dwMarker   = Maybe CLabel
marker
               }
  where
    srcNotes :: [DwarfInfo]
srcNotes
      | NCGConfig -> Bool
ncgDwarfSourceNotes NCGConfig
config = (CmmTickish -> [DwarfInfo]) -> [CmmTickish] -> [DwarfInfo]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap CmmTickish -> [DwarfInfo]
tickToDwarf (DebugBlock -> [CmmTickish]
dblTicks DebugBlock
blk)
      | Bool
otherwise                  = []
    marker :: Maybe CLabel
marker
      | Just Int
_ <- DebugBlock -> Maybe Int
dblPosition DebugBlock
blk = CLabel -> Maybe CLabel
forall a. a -> Maybe a
Just (CLabel -> Maybe CLabel) -> CLabel -> Maybe CLabel
forall a b. (a -> b) -> a -> b
$ Label -> CLabel
forall a. Uniquable a => a -> CLabel
mkAsmTempLabel (Label -> CLabel) -> Label -> CLabel
forall a b. (a -> b) -> a -> b
$ DebugBlock -> Label
dblLabel DebugBlock
blk
      | Bool
otherwise                 = Maybe CLabel
forall a. Maybe a
Nothing   
tickToDwarf :: CmmTickish -> [DwarfInfo]
tickToDwarf :: CmmTickish -> [DwarfInfo]
tickToDwarf  (SourceNote RealSrcSpan
ss FilePath
_) = [RealSrcSpan -> DwarfInfo
DwarfSrcNote RealSrcSpan
ss]
tickToDwarf CmmTickish
_ = []
debugFrame :: Unique -> [DebugBlock] -> DwarfFrame
debugFrame :: Unique -> [DebugBlock] -> DwarfFrame
debugFrame Unique
u [DebugBlock]
procs
  = DwarfFrame { dwCieLabel :: CLabel
dwCieLabel = Unique -> CLabel
forall a. Uniquable a => a -> CLabel
mkAsmTempLabel Unique
u
               , dwCieInit :: UnwindTable
dwCieInit  = UnwindTable
initUws
               , dwCieProcs :: [DwarfFrameProc]
dwCieProcs = (DebugBlock -> DwarfFrameProc) -> [DebugBlock] -> [DwarfFrameProc]
forall a b. (a -> b) -> [a] -> [b]
map (UnwindTable -> DebugBlock -> DwarfFrameProc
procToFrame UnwindTable
initUws) [DebugBlock]
procs
               }
  where
    initUws :: UnwindTable
    initUws :: UnwindTable
initUws = [(GlobalReg, Maybe UnwindExpr)] -> UnwindTable
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(GlobalReg
Sp, UnwindExpr -> Maybe UnwindExpr
forall a. a -> Maybe a
Just (GlobalReg -> Int -> UnwindExpr
UwReg GlobalReg
Sp Int
0))]
procToFrame :: UnwindTable -> DebugBlock -> DwarfFrameProc
procToFrame :: UnwindTable -> DebugBlock -> DwarfFrameProc
procToFrame UnwindTable
initUws DebugBlock
blk
  = DwarfFrameProc { dwFdeProc :: CLabel
dwFdeProc    = DebugBlock -> CLabel
dblCLabel DebugBlock
blk
                   , dwFdeHasInfo :: Bool
dwFdeHasInfo = DebugBlock -> Bool
dblHasInfoTbl DebugBlock
blk
                   , dwFdeBlocks :: [DwarfFrameBlock]
dwFdeBlocks  = ((DebugBlock, [UnwindPoint]) -> DwarfFrameBlock)
-> [(DebugBlock, [UnwindPoint])] -> [DwarfFrameBlock]
forall a b. (a -> b) -> [a] -> [b]
map ((DebugBlock -> [UnwindPoint] -> DwarfFrameBlock)
-> (DebugBlock, [UnwindPoint]) -> DwarfFrameBlock
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry DebugBlock -> [UnwindPoint] -> DwarfFrameBlock
blockToFrame)
                                        ([(DebugBlock, [UnwindPoint])] -> [(DebugBlock, [UnwindPoint])]
setHasInfo [(DebugBlock, [UnwindPoint])]
blockUws)
                   }
  where blockUws :: [(DebugBlock, [UnwindPoint])]
        blockUws :: [(DebugBlock, [UnwindPoint])]
blockUws = ((Int, (DebugBlock, [UnwindPoint])) -> (DebugBlock, [UnwindPoint]))
-> [(Int, (DebugBlock, [UnwindPoint]))]
-> [(DebugBlock, [UnwindPoint])]
forall a b. (a -> b) -> [a] -> [b]
map (Int, (DebugBlock, [UnwindPoint])) -> (DebugBlock, [UnwindPoint])
forall a b. (a, b) -> b
snd ([(Int, (DebugBlock, [UnwindPoint]))]
 -> [(DebugBlock, [UnwindPoint])])
-> [(Int, (DebugBlock, [UnwindPoint]))]
-> [(DebugBlock, [UnwindPoint])]
forall a b. (a -> b) -> a -> b
$ ((Int, (DebugBlock, [UnwindPoint]))
 -> (Int, (DebugBlock, [UnwindPoint])) -> Ordering)
-> [(Int, (DebugBlock, [UnwindPoint]))]
-> [(Int, (DebugBlock, [UnwindPoint]))]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (((Int, (DebugBlock, [UnwindPoint])) -> Int)
-> (Int, (DebugBlock, [UnwindPoint]))
-> (Int, (DebugBlock, [UnwindPoint]))
-> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (Int, (DebugBlock, [UnwindPoint])) -> Int
forall a b. (a, b) -> a
fst) ([(Int, (DebugBlock, [UnwindPoint]))]
 -> [(Int, (DebugBlock, [UnwindPoint]))])
-> [(Int, (DebugBlock, [UnwindPoint]))]
-> [(Int, (DebugBlock, [UnwindPoint]))]
forall a b. (a -> b) -> a -> b
$ DebugBlock -> [(Int, (DebugBlock, [UnwindPoint]))]
flatten DebugBlock
blk
        flatten :: DebugBlock
                -> [(Int, (DebugBlock, [UnwindPoint]))]
        flatten :: DebugBlock -> [(Int, (DebugBlock, [UnwindPoint]))]
flatten b :: DebugBlock
b@DebugBlock{ dblPosition :: DebugBlock -> Maybe Int
dblPosition=Maybe Int
pos, dblUnwind :: DebugBlock -> [UnwindPoint]
dblUnwind=[UnwindPoint]
uws, dblBlocks :: DebugBlock -> [DebugBlock]
dblBlocks=[DebugBlock]
blocks }
          | Just Int
p <- Maybe Int
pos  = (Int
p, (DebugBlock
b, [UnwindPoint]
uws'))(Int, (DebugBlock, [UnwindPoint]))
-> [(Int, (DebugBlock, [UnwindPoint]))]
-> [(Int, (DebugBlock, [UnwindPoint]))]
forall a. a -> [a] -> [a]
:[(Int, (DebugBlock, [UnwindPoint]))]
nested
          | Bool
otherwise      = [(Int, (DebugBlock, [UnwindPoint]))]
nested 
          where uws' :: [UnwindPoint]
uws'   = UnwindTable -> [UnwindPoint] -> [UnwindPoint]
addDefaultUnwindings UnwindTable
initUws [UnwindPoint]
uws
                nested :: [(Int, (DebugBlock, [UnwindPoint]))]
nested = (DebugBlock -> [(Int, (DebugBlock, [UnwindPoint]))])
-> [DebugBlock] -> [(Int, (DebugBlock, [UnwindPoint]))]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap DebugBlock -> [(Int, (DebugBlock, [UnwindPoint]))]
flatten [DebugBlock]
blocks
        
        
        
        
        setHasInfo :: [(DebugBlock, [UnwindPoint])]
                   -> [(DebugBlock, [UnwindPoint])]
        setHasInfo :: [(DebugBlock, [UnwindPoint])] -> [(DebugBlock, [UnwindPoint])]
setHasInfo [] = []
        setHasInfo ((DebugBlock, [UnwindPoint])
c0:[(DebugBlock, [UnwindPoint])]
cs) = (DebugBlock -> DebugBlock)
-> (DebugBlock, [UnwindPoint]) -> (DebugBlock, [UnwindPoint])
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first DebugBlock -> DebugBlock
setIt (DebugBlock, [UnwindPoint])
c0 (DebugBlock, [UnwindPoint])
-> [(DebugBlock, [UnwindPoint])] -> [(DebugBlock, [UnwindPoint])]
forall a. a -> [a] -> [a]
: [(DebugBlock, [UnwindPoint])]
cs
          where
            setIt :: DebugBlock -> DebugBlock
setIt DebugBlock
child =
              DebugBlock
child { dblHasInfoTbl :: Bool
dblHasInfoTbl = DebugBlock -> Bool
dblHasInfoTbl DebugBlock
child
                                      Bool -> Bool -> Bool
|| DebugBlock -> Bool
dblHasInfoTbl DebugBlock
blk }
blockToFrame :: DebugBlock -> [UnwindPoint] -> DwarfFrameBlock
blockToFrame :: DebugBlock -> [UnwindPoint] -> DwarfFrameBlock
blockToFrame DebugBlock
blk [UnwindPoint]
uws
  = DwarfFrameBlock { dwFdeBlkHasInfo :: Bool
dwFdeBlkHasInfo = DebugBlock -> Bool
dblHasInfoTbl DebugBlock
blk
                    , dwFdeUnwind :: [UnwindPoint]
dwFdeUnwind     = [UnwindPoint]
uws
                    }
addDefaultUnwindings :: UnwindTable -> [UnwindPoint] -> [UnwindPoint]
addDefaultUnwindings :: UnwindTable -> [UnwindPoint] -> [UnwindPoint]
addDefaultUnwindings UnwindTable
tbl [UnwindPoint]
pts =
    [ CLabel -> UnwindTable -> UnwindPoint
UnwindPoint CLabel
lbl (UnwindTable
tbl' UnwindTable -> UnwindTable -> UnwindTable
forall a. Monoid a => a -> a -> a
`mappend` UnwindTable
tbl)
      
    | UnwindPoint CLabel
lbl UnwindTable
tbl' <- [UnwindPoint]
pts
    ]