module Dwarf.Types
(
DwarfInfo(..)
, pprDwarfInfo
, pprAbbrevDecls
, DwarfARange(..)
, pprDwarfARanges
, DwarfFrame(..), DwarfFrameProc(..), DwarfFrameBlock(..)
, pprDwarfFrame
, pprByte
, pprHalf
, pprData4'
, pprDwWord
, pprWord
, pprLEBWord
, pprLEBInt
, wordAlign
, sectionOffset
)
where
import GhcPrelude
import Debug
import CLabel
import CmmExpr ( GlobalReg(..) )
import Encoding
import FastString
import Outputable
import Platform
import Unique
import Reg
import SrcLoc
import Util
import Dwarf.Constants
import qualified Control.Monad.Trans.State.Strict as S
import Control.Monad (zipWithM, join)
import Data.Bits
import qualified Data.Map as Map
import Data.Word
import Data.Char
import CodeGen.Platform
data DwarfInfo
= DwarfCompileUnit { DwarfInfo -> [DwarfInfo]
dwChildren :: [DwarfInfo]
, DwarfInfo -> String
dwName :: String
, DwarfInfo -> String
dwProducer :: String
, DwarfInfo -> String
dwCompDir :: String
, DwarfInfo -> CLabel
dwLowLabel :: CLabel
, DwarfInfo -> CLabel
dwHighLabel :: CLabel
, DwarfInfo -> PtrString
dwLineLabel :: PtrString }
| DwarfSubprogram { dwChildren :: [DwarfInfo]
, dwName :: String
, DwarfInfo -> CLabel
dwLabel :: CLabel
, DwarfInfo -> Maybe CLabel
dwParent :: Maybe CLabel
}
| DwarfBlock { dwChildren :: [DwarfInfo]
, dwLabel :: CLabel
, DwarfInfo -> Maybe CLabel
dwMarker :: Maybe CLabel
}
| DwarfSrcNote { DwarfInfo -> RealSrcSpan
dwSrcSpan :: RealSrcSpan
}
data DwarfAbbrev
= DwAbbrNull
| DwAbbrCompileUnit
| DwAbbrSubprogram
| DwAbbrSubprogramWithParent
| DwAbbrBlockWithoutCode
| DwAbbrBlock
| DwAbbrGhcSrcNote
deriving (DwarfAbbrev -> DwarfAbbrev -> Bool
(DwarfAbbrev -> DwarfAbbrev -> Bool)
-> (DwarfAbbrev -> DwarfAbbrev -> Bool) -> Eq DwarfAbbrev
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DwarfAbbrev -> DwarfAbbrev -> Bool
$c/= :: DwarfAbbrev -> DwarfAbbrev -> Bool
== :: DwarfAbbrev -> DwarfAbbrev -> Bool
$c== :: DwarfAbbrev -> DwarfAbbrev -> Bool
Eq, Int -> DwarfAbbrev
DwarfAbbrev -> Int
DwarfAbbrev -> [DwarfAbbrev]
DwarfAbbrev -> DwarfAbbrev
DwarfAbbrev -> DwarfAbbrev -> [DwarfAbbrev]
DwarfAbbrev -> DwarfAbbrev -> DwarfAbbrev -> [DwarfAbbrev]
(DwarfAbbrev -> DwarfAbbrev)
-> (DwarfAbbrev -> DwarfAbbrev)
-> (Int -> DwarfAbbrev)
-> (DwarfAbbrev -> Int)
-> (DwarfAbbrev -> [DwarfAbbrev])
-> (DwarfAbbrev -> DwarfAbbrev -> [DwarfAbbrev])
-> (DwarfAbbrev -> DwarfAbbrev -> [DwarfAbbrev])
-> (DwarfAbbrev -> DwarfAbbrev -> DwarfAbbrev -> [DwarfAbbrev])
-> Enum DwarfAbbrev
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: DwarfAbbrev -> DwarfAbbrev -> DwarfAbbrev -> [DwarfAbbrev]
$cenumFromThenTo :: DwarfAbbrev -> DwarfAbbrev -> DwarfAbbrev -> [DwarfAbbrev]
enumFromTo :: DwarfAbbrev -> DwarfAbbrev -> [DwarfAbbrev]
$cenumFromTo :: DwarfAbbrev -> DwarfAbbrev -> [DwarfAbbrev]
enumFromThen :: DwarfAbbrev -> DwarfAbbrev -> [DwarfAbbrev]
$cenumFromThen :: DwarfAbbrev -> DwarfAbbrev -> [DwarfAbbrev]
enumFrom :: DwarfAbbrev -> [DwarfAbbrev]
$cenumFrom :: DwarfAbbrev -> [DwarfAbbrev]
fromEnum :: DwarfAbbrev -> Int
$cfromEnum :: DwarfAbbrev -> Int
toEnum :: Int -> DwarfAbbrev
$ctoEnum :: Int -> DwarfAbbrev
pred :: DwarfAbbrev -> DwarfAbbrev
$cpred :: DwarfAbbrev -> DwarfAbbrev
succ :: DwarfAbbrev -> DwarfAbbrev
$csucc :: DwarfAbbrev -> DwarfAbbrev
Enum)
pprAbbrev :: DwarfAbbrev -> SDoc
pprAbbrev :: DwarfAbbrev -> SDoc
pprAbbrev = Word -> SDoc
pprLEBWord (Word -> SDoc) -> (DwarfAbbrev -> Word) -> DwarfAbbrev -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word) -> (DwarfAbbrev -> Int) -> DwarfAbbrev -> Word
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DwarfAbbrev -> Int
forall a. Enum a => a -> Int
fromEnum
pprAbbrevDecls :: Bool -> SDoc
pprAbbrevDecls :: Bool -> SDoc
pprAbbrevDecls haveDebugLine :: Bool
haveDebugLine =
let mkAbbrev :: DwarfAbbrev -> Word -> Word8 -> [(Word, Word)] -> SDoc
mkAbbrev abbr :: DwarfAbbrev
abbr tag :: Word
tag chld :: Word8
chld flds :: [(Word, Word)]
flds =
let fld :: (Word, Word) -> SDoc
fld (tag :: Word
tag, form :: Word
form) = Word -> SDoc
pprLEBWord Word
tag SDoc -> SDoc -> SDoc
$$ Word -> SDoc
pprLEBWord Word
form
in DwarfAbbrev -> SDoc
pprAbbrev DwarfAbbrev
abbr SDoc -> SDoc -> SDoc
$$ Word -> SDoc
pprLEBWord Word
tag SDoc -> SDoc -> SDoc
$$ Word8 -> SDoc
pprByte Word8
chld SDoc -> SDoc -> SDoc
$$
[SDoc] -> SDoc
vcat (((Word, Word) -> SDoc) -> [(Word, Word)] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (Word, Word) -> SDoc
fld [(Word, Word)]
flds) SDoc -> SDoc -> SDoc
$$ Word8 -> SDoc
pprByte 0 SDoc -> SDoc -> SDoc
$$ Word8 -> SDoc
pprByte 0
subprogramAttrs :: [(Word, Word)]
subprogramAttrs =
[ (Word
dW_AT_name, Word
dW_FORM_string)
, (Word
dW_AT_MIPS_linkage_name, Word
dW_FORM_string)
, (Word
dW_AT_external, Word
dW_FORM_flag)
, (Word
dW_AT_low_pc, Word
dW_FORM_addr)
, (Word
dW_AT_high_pc, Word
dW_FORM_addr)
, (Word
dW_AT_frame_base, Word
dW_FORM_block1)
]
in SDoc
dwarfAbbrevSection SDoc -> SDoc -> SDoc
$$
PtrString -> SDoc
ptext PtrString
dwarfAbbrevLabel SDoc -> SDoc -> SDoc
<> SDoc
colon SDoc -> SDoc -> SDoc
$$
DwarfAbbrev -> Word -> Word8 -> [(Word, Word)] -> SDoc
mkAbbrev DwarfAbbrev
DwAbbrCompileUnit Word
dW_TAG_compile_unit Word8
dW_CHILDREN_yes
([(Word
dW_AT_name, Word
dW_FORM_string)
, (Word
dW_AT_producer, Word
dW_FORM_string)
, (Word
dW_AT_language, Word
dW_FORM_data4)
, (Word
dW_AT_comp_dir, Word
dW_FORM_string)
, (Word
dW_AT_use_UTF8, Word
dW_FORM_flag_present)
, (Word
dW_AT_low_pc, Word
dW_FORM_addr)
, (Word
dW_AT_high_pc, Word
dW_FORM_addr)
] [(Word, Word)] -> [(Word, Word)] -> [(Word, Word)]
forall a. [a] -> [a] -> [a]
++
(if Bool
haveDebugLine
then [ (Word
dW_AT_stmt_list, Word
dW_FORM_data4) ]
else [])) SDoc -> SDoc -> SDoc
$$
DwarfAbbrev -> Word -> Word8 -> [(Word, Word)] -> SDoc
mkAbbrev DwarfAbbrev
DwAbbrSubprogram Word
dW_TAG_subprogram Word8
dW_CHILDREN_yes
[(Word, Word)]
subprogramAttrs SDoc -> SDoc -> SDoc
$$
DwarfAbbrev -> Word -> Word8 -> [(Word, Word)] -> SDoc
mkAbbrev DwarfAbbrev
DwAbbrSubprogramWithParent Word
dW_TAG_subprogram Word8
dW_CHILDREN_yes
([(Word, Word)]
subprogramAttrs [(Word, Word)] -> [(Word, Word)] -> [(Word, Word)]
forall a. [a] -> [a] -> [a]
++ [(Word
dW_AT_ghc_tick_parent, Word
dW_FORM_ref_addr)]) SDoc -> SDoc -> SDoc
$$
DwarfAbbrev -> Word -> Word8 -> [(Word, Word)] -> SDoc
mkAbbrev DwarfAbbrev
DwAbbrBlockWithoutCode Word
dW_TAG_lexical_block Word8
dW_CHILDREN_yes
[ (Word
dW_AT_name, Word
dW_FORM_string)
] SDoc -> SDoc -> SDoc
$$
DwarfAbbrev -> Word -> Word8 -> [(Word, Word)] -> SDoc
mkAbbrev DwarfAbbrev
DwAbbrBlock Word
dW_TAG_lexical_block Word8
dW_CHILDREN_yes
[ (Word
dW_AT_name, Word
dW_FORM_string)
, (Word
dW_AT_low_pc, Word
dW_FORM_addr)
, (Word
dW_AT_high_pc, Word
dW_FORM_addr)
] SDoc -> SDoc -> SDoc
$$
DwarfAbbrev -> Word -> Word8 -> [(Word, Word)] -> SDoc
mkAbbrev DwarfAbbrev
DwAbbrGhcSrcNote Word
dW_TAG_ghc_src_note Word8
dW_CHILDREN_no
[ (Word
dW_AT_ghc_span_file, Word
dW_FORM_string)
, (Word
dW_AT_ghc_span_start_line, Word
dW_FORM_data4)
, (Word
dW_AT_ghc_span_start_col, Word
dW_FORM_data2)
, (Word
dW_AT_ghc_span_end_line, Word
dW_FORM_data4)
, (Word
dW_AT_ghc_span_end_col, Word
dW_FORM_data2)
] SDoc -> SDoc -> SDoc
$$
Word8 -> SDoc
pprByte 0
pprDwarfInfo :: Bool -> DwarfInfo -> SDoc
pprDwarfInfo :: Bool -> DwarfInfo -> SDoc
pprDwarfInfo haveSrc :: Bool
haveSrc d :: DwarfInfo
d
= case DwarfInfo
d of
DwarfCompileUnit {} -> SDoc
hasChildren
DwarfSubprogram {} -> SDoc
hasChildren
DwarfBlock {} -> SDoc
hasChildren
DwarfSrcNote {} -> SDoc
noChildren
where
hasChildren :: SDoc
hasChildren =
Bool -> DwarfInfo -> SDoc
pprDwarfInfoOpen Bool
haveSrc DwarfInfo
d SDoc -> SDoc -> SDoc
$$
[SDoc] -> SDoc
vcat ((DwarfInfo -> SDoc) -> [DwarfInfo] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (Bool -> DwarfInfo -> SDoc
pprDwarfInfo Bool
haveSrc) (DwarfInfo -> [DwarfInfo]
dwChildren DwarfInfo
d)) SDoc -> SDoc -> SDoc
$$
SDoc
pprDwarfInfoClose
noChildren :: SDoc
noChildren = Bool -> DwarfInfo -> SDoc
pprDwarfInfoOpen Bool
haveSrc DwarfInfo
d
pprDwarfInfoOpen :: Bool -> DwarfInfo -> SDoc
pprDwarfInfoOpen :: Bool -> DwarfInfo -> SDoc
pprDwarfInfoOpen haveSrc :: Bool
haveSrc (DwarfCompileUnit _ name :: String
name producer :: String
producer compDir :: String
compDir lowLabel :: CLabel
lowLabel
highLabel :: CLabel
highLabel lineLbl :: PtrString
lineLbl) =
DwarfAbbrev -> SDoc
pprAbbrev DwarfAbbrev
DwAbbrCompileUnit
SDoc -> SDoc -> SDoc
$$ String -> SDoc
pprString String
name
SDoc -> SDoc -> SDoc
$$ String -> SDoc
pprString String
producer
SDoc -> SDoc -> SDoc
$$ Word -> SDoc
pprData4 Word
dW_LANG_Haskell
SDoc -> SDoc -> SDoc
$$ String -> SDoc
pprString String
compDir
SDoc -> SDoc -> SDoc
$$ SDoc -> SDoc
pprWord (CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
lowLabel)
SDoc -> SDoc -> SDoc
$$ SDoc -> SDoc
pprWord (CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
highLabel)
SDoc -> SDoc -> SDoc
$$ if Bool
haveSrc
then SDoc -> SDoc -> SDoc
sectionOffset (PtrString -> SDoc
ptext PtrString
lineLbl) (PtrString -> SDoc
ptext PtrString
dwarfLineLabel)
else SDoc
empty
pprDwarfInfoOpen _ (DwarfSubprogram _ name :: String
name label :: CLabel
label
parent :: Maybe CLabel
parent) = (DynFlags -> SDoc) -> SDoc
sdocWithDynFlags ((DynFlags -> SDoc) -> SDoc) -> (DynFlags -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \df :: DynFlags
df ->
CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr (CLabel -> CLabel
mkAsmTempDieLabel CLabel
label) SDoc -> SDoc -> SDoc
<> SDoc
colon
SDoc -> SDoc -> SDoc
$$ DwarfAbbrev -> SDoc
pprAbbrev DwarfAbbrev
abbrev
SDoc -> SDoc -> SDoc
$$ String -> SDoc
pprString String
name
SDoc -> SDoc -> SDoc
$$ String -> SDoc
pprString (DynFlags -> SDoc -> PprStyle -> String
renderWithStyle DynFlags
df (CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
label) (CodeStyle -> PprStyle
mkCodeStyle CodeStyle
CStyle))
SDoc -> SDoc -> SDoc
$$ Bool -> SDoc
pprFlag (CLabel -> Bool
externallyVisibleCLabel CLabel
label)
SDoc -> SDoc -> SDoc
$$ SDoc -> SDoc
pprWord (CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
label)
SDoc -> SDoc -> SDoc
$$ SDoc -> SDoc
pprWord (CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr (CLabel -> SDoc) -> CLabel -> SDoc
forall a b. (a -> b) -> a -> b
$ CLabel -> CLabel
mkAsmTempEndLabel CLabel
label)
SDoc -> SDoc -> SDoc
$$ Word8 -> SDoc
pprByte 1
SDoc -> SDoc -> SDoc
$$ Word8 -> SDoc
pprByte Word8
dW_OP_call_frame_cfa
SDoc -> SDoc -> SDoc
$$ SDoc
parentValue
where
abbrev :: DwarfAbbrev
abbrev = case Maybe CLabel
parent of Nothing -> DwarfAbbrev
DwAbbrSubprogram
Just _ -> DwarfAbbrev
DwAbbrSubprogramWithParent
parentValue :: SDoc
parentValue = SDoc -> (CLabel -> SDoc) -> Maybe CLabel -> SDoc
forall b a. b -> (a -> b) -> Maybe a -> b
maybe SDoc
empty CLabel -> SDoc
forall a. Outputable a => a -> SDoc
pprParentDie Maybe CLabel
parent
pprParentDie :: a -> SDoc
pprParentDie sym :: a
sym = SDoc -> SDoc -> SDoc
sectionOffset (a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
sym) (PtrString -> SDoc
ptext PtrString
dwarfInfoLabel)
pprDwarfInfoOpen _ (DwarfBlock _ label :: CLabel
label Nothing) = (DynFlags -> SDoc) -> SDoc
sdocWithDynFlags ((DynFlags -> SDoc) -> SDoc) -> (DynFlags -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \df :: DynFlags
df ->
CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr (CLabel -> CLabel
mkAsmTempDieLabel CLabel
label) SDoc -> SDoc -> SDoc
<> SDoc
colon
SDoc -> SDoc -> SDoc
$$ DwarfAbbrev -> SDoc
pprAbbrev DwarfAbbrev
DwAbbrBlockWithoutCode
SDoc -> SDoc -> SDoc
$$ String -> SDoc
pprString (DynFlags -> SDoc -> PprStyle -> String
renderWithStyle DynFlags
df (CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
label) (CodeStyle -> PprStyle
mkCodeStyle CodeStyle
CStyle))
pprDwarfInfoOpen _ (DwarfBlock _ label :: CLabel
label (Just marker :: CLabel
marker)) = (DynFlags -> SDoc) -> SDoc
sdocWithDynFlags ((DynFlags -> SDoc) -> SDoc) -> (DynFlags -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \df :: DynFlags
df ->
CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr (CLabel -> CLabel
mkAsmTempDieLabel CLabel
label) SDoc -> SDoc -> SDoc
<> SDoc
colon
SDoc -> SDoc -> SDoc
$$ DwarfAbbrev -> SDoc
pprAbbrev DwarfAbbrev
DwAbbrBlock
SDoc -> SDoc -> SDoc
$$ String -> SDoc
pprString (DynFlags -> SDoc -> PprStyle -> String
renderWithStyle DynFlags
df (CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
label) (CodeStyle -> PprStyle
mkCodeStyle CodeStyle
CStyle))
SDoc -> SDoc -> SDoc
$$ SDoc -> SDoc
pprWord (CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
marker)
SDoc -> SDoc -> SDoc
$$ SDoc -> SDoc
pprWord (CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr (CLabel -> SDoc) -> CLabel -> SDoc
forall a b. (a -> b) -> a -> b
$ CLabel -> CLabel
mkAsmTempEndLabel CLabel
marker)
pprDwarfInfoOpen _ (DwarfSrcNote ss :: RealSrcSpan
ss) =
DwarfAbbrev -> SDoc
pprAbbrev DwarfAbbrev
DwAbbrGhcSrcNote
SDoc -> SDoc -> SDoc
$$ SDoc -> SDoc
pprString' (FastString -> SDoc
ftext (FastString -> SDoc) -> FastString -> SDoc
forall a b. (a -> b) -> a -> b
$ RealSrcSpan -> FastString
srcSpanFile RealSrcSpan
ss)
SDoc -> SDoc -> SDoc
$$ Word -> SDoc
pprData4 (Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word) -> Int -> Word
forall a b. (a -> b) -> a -> b
$ RealSrcSpan -> Int
srcSpanStartLine RealSrcSpan
ss)
SDoc -> SDoc -> SDoc
$$ Word16 -> SDoc
pprHalf (Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word16) -> Int -> Word16
forall a b. (a -> b) -> a -> b
$ RealSrcSpan -> Int
srcSpanStartCol RealSrcSpan
ss)
SDoc -> SDoc -> SDoc
$$ Word -> SDoc
pprData4 (Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word) -> Int -> Word
forall a b. (a -> b) -> a -> b
$ RealSrcSpan -> Int
srcSpanEndLine RealSrcSpan
ss)
SDoc -> SDoc -> SDoc
$$ Word16 -> SDoc
pprHalf (Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word16) -> Int -> Word16
forall a b. (a -> b) -> a -> b
$ RealSrcSpan -> Int
srcSpanEndCol RealSrcSpan
ss)
pprDwarfInfoClose :: SDoc
pprDwarfInfoClose :: SDoc
pprDwarfInfoClose = DwarfAbbrev -> SDoc
pprAbbrev DwarfAbbrev
DwAbbrNull
data DwarfARange
= DwarfARange
{ DwarfARange -> CLabel
dwArngStartLabel :: CLabel
, DwarfARange -> CLabel
dwArngEndLabel :: CLabel
}
pprDwarfARanges :: [DwarfARange] -> Unique -> SDoc
pprDwarfARanges :: [DwarfARange] -> Unique -> SDoc
pprDwarfARanges arngs :: [DwarfARange]
arngs unitU :: Unique
unitU = (Platform -> SDoc) -> SDoc
sdocWithPlatform ((Platform -> SDoc) -> SDoc) -> (Platform -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \plat :: Platform
plat ->
let wordSize :: Int
wordSize = Platform -> Int
platformWordSize Platform
plat
paddingSize :: Int
paddingSize = 4 :: Int
pad :: Int -> SDoc
pad n :: Int
n = [SDoc] -> SDoc
vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ Int -> SDoc -> [SDoc]
forall a. Int -> a -> [a]
replicate Int
n (SDoc -> [SDoc]) -> SDoc -> [SDoc]
forall a b. (a -> b) -> a -> b
$ Word8 -> SDoc
pprByte 0
initialLength :: Int
initialLength = 8 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
paddingSize Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [DwarfARange] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [DwarfARange]
arngs) Int -> Int -> Int
forall a. Num a => a -> a -> a
* 2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
wordSize
in SDoc -> SDoc
pprDwWord (Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr Int
initialLength)
SDoc -> SDoc -> SDoc
$$ Word16 -> SDoc
pprHalf 2
SDoc -> SDoc -> SDoc
$$ SDoc -> SDoc -> SDoc
sectionOffset (CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr (CLabel -> SDoc) -> CLabel -> SDoc
forall a b. (a -> b) -> a -> b
$ Unique -> CLabel
forall a. Uniquable a => a -> CLabel
mkAsmTempLabel (Unique -> CLabel) -> Unique -> CLabel
forall a b. (a -> b) -> a -> b
$ Unique
unitU)
(PtrString -> SDoc
ptext PtrString
dwarfInfoLabel)
SDoc -> SDoc -> SDoc
$$ Word8 -> SDoc
pprByte (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
wordSize)
SDoc -> SDoc -> SDoc
$$ Word8 -> SDoc
pprByte 0
SDoc -> SDoc -> SDoc
$$ Int -> SDoc
pad Int
paddingSize
SDoc -> SDoc -> SDoc
$$ [SDoc] -> SDoc
vcat ((DwarfARange -> SDoc) -> [DwarfARange] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map DwarfARange -> SDoc
pprDwarfARange [DwarfARange]
arngs)
SDoc -> SDoc -> SDoc
$$ SDoc -> SDoc
pprWord (Char -> SDoc
char '0')
SDoc -> SDoc -> SDoc
$$ SDoc -> SDoc
pprWord (Char -> SDoc
char '0')
pprDwarfARange :: DwarfARange -> SDoc
pprDwarfARange :: DwarfARange -> SDoc
pprDwarfARange arng :: DwarfARange
arng = SDoc -> SDoc
pprWord (CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr (CLabel -> SDoc) -> CLabel -> SDoc
forall a b. (a -> b) -> a -> b
$ DwarfARange -> CLabel
dwArngStartLabel DwarfARange
arng) SDoc -> SDoc -> SDoc
$$ SDoc -> SDoc
pprWord SDoc
length
where
length :: SDoc
length = CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr (DwarfARange -> CLabel
dwArngEndLabel DwarfARange
arng)
SDoc -> SDoc -> SDoc
<> Char -> SDoc
char '-' SDoc -> SDoc -> SDoc
<> CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr (DwarfARange -> CLabel
dwArngStartLabel DwarfARange
arng)
data DwarfFrame
= DwarfFrame
{ DwarfFrame -> CLabel
dwCieLabel :: CLabel
, DwarfFrame -> UnwindTable
dwCieInit :: UnwindTable
, DwarfFrame -> [DwarfFrameProc]
dwCieProcs :: [DwarfFrameProc]
}
data DwarfFrameProc
= DwarfFrameProc
{ DwarfFrameProc -> CLabel
dwFdeProc :: CLabel
, DwarfFrameProc -> Bool
dwFdeHasInfo :: Bool
, DwarfFrameProc -> [DwarfFrameBlock]
dwFdeBlocks :: [DwarfFrameBlock]
}
data DwarfFrameBlock
= DwarfFrameBlock
{ DwarfFrameBlock -> Bool
dwFdeBlkHasInfo :: Bool
, DwarfFrameBlock -> [UnwindPoint]
dwFdeUnwind :: [UnwindPoint]
}
instance Outputable DwarfFrameBlock where
ppr :: DwarfFrameBlock -> SDoc
ppr (DwarfFrameBlock hasInfo :: Bool
hasInfo unwinds :: [UnwindPoint]
unwinds) = SDoc -> SDoc
braces (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ Bool -> SDoc
forall a. Outputable a => a -> SDoc
ppr Bool
hasInfo SDoc -> SDoc -> SDoc
<+> [UnwindPoint] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [UnwindPoint]
unwinds
pprDwarfFrame :: DwarfFrame -> SDoc
pprDwarfFrame :: DwarfFrame -> SDoc
pprDwarfFrame DwarfFrame{dwCieLabel :: DwarfFrame -> CLabel
dwCieLabel=CLabel
cieLabel,dwCieInit :: DwarfFrame -> UnwindTable
dwCieInit=UnwindTable
cieInit,dwCieProcs :: DwarfFrame -> [DwarfFrameProc]
dwCieProcs=[DwarfFrameProc]
procs}
= (Platform -> SDoc) -> SDoc
sdocWithPlatform ((Platform -> SDoc) -> SDoc) -> (Platform -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \plat :: Platform
plat ->
let cieStartLabel :: CLabel
cieStartLabel= CLabel -> FastString -> CLabel
mkAsmTempDerivedLabel CLabel
cieLabel (String -> FastString
fsLit "_start")
cieEndLabel :: CLabel
cieEndLabel = CLabel -> CLabel
mkAsmTempEndLabel CLabel
cieLabel
length :: SDoc
length = CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
cieEndLabel SDoc -> SDoc -> SDoc
<> Char -> SDoc
char '-' SDoc -> SDoc -> SDoc
<> CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
cieStartLabel
spReg :: Word8
spReg = Platform -> GlobalReg -> Word8
dwarfGlobalRegNo Platform
plat GlobalReg
Sp
retReg :: Word8
retReg = Platform -> Word8
dwarfReturnRegNo Platform
plat
wordSize :: Int
wordSize = Platform -> Int
platformWordSize Platform
plat
pprInit :: (GlobalReg, Maybe UnwindExpr) -> SDoc
pprInit :: (GlobalReg, Maybe UnwindExpr) -> SDoc
pprInit (g :: GlobalReg
g, uw :: Maybe UnwindExpr
uw) = Platform
-> GlobalReg -> (Maybe UnwindExpr, Maybe UnwindExpr) -> SDoc
pprSetUnwind Platform
plat GlobalReg
g (Maybe UnwindExpr
forall a. Maybe a
Nothing, Maybe UnwindExpr
uw)
preserveSp :: SDoc
preserveSp = case Platform -> Arch
platformArch Platform
plat of
ArchX86 -> Word8 -> SDoc
pprByte Word8
dW_CFA_same_value SDoc -> SDoc -> SDoc
$$ Word -> SDoc
pprLEBWord 4
ArchX86_64 -> Word8 -> SDoc
pprByte Word8
dW_CFA_same_value SDoc -> SDoc -> SDoc
$$ Word -> SDoc
pprLEBWord 7
_ -> SDoc
empty
in [SDoc] -> SDoc
vcat [ CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
cieLabel SDoc -> SDoc -> SDoc
<> SDoc
colon
, SDoc -> SDoc
pprData4' SDoc
length
, CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
cieStartLabel SDoc -> SDoc -> SDoc
<> SDoc
colon
, SDoc -> SDoc
pprData4' (String -> SDoc
text "-1")
, Word8 -> SDoc
pprByte 3
, Word8 -> SDoc
pprByte 0
, Word8 -> SDoc
pprByte 1
, Word8 -> SDoc
pprByte (128Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
-Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
wordSize)
, Word8 -> SDoc
pprByte Word8
retReg
] SDoc -> SDoc -> SDoc
$$
[SDoc] -> SDoc
vcat (((GlobalReg, Maybe UnwindExpr) -> SDoc)
-> [(GlobalReg, Maybe UnwindExpr)] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (GlobalReg, Maybe UnwindExpr) -> SDoc
pprInit ([(GlobalReg, Maybe UnwindExpr)] -> [SDoc])
-> [(GlobalReg, Maybe UnwindExpr)] -> [SDoc]
forall a b. (a -> b) -> a -> b
$ UnwindTable -> [(GlobalReg, Maybe UnwindExpr)]
forall k a. Map k a -> [(k, a)]
Map.toList UnwindTable
cieInit) SDoc -> SDoc -> SDoc
$$
[SDoc] -> SDoc
vcat [
Word8 -> SDoc
pprByte (Word8
dW_CFA_offsetWord8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+Word8
retReg)
, Word8 -> SDoc
pprByte 0
, SDoc
preserveSp
, Word8 -> SDoc
pprByte Word8
dW_CFA_val_offset
, Word -> SDoc
pprLEBWord (Word8 -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
spReg)
, Word -> SDoc
pprLEBWord 0
] SDoc -> SDoc -> SDoc
$$
SDoc
wordAlign SDoc -> SDoc -> SDoc
$$
CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
cieEndLabel SDoc -> SDoc -> SDoc
<> SDoc
colon SDoc -> SDoc -> SDoc
$$
[SDoc] -> SDoc
vcat ((DwarfFrameProc -> SDoc) -> [DwarfFrameProc] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (CLabel -> UnwindTable -> DwarfFrameProc -> SDoc
pprFrameProc CLabel
cieLabel UnwindTable
cieInit) [DwarfFrameProc]
procs)
pprFrameProc :: CLabel -> UnwindTable -> DwarfFrameProc -> SDoc
pprFrameProc :: CLabel -> UnwindTable -> DwarfFrameProc -> SDoc
pprFrameProc frameLbl :: CLabel
frameLbl initUw :: UnwindTable
initUw (DwarfFrameProc procLbl :: CLabel
procLbl hasInfo :: Bool
hasInfo blocks :: [DwarfFrameBlock]
blocks)
= let fdeLabel :: CLabel
fdeLabel = CLabel -> FastString -> CLabel
mkAsmTempDerivedLabel CLabel
procLbl (String -> FastString
fsLit "_fde")
fdeEndLabel :: CLabel
fdeEndLabel = CLabel -> FastString -> CLabel
mkAsmTempDerivedLabel CLabel
procLbl (String -> FastString
fsLit "_fde_end")
procEnd :: CLabel
procEnd = CLabel -> CLabel
mkAsmTempEndLabel CLabel
procLbl
ifInfo :: String -> SDoc
ifInfo str :: String
str = if Bool
hasInfo then String -> SDoc
text String
str else SDoc
empty
in [SDoc] -> SDoc
vcat [ SDoc -> SDoc
whenPprDebug (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ String -> SDoc
text "# Unwinding for" SDoc -> SDoc -> SDoc
<+> CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
procLbl SDoc -> SDoc -> SDoc
<> SDoc
colon
, SDoc -> SDoc
pprData4' (CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
fdeEndLabel SDoc -> SDoc -> SDoc
<> Char -> SDoc
char '-' SDoc -> SDoc -> SDoc
<> CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
fdeLabel)
, CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
fdeLabel SDoc -> SDoc -> SDoc
<> SDoc
colon
, SDoc -> SDoc
pprData4' (CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
frameLbl SDoc -> SDoc -> SDoc
<> Char -> SDoc
char '-' SDoc -> SDoc -> SDoc
<>
PtrString -> SDoc
ptext PtrString
dwarfFrameLabel)
, SDoc -> SDoc
pprWord (CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
procLbl SDoc -> SDoc -> SDoc
<> String -> SDoc
ifInfo "-1")
, SDoc -> SDoc
pprWord (CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
procEnd SDoc -> SDoc -> SDoc
<> Char -> SDoc
char '-' SDoc -> SDoc -> SDoc
<>
CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
procLbl SDoc -> SDoc -> SDoc
<> String -> SDoc
ifInfo "+1")
] SDoc -> SDoc -> SDoc
$$
[SDoc] -> SDoc
vcat (State UnwindTable [SDoc] -> UnwindTable -> [SDoc]
forall s a. State s a -> s -> a
S.evalState ((DwarfFrameBlock -> StateT UnwindTable Identity SDoc)
-> [DwarfFrameBlock] -> State UnwindTable [SDoc]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM DwarfFrameBlock -> StateT UnwindTable Identity SDoc
pprFrameBlock [DwarfFrameBlock]
blocks) UnwindTable
initUw) SDoc -> SDoc -> SDoc
$$
SDoc
wordAlign SDoc -> SDoc -> SDoc
$$
CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
fdeEndLabel SDoc -> SDoc -> SDoc
<> SDoc
colon
pprFrameBlock :: DwarfFrameBlock -> S.State UnwindTable SDoc
pprFrameBlock :: DwarfFrameBlock -> StateT UnwindTable Identity SDoc
pprFrameBlock (DwarfFrameBlock hasInfo :: Bool
hasInfo uws0 :: [UnwindPoint]
uws0) =
[SDoc] -> SDoc
vcat ([SDoc] -> SDoc)
-> State UnwindTable [SDoc] -> StateT UnwindTable Identity SDoc
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Bool -> UnwindPoint -> StateT UnwindTable Identity SDoc)
-> [Bool] -> [UnwindPoint] -> State UnwindTable [SDoc]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM Bool -> UnwindPoint -> StateT UnwindTable Identity SDoc
pprFrameDecl (Bool
True Bool -> [Bool] -> [Bool]
forall a. a -> [a] -> [a]
: Bool -> [Bool]
forall a. a -> [a]
repeat Bool
False) [UnwindPoint]
uws0
where
pprFrameDecl :: Bool -> UnwindPoint -> S.State UnwindTable SDoc
pprFrameDecl :: Bool -> UnwindPoint -> StateT UnwindTable Identity SDoc
pprFrameDecl firstDecl :: Bool
firstDecl (UnwindPoint lbl :: CLabel
lbl uws :: UnwindTable
uws) = (UnwindTable -> (SDoc, UnwindTable))
-> StateT UnwindTable Identity SDoc
forall (m :: * -> *) s a. Monad m => (s -> (a, s)) -> StateT s m a
S.state ((UnwindTable -> (SDoc, UnwindTable))
-> StateT UnwindTable Identity SDoc)
-> (UnwindTable -> (SDoc, UnwindTable))
-> StateT UnwindTable Identity SDoc
forall a b. (a -> b) -> a -> b
$ \oldUws :: UnwindTable
oldUws ->
let
isChanged :: GlobalReg -> Maybe UnwindExpr
-> Maybe (Maybe UnwindExpr, Maybe UnwindExpr)
isChanged :: GlobalReg
-> Maybe UnwindExpr -> Maybe (Maybe UnwindExpr, Maybe UnwindExpr)
isChanged g :: GlobalReg
g new :: Maybe UnwindExpr
new
| Maybe UnwindExpr -> Maybe (Maybe UnwindExpr)
forall a. a -> Maybe a
Just Maybe UnwindExpr
new Maybe (Maybe UnwindExpr) -> Maybe (Maybe UnwindExpr) -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe (Maybe UnwindExpr)
old = Maybe (Maybe UnwindExpr, Maybe UnwindExpr)
forall a. Maybe a
Nothing
| Maybe (Maybe UnwindExpr)
Nothing <- Maybe (Maybe UnwindExpr)
old
, Maybe UnwindExpr
Nothing <- Maybe UnwindExpr
new = Maybe (Maybe UnwindExpr, Maybe UnwindExpr)
forall a. Maybe a
Nothing
| Bool
otherwise = (Maybe UnwindExpr, Maybe UnwindExpr)
-> Maybe (Maybe UnwindExpr, Maybe UnwindExpr)
forall a. a -> Maybe a
Just (Maybe (Maybe UnwindExpr) -> Maybe UnwindExpr
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join Maybe (Maybe UnwindExpr)
old, Maybe UnwindExpr
new)
where
old :: Maybe (Maybe UnwindExpr)
old = GlobalReg -> UnwindTable -> Maybe (Maybe UnwindExpr)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup GlobalReg
g UnwindTable
oldUws
changed :: [(GlobalReg, (Maybe UnwindExpr, Maybe UnwindExpr))]
changed = Map GlobalReg (Maybe UnwindExpr, Maybe UnwindExpr)
-> [(GlobalReg, (Maybe UnwindExpr, Maybe UnwindExpr))]
forall k a. Map k a -> [(k, a)]
Map.toList (Map GlobalReg (Maybe UnwindExpr, Maybe UnwindExpr)
-> [(GlobalReg, (Maybe UnwindExpr, Maybe UnwindExpr))])
-> Map GlobalReg (Maybe UnwindExpr, Maybe UnwindExpr)
-> [(GlobalReg, (Maybe UnwindExpr, Maybe UnwindExpr))]
forall a b. (a -> b) -> a -> b
$ (GlobalReg
-> Maybe UnwindExpr -> Maybe (Maybe UnwindExpr, Maybe UnwindExpr))
-> UnwindTable
-> Map GlobalReg (Maybe UnwindExpr, Maybe UnwindExpr)
forall k a b. (k -> a -> Maybe b) -> Map k a -> Map k b
Map.mapMaybeWithKey GlobalReg
-> Maybe UnwindExpr -> Maybe (Maybe UnwindExpr, Maybe UnwindExpr)
isChanged UnwindTable
uws
in if UnwindTable
oldUws UnwindTable -> UnwindTable -> Bool
forall a. Eq a => a -> a -> Bool
== UnwindTable
uws
then (SDoc
empty, UnwindTable
oldUws)
else let
needsOffset :: Bool
needsOffset = Bool
firstDecl Bool -> Bool -> Bool
&& Bool
hasInfo
lblDoc :: SDoc
lblDoc = CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
lbl SDoc -> SDoc -> SDoc
<>
if Bool
needsOffset then String -> SDoc
text "-1" else SDoc
empty
doc :: SDoc
doc = (Platform -> SDoc) -> SDoc
sdocWithPlatform ((Platform -> SDoc) -> SDoc) -> (Platform -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \plat :: Platform
plat ->
Word8 -> SDoc
pprByte Word8
dW_CFA_set_loc SDoc -> SDoc -> SDoc
$$ SDoc -> SDoc
pprWord SDoc
lblDoc SDoc -> SDoc -> SDoc
$$
[SDoc] -> SDoc
vcat (((GlobalReg, (Maybe UnwindExpr, Maybe UnwindExpr)) -> SDoc)
-> [(GlobalReg, (Maybe UnwindExpr, Maybe UnwindExpr))] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map ((GlobalReg -> (Maybe UnwindExpr, Maybe UnwindExpr) -> SDoc)
-> (GlobalReg, (Maybe UnwindExpr, Maybe UnwindExpr)) -> SDoc
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((GlobalReg -> (Maybe UnwindExpr, Maybe UnwindExpr) -> SDoc)
-> (GlobalReg, (Maybe UnwindExpr, Maybe UnwindExpr)) -> SDoc)
-> (GlobalReg -> (Maybe UnwindExpr, Maybe UnwindExpr) -> SDoc)
-> (GlobalReg, (Maybe UnwindExpr, Maybe UnwindExpr))
-> SDoc
forall a b. (a -> b) -> a -> b
$ Platform
-> GlobalReg -> (Maybe UnwindExpr, Maybe UnwindExpr) -> SDoc
pprSetUnwind Platform
plat) [(GlobalReg, (Maybe UnwindExpr, Maybe UnwindExpr))]
changed)
in (SDoc
doc, UnwindTable
uws)
dwarfGlobalRegNo :: Platform -> GlobalReg -> Word8
dwarfGlobalRegNo :: Platform -> GlobalReg -> Word8
dwarfGlobalRegNo p :: Platform
p UnwindReturnReg = Platform -> Word8
dwarfReturnRegNo Platform
p
dwarfGlobalRegNo p :: Platform
p reg :: GlobalReg
reg = Word8 -> (RealReg -> Word8) -> Maybe RealReg -> Word8
forall b a. b -> (a -> b) -> Maybe a -> b
maybe 0 (Platform -> Reg -> Word8
dwarfRegNo Platform
p (Reg -> Word8) -> (RealReg -> Reg) -> RealReg -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RealReg -> Reg
RegReal) (Maybe RealReg -> Word8) -> Maybe RealReg -> Word8
forall a b. (a -> b) -> a -> b
$ Platform -> GlobalReg -> Maybe RealReg
globalRegMaybe Platform
p GlobalReg
reg
pprSetUnwind :: Platform
-> GlobalReg
-> (Maybe UnwindExpr, Maybe UnwindExpr)
-> SDoc
pprSetUnwind :: Platform
-> GlobalReg -> (Maybe UnwindExpr, Maybe UnwindExpr) -> SDoc
pprSetUnwind plat :: Platform
plat g :: GlobalReg
g (_, Nothing)
= Platform -> GlobalReg -> SDoc
pprUndefUnwind Platform
plat GlobalReg
g
pprSetUnwind _ Sp (Just (UwReg s :: GlobalReg
s _), Just (UwReg s' :: GlobalReg
s' o' :: Int
o')) | GlobalReg
s GlobalReg -> GlobalReg -> Bool
forall a. Eq a => a -> a -> Bool
== GlobalReg
s'
= if Int
o' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= 0
then Word8 -> SDoc
pprByte Word8
dW_CFA_def_cfa_offset SDoc -> SDoc -> SDoc
$$ Word -> SDoc
pprLEBWord (Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
o')
else Word8 -> SDoc
pprByte Word8
dW_CFA_def_cfa_offset_sf SDoc -> SDoc -> SDoc
$$ Int -> SDoc
pprLEBInt Int
o'
pprSetUnwind plat :: Platform
plat Sp (_, Just (UwReg s' :: GlobalReg
s' o' :: Int
o'))
= if Int
o' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= 0
then Word8 -> SDoc
pprByte Word8
dW_CFA_def_cfa SDoc -> SDoc -> SDoc
$$
Platform -> GlobalReg -> SDoc
pprLEBRegNo Platform
plat GlobalReg
s' SDoc -> SDoc -> SDoc
$$
Word -> SDoc
pprLEBWord (Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
o')
else Word8 -> SDoc
pprByte Word8
dW_CFA_def_cfa_sf SDoc -> SDoc -> SDoc
$$
Platform -> GlobalReg -> SDoc
pprLEBRegNo Platform
plat GlobalReg
s' SDoc -> SDoc -> SDoc
$$
Int -> SDoc
pprLEBInt Int
o'
pprSetUnwind _ Sp (_, Just uw :: UnwindExpr
uw)
= Word8 -> SDoc
pprByte Word8
dW_CFA_def_cfa_expression SDoc -> SDoc -> SDoc
$$ Bool -> UnwindExpr -> SDoc
pprUnwindExpr Bool
False UnwindExpr
uw
pprSetUnwind plat :: Platform
plat g :: GlobalReg
g (_, Just (UwDeref (UwReg Sp o :: Int
o)))
| Int
o Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0 Bool -> Bool -> Bool
&& ((-Int
o) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Platform -> Int
platformWordSize Platform
plat) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0
= Word8 -> SDoc
pprByte (Word8
dW_CFA_offset Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Platform -> GlobalReg -> Word8
dwarfGlobalRegNo Platform
plat GlobalReg
g) SDoc -> SDoc -> SDoc
$$
Word -> SDoc
pprLEBWord (Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral ((-Int
o) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Platform -> Int
platformWordSize Platform
plat))
| Bool
otherwise
= Word8 -> SDoc
pprByte Word8
dW_CFA_offset_extended_sf SDoc -> SDoc -> SDoc
$$
Platform -> GlobalReg -> SDoc
pprLEBRegNo Platform
plat GlobalReg
g SDoc -> SDoc -> SDoc
$$
Int -> SDoc
pprLEBInt Int
o
pprSetUnwind plat :: Platform
plat g :: GlobalReg
g (_, Just (UwDeref uw :: UnwindExpr
uw))
= Word8 -> SDoc
pprByte Word8
dW_CFA_expression SDoc -> SDoc -> SDoc
$$
Platform -> GlobalReg -> SDoc
pprLEBRegNo Platform
plat GlobalReg
g SDoc -> SDoc -> SDoc
$$
Bool -> UnwindExpr -> SDoc
pprUnwindExpr Bool
True UnwindExpr
uw
pprSetUnwind plat :: Platform
plat g :: GlobalReg
g (_, Just (UwReg g' :: GlobalReg
g' 0))
| GlobalReg
g GlobalReg -> GlobalReg -> Bool
forall a. Eq a => a -> a -> Bool
== GlobalReg
g'
= Word8 -> SDoc
pprByte Word8
dW_CFA_same_value SDoc -> SDoc -> SDoc
$$
Platform -> GlobalReg -> SDoc
pprLEBRegNo Platform
plat GlobalReg
g
pprSetUnwind plat :: Platform
plat g :: GlobalReg
g (_, Just uw :: UnwindExpr
uw)
= Word8 -> SDoc
pprByte Word8
dW_CFA_val_expression SDoc -> SDoc -> SDoc
$$
Platform -> GlobalReg -> SDoc
pprLEBRegNo Platform
plat GlobalReg
g SDoc -> SDoc -> SDoc
$$
Bool -> UnwindExpr -> SDoc
pprUnwindExpr Bool
True UnwindExpr
uw
pprLEBRegNo :: Platform -> GlobalReg -> SDoc
pprLEBRegNo :: Platform -> GlobalReg -> SDoc
pprLEBRegNo plat :: Platform
plat = Word -> SDoc
pprLEBWord (Word -> SDoc) -> (GlobalReg -> Word) -> GlobalReg -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word) -> (GlobalReg -> Word8) -> GlobalReg -> Word
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Platform -> GlobalReg -> Word8
dwarfGlobalRegNo Platform
plat
pprUnwindExpr :: Bool -> UnwindExpr -> SDoc
pprUnwindExpr :: Bool -> UnwindExpr -> SDoc
pprUnwindExpr spIsCFA :: Bool
spIsCFA expr :: UnwindExpr
expr
= (Platform -> SDoc) -> SDoc
sdocWithPlatform ((Platform -> SDoc) -> SDoc) -> (Platform -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \plat :: Platform
plat ->
let pprE :: UnwindExpr -> SDoc
pprE (UwConst i :: Int
i)
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= 0 Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 32 = Word8 -> SDoc
pprByte (Word8
dW_OP_lit0 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i)
| Bool
otherwise = Word8 -> SDoc
pprByte Word8
dW_OP_consts SDoc -> SDoc -> SDoc
$$ Int -> SDoc
pprLEBInt Int
i
pprE (UwReg Sp i :: Int
i) | Bool
spIsCFA
= if Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0
then Word8 -> SDoc
pprByte Word8
dW_OP_call_frame_cfa
else UnwindExpr -> SDoc
pprE (UnwindExpr -> UnwindExpr -> UnwindExpr
UwPlus (GlobalReg -> Int -> UnwindExpr
UwReg GlobalReg
Sp 0) (Int -> UnwindExpr
UwConst Int
i))
pprE (UwReg g :: GlobalReg
g i :: Int
i) = Word8 -> SDoc
pprByte (Word8
dW_OP_breg0Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+Platform -> GlobalReg -> Word8
dwarfGlobalRegNo Platform
plat GlobalReg
g) SDoc -> SDoc -> SDoc
$$
Int -> SDoc
pprLEBInt Int
i
pprE (UwDeref u :: UnwindExpr
u) = UnwindExpr -> SDoc
pprE UnwindExpr
u SDoc -> SDoc -> SDoc
$$ Word8 -> SDoc
pprByte Word8
dW_OP_deref
pprE (UwLabel l :: CLabel
l) = Word8 -> SDoc
pprByte Word8
dW_OP_addr SDoc -> SDoc -> SDoc
$$ SDoc -> SDoc
pprWord (CLabel -> SDoc
forall a. Outputable a => a -> SDoc
ppr CLabel
l)
pprE (UwPlus u1 :: UnwindExpr
u1 u2 :: UnwindExpr
u2) = UnwindExpr -> SDoc
pprE UnwindExpr
u1 SDoc -> SDoc -> SDoc
$$ UnwindExpr -> SDoc
pprE UnwindExpr
u2 SDoc -> SDoc -> SDoc
$$ Word8 -> SDoc
pprByte Word8
dW_OP_plus
pprE (UwMinus u1 :: UnwindExpr
u1 u2 :: UnwindExpr
u2) = UnwindExpr -> SDoc
pprE UnwindExpr
u1 SDoc -> SDoc -> SDoc
$$ UnwindExpr -> SDoc
pprE UnwindExpr
u2 SDoc -> SDoc -> SDoc
$$ Word8 -> SDoc
pprByte Word8
dW_OP_minus
pprE (UwTimes u1 :: UnwindExpr
u1 u2 :: UnwindExpr
u2) = UnwindExpr -> SDoc
pprE UnwindExpr
u1 SDoc -> SDoc -> SDoc
$$ UnwindExpr -> SDoc
pprE UnwindExpr
u2 SDoc -> SDoc -> SDoc
$$ Word8 -> SDoc
pprByte Word8
dW_OP_mul
in String -> SDoc
text "\t.uleb128 2f-1f" SDoc -> SDoc -> SDoc
$$
String -> SDoc
text "1:" SDoc -> SDoc -> SDoc
$$
UnwindExpr -> SDoc
pprE UnwindExpr
expr SDoc -> SDoc -> SDoc
$$
String -> SDoc
text "2:"
pprUndefUnwind :: Platform -> GlobalReg -> SDoc
pprUndefUnwind :: Platform -> GlobalReg -> SDoc
pprUndefUnwind plat :: Platform
plat g :: GlobalReg
g = Word8 -> SDoc
pprByte Word8
dW_CFA_undefined SDoc -> SDoc -> SDoc
$$
Platform -> GlobalReg -> SDoc
pprLEBRegNo Platform
plat GlobalReg
g
wordAlign :: SDoc
wordAlign :: SDoc
wordAlign = (Platform -> SDoc) -> SDoc
sdocWithPlatform ((Platform -> SDoc) -> SDoc) -> (Platform -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \plat :: Platform
plat ->
String -> SDoc
text "\t.align " SDoc -> SDoc -> SDoc
<> case Platform -> OS
platformOS Platform
plat of
OSDarwin -> case Platform -> Int
platformWordSize Platform
plat of
8 -> String -> SDoc
text "3"
4 -> String -> SDoc
text "2"
_other :: Int
_other -> String -> SDoc
forall a. HasCallStack => String -> a
error "wordAlign: Unsupported word size!"
_other :: OS
_other -> Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Platform -> Int
platformWordSize Platform
plat)
pprByte :: Word8 -> SDoc
pprByte :: Word8 -> SDoc
pprByte x :: Word8
x = String -> SDoc
text "\t.byte " SDoc -> SDoc -> SDoc
<> Word -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Word8 -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
x :: Word)
pprHalf :: Word16 -> SDoc
pprHalf :: Word16 -> SDoc
pprHalf x :: Word16
x = String -> SDoc
text "\t.short" SDoc -> SDoc -> SDoc
<+> Word -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Word16 -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
x :: Word)
pprFlag :: Bool -> SDoc
pprFlag :: Bool -> SDoc
pprFlag f :: Bool
f = Word8 -> SDoc
pprByte (if Bool
f then 0xff else 0x00)
pprData4' :: SDoc -> SDoc
pprData4' :: SDoc -> SDoc
pprData4' x :: SDoc
x = String -> SDoc
text "\t.long " SDoc -> SDoc -> SDoc
<> SDoc
x
pprData4 :: Word -> SDoc
pprData4 :: Word -> SDoc
pprData4 = SDoc -> SDoc
pprData4' (SDoc -> SDoc) -> (Word -> SDoc) -> Word -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word -> SDoc
forall a. Outputable a => a -> SDoc
ppr
pprDwWord :: SDoc -> SDoc
pprDwWord :: SDoc -> SDoc
pprDwWord = SDoc -> SDoc
pprData4'
pprWord :: SDoc -> SDoc
pprWord :: SDoc -> SDoc
pprWord s :: SDoc
s = (SDoc -> SDoc -> SDoc
<> SDoc
s) (SDoc -> SDoc)
-> ((Platform -> SDoc) -> SDoc) -> (Platform -> SDoc) -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Platform -> SDoc) -> SDoc
sdocWithPlatform ((Platform -> SDoc) -> SDoc) -> (Platform -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \plat :: Platform
plat ->
case Platform -> Int
platformWordSize Platform
plat of
4 -> String -> SDoc
text "\t.long "
8 -> String -> SDoc
text "\t.quad "
n :: Int
n -> String -> SDoc
forall a. String -> a
panic (String -> SDoc) -> String -> SDoc
forall a b. (a -> b) -> a -> b
$ "pprWord: Unsupported target platform word length " String -> String -> String
forall a. [a] -> [a] -> [a]
++
Int -> String
forall a. Show a => a -> String
show Int
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ "!"
pprLEBWord :: Word -> SDoc
pprLEBWord :: Word -> SDoc
pprLEBWord x :: Word
x | Word
x Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
< 128 = Word8 -> SDoc
pprByte (Word -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
x)
| Bool
otherwise = Word8 -> SDoc
pprByte (Word -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word -> Word8) -> Word -> Word8
forall a b. (a -> b) -> a -> b
$ 128 Word -> Word -> Word
forall a. Bits a => a -> a -> a
.|. (Word
x Word -> Word -> Word
forall a. Bits a => a -> a -> a
.&. 127)) SDoc -> SDoc -> SDoc
$$
Word -> SDoc
pprLEBWord (Word
x Word -> Int -> Word
forall a. Bits a => a -> Int -> a
`shiftR` 7)
pprLEBInt :: Int -> SDoc
pprLEBInt :: Int -> SDoc
pprLEBInt x :: Int
x | Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= -64 Bool -> Bool -> Bool
&& Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 64
= Word8 -> SDoc
pprByte (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
x Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 127))
| Bool
otherwise = Word8 -> SDoc
pprByte (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ 128 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. (Int
x Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. 127)) SDoc -> SDoc -> SDoc
$$
Int -> SDoc
pprLEBInt (Int
x Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` 7)
pprString' :: SDoc -> SDoc
pprString' :: SDoc -> SDoc
pprString' str :: SDoc
str = String -> SDoc
text "\t.asciz \"" SDoc -> SDoc -> SDoc
<> SDoc
str SDoc -> SDoc -> SDoc
<> Char -> SDoc
char '"'
pprString :: String -> SDoc
pprString :: String -> SDoc
pprString str :: String
str
= SDoc -> SDoc
pprString' (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ [SDoc] -> SDoc
hcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (Char -> SDoc) -> String -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map Char -> SDoc
escapeChar (String -> [SDoc]) -> String -> [SDoc]
forall a b. (a -> b) -> a -> b
$
if String
str String -> Int -> Bool
forall a. [a] -> Int -> Bool
`lengthIs` String -> Int
utf8EncodedLength String
str
then String
str
else (Word8 -> Char) -> [Word8] -> String
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Char
chr (Int -> Char) -> (Word8 -> Int) -> Word8 -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ([Word8] -> String) -> [Word8] -> String
forall a b. (a -> b) -> a -> b
$ FastString -> [Word8]
bytesFS (FastString -> [Word8]) -> FastString -> [Word8]
forall a b. (a -> b) -> a -> b
$ String -> FastString
mkFastString String
str
escapeChar :: Char -> SDoc
escapeChar :: Char -> SDoc
escapeChar '\\' = String -> SDoc
text "\\\\"
escapeChar '\"' = String -> SDoc
text "\\\""
escapeChar '\n' = String -> SDoc
text "\\n"
escapeChar c :: Char
c
| Char -> Bool
isAscii Char
c Bool -> Bool -> Bool
&& Char -> Bool
isPrint Char
c Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= '?'
= Char -> SDoc
char Char
c
| Bool
otherwise
= Char -> SDoc
char '\\' SDoc -> SDoc -> SDoc
<> Char -> SDoc
char (Int -> Char
intToDigit (Int
ch Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` 64)) SDoc -> SDoc -> SDoc
<>
Char -> SDoc
char (Int -> Char
intToDigit ((Int
ch Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` 8) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` 8)) SDoc -> SDoc -> SDoc
<>
Char -> SDoc
char (Int -> Char
intToDigit (Int
ch Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` 8))
where ch :: Int
ch = Char -> Int
ord Char
c
sectionOffset :: SDoc -> SDoc -> SDoc
sectionOffset :: SDoc -> SDoc -> SDoc
sectionOffset target :: SDoc
target section :: SDoc
section = (Platform -> SDoc) -> SDoc
sdocWithPlatform ((Platform -> SDoc) -> SDoc) -> (Platform -> SDoc) -> SDoc
forall a b. (a -> b) -> a -> b
$ \plat :: Platform
plat ->
case Platform -> OS
platformOS Platform
plat of
OSDarwin -> SDoc -> SDoc
pprDwWord (SDoc
target SDoc -> SDoc -> SDoc
<> Char -> SDoc
char '-' SDoc -> SDoc -> SDoc
<> SDoc
section)
OSMinGW32 -> String -> SDoc
text "\t.secrel32 " SDoc -> SDoc -> SDoc
<> SDoc
target
_other :: OS
_other -> SDoc -> SDoc
pprDwWord SDoc
target