    -- | Constants describing the DWARF format. Most of this simply
    -- mirrors \/usr\/include\/dwarf.h.

    module GHC.CmmToAsm.Dwarf.Constants where

    import GHC.Prelude

    import GHC.Utils.Asm
    import GHC.Data.FastString
    import GHC.Platform
    import GHC.Utils.Outputable

    import GHC.Platform.Reg
    import GHC.CmmToAsm.X86.Regs
    import GHC.CmmToAsm.PPC.Regs (toRegNo)

    import Data.Word

    -- | Language ID used for Haskell.
    dW_LANG_Haskell :: Word
    dW_LANG_Haskell :: Word
    dW_LANG_Haskell = Word
    0x18
      -- Thanks to Nathan Howell for getting us our very own language ID!

    -- * Dwarf tags
    dW_TAG_compile_unit, dW_TAG_subroutine_type,
      dW_TAG_file_type, dW_TAG_subprogram, dW_TAG_lexical_block,
      dW_TAG_base_type, dW_TAG_structure_type, dW_TAG_pointer_type,
      dW_TAG_array_type, dW_TAG_subrange_type, dW_TAG_typedef,
      dW_TAG_variable, dW_TAG_arg_variable, dW_TAG_auto_variable,
      dW_TAG_ghc_src_note :: Word
    dW_TAG_array_type :: Word
    dW_TAG_array_type      = Word
    1
    dW_TAG_lexical_block :: Word
    dW_TAG_lexical_block   = Word
    11
    dW_TAG_pointer_type :: Word
    dW_TAG_pointer_type    = Word
    15
    dW_TAG_compile_unit :: Word
    dW_TAG_compile_unit    = Word
    17
    dW_TAG_structure_type :: Word
    dW_TAG_structure_type  = Word
    19
    dW_TAG_typedef :: Word
    dW_TAG_typedef         = Word
    22
    dW_TAG_subroutine_type :: Word
    dW_TAG_subroutine_type = Word
    32
    dW_TAG_subrange_type :: Word
    dW_TAG_subrange_type   = Word
    33
    dW_TAG_base_type :: Word
    dW_TAG_base_type       = Word
    36
    dW_TAG_file_type :: Word
    dW_TAG_file_type       = Word
    41
    dW_TAG_subprogram :: Word
    dW_TAG_subprogram      = Word
    46
    dW_TAG_variable :: Word
    dW_TAG_variable        = Word
    52
    dW_TAG_auto_variable :: Word
    dW_TAG_auto_variable   = Word
    256
    dW_TAG_arg_variable :: Word
    dW_TAG_arg_variable    = Word
    257

    dW_TAG_ghc_src_note :: Word
    dW_TAG_ghc_src_note    = Word
    0x5b00

    -- * Dwarf attributes
    dW_AT_name, dW_AT_stmt_list, dW_AT_low_pc, dW_AT_high_pc, dW_AT_language,
      dW_AT_comp_dir, dW_AT_producer, dW_AT_external, dW_AT_frame_base,
      dW_AT_use_UTF8, dW_AT_MIPS_linkage_name :: Word
    dW_AT_name :: Word
    dW_AT_name              = Word
    0x03
    dW_AT_stmt_list :: Word
    dW_AT_stmt_list         = Word
    0x10
    dW_AT_low_pc :: Word
    dW_AT_low_pc            = Word
    0x11
    dW_AT_high_pc :: Word
    dW_AT_high_pc           = Word
    0x12
    dW_AT_language :: Word
    dW_AT_language          = Word
    0x13
    dW_AT_comp_dir :: Word
    dW_AT_comp_dir          = Word
    0x1b
    dW_AT_producer :: Word
    dW_AT_producer          = Word
    0x25
    dW_AT_external :: Word
    dW_AT_external          = Word
    0x3f
    dW_AT_frame_base :: Word
    dW_AT_frame_base        = Word
    0x40
    dW_AT_use_UTF8 :: Word
    dW_AT_use_UTF8          = Word
    0x53
    dW_AT_MIPS_linkage_name :: Word
    dW_AT_MIPS_linkage_name = Word
    0x2007

    -- * Custom DWARF attributes
    -- Chosen a more or less random section of the vendor-extensible region

    -- ** Describing C-- blocks
    -- These appear in DW_TAG_lexical_scope DIEs corresponding to C-- blocks
    dW_AT_ghc_tick_parent :: Word
    dW_AT_ghc_tick_parent :: Word
    dW_AT_ghc_tick_parent     = Word
    0x2b20

    -- ** Describing source notes
    -- These appear in DW_TAG_ghc_src_note DIEs
    dW_AT_ghc_span_file, dW_AT_ghc_span_start_line,
      dW_AT_ghc_span_start_col, dW_AT_ghc_span_end_line,
      dW_AT_ghc_span_end_col :: Word
    dW_AT_ghc_span_file :: Word
    dW_AT_ghc_span_file       = Word
    0x2b00
    dW_AT_ghc_span_start_line :: Word
    dW_AT_ghc_span_start_line = Word
    0x2b01
    dW_AT_ghc_span_start_col :: Word
    dW_AT_ghc_span_start_col  = Word
    0x2b02
    dW_AT_ghc_span_end_line :: Word
    dW_AT_ghc_span_end_line   = Word
    0x2b03
    dW_AT_ghc_span_end_col :: Word
    dW_AT_ghc_span_end_col    = Word
    0x2b04

    -- * Abbrev declarations
    dW_CHILDREN_no, dW_CHILDREN_yes :: Word8
    dW_CHILDREN_no :: Word8
    dW_CHILDREN_no  = Word8
    0
    dW_CHILDREN_yes :: Word8
    dW_CHILDREN_yes = Word8
    1

    dW_FORM_addr, dW_FORM_data2, dW_FORM_data4, dW_FORM_string, dW_FORM_flag,
      dW_FORM_block1, dW_FORM_ref4, dW_FORM_ref_addr, dW_FORM_flag_present :: Word
    dW_FORM_addr :: Word
    dW_FORM_addr   = Word
    0x01
    dW_FORM_data2 :: Word
    dW_FORM_data2  = Word
    0x05
    dW_FORM_data4 :: Word
    dW_FORM_data4  = Word
    0x06
    dW_FORM_string :: Word
    dW_FORM_string = Word
    0x08
    dW_FORM_flag :: Word
    dW_FORM_flag   = Word
    0x0c
    dW_FORM_block1 :: Word
    dW_FORM_block1 = Word
    0x0a
    dW_FORM_ref_addr :: Word
    dW_FORM_ref_addr     = Word
    0x10
    dW_FORM_ref4 :: Word
    dW_FORM_ref4         = Word
    0x13
    dW_FORM_flag_present :: Word
    dW_FORM_flag_present = Word
    0x19

    -- * Dwarf native types
    dW_ATE_address, dW_ATE_boolean, dW_ATE_float, dW_ATE_signed,
      dW_ATE_signed_char, dW_ATE_unsigned, dW_ATE_unsigned_char :: Word
    dW_ATE_address :: Word
    dW_ATE_address       = Word
    1
    dW_ATE_boolean :: Word
    dW_ATE_boolean       = Word
    2
    dW_ATE_float :: Word
    dW_ATE_float         = Word
    4
    dW_ATE_signed :: Word
    dW_ATE_signed        = Word
    5
    dW_ATE_signed_char :: Word
    dW_ATE_signed_char   = Word
    6
    dW_ATE_unsigned :: Word
    dW_ATE_unsigned      = Word
    7
    dW_ATE_unsigned_char :: Word
    dW_ATE_unsigned_char = Word
    8

    -- * Call frame information
    dW_CFA_set_loc, dW_CFA_undefined, dW_CFA_same_value,
      dW_CFA_def_cfa, dW_CFA_def_cfa_offset, dW_CFA_def_cfa_expression,
      dW_CFA_expression, dW_CFA_offset_extended_sf, dW_CFA_def_cfa_offset_sf,
      dW_CFA_def_cfa_sf, dW_CFA_val_offset, dW_CFA_val_expression,
      dW_CFA_offset :: Word8
    dW_CFA_set_loc :: Word8
    dW_CFA_set_loc            = Word8
    0x01
    dW_CFA_undefined :: Word8
    dW_CFA_undefined          = Word8
    0x07
    dW_CFA_same_value :: Word8
    dW_CFA_same_value         = Word8
    0x08
    dW_CFA_def_cfa :: Word8
    dW_CFA_def_cfa            = Word8
    0x0c
    dW_CFA_def_cfa_offset :: Word8
    dW_CFA_def_cfa_offset     = Word8
    0x0e
    dW_CFA_def_cfa_expression :: Word8
    dW_CFA_def_cfa_expression = Word8
    0x0f
    dW_CFA_expression :: Word8
    dW_CFA_expression         = Word8
    0x10
    dW_CFA_offset_extended_sf :: Word8
    dW_CFA_offset_extended_sf = Word8
    0x11
    dW_CFA_def_cfa_sf :: Word8
    dW_CFA_def_cfa_sf         = Word8
    0x12
    dW_CFA_def_cfa_offset_sf :: Word8
    dW_CFA_def_cfa_offset_sf  = Word8
    0x13
    dW_CFA_val_offset :: Word8
    dW_CFA_val_offset         = Word8
    0x14
    dW_CFA_val_expression :: Word8
    dW_CFA_val_expression     = Word8
    0x16
    dW_CFA_offset :: Word8
    dW_CFA_offset             = Word8
    0x80

    -- * Operations
    dW_OP_addr, dW_OP_deref, dW_OP_consts,
      dW_OP_minus, dW_OP_mul, dW_OP_plus,
      dW_OP_lit0, dW_OP_breg0, dW_OP_call_frame_cfa :: Word8
    dW_OP_addr :: Word8
    dW_OP_addr           = Word8
    0x03
    dW_OP_deref :: Word8
    dW_OP_deref          = Word8
    0x06
    dW_OP_consts :: Word8
    dW_OP_consts         = Word8
    0x11
    dW_OP_minus :: Word8
    dW_OP_minus          = Word8
    0x1c
    dW_OP_mul :: Word8
    dW_OP_mul            = Word8
    0x1e
    dW_OP_plus :: Word8
    dW_OP_plus           = Word8
    0x22
    dW_OP_lit0 :: Word8
    dW_OP_lit0           = Word8
    0x30
    dW_OP_breg0 :: Word8
    dW_OP_breg0          = Word8
    0x70
    dW_OP_call_frame_cfa :: Word8
    dW_OP_call_frame_cfa = Word8
    0x9c

    -- * Dwarf section declarations
    dwarfInfoSection, dwarfAbbrevSection, dwarfLineSection,
      dwarfFrameSection, dwarfGhcSection, dwarfARangesSection :: Platform -> SDoc
    dwarfInfoSection :: Platform -> SDoc
    dwarfInfoSection    Platform
    platform = Platform -> String -> SDoc
    dwarfSection Platform
    platform String
    "info"
    dwarfAbbrevSection :: Platform -> SDoc
    dwarfAbbrevSection  Platform
    platform = Platform -> String -> SDoc
    dwarfSection Platform
    platform String
    "abbrev"
    dwarfLineSection :: Platform -> SDoc
    dwarfLineSection    Platform
    platform = Platform -> String -> SDoc
    dwarfSection Platform
    platform String
    "line"
    dwarfFrameSection :: Platform -> SDoc
    dwarfFrameSection   Platform
    platform = Platform -> String -> SDoc
    dwarfSection Platform
    platform String
    "frame"
    dwarfGhcSection :: Platform -> SDoc
    dwarfGhcSection     Platform
    platform = Platform -> String -> SDoc
    dwarfSection Platform
    platform String
    "ghc"
    dwarfARangesSection :: Platform -> SDoc
    dwarfARangesSection Platform
    platform = Platform -> String -> SDoc
    dwarfSection Platform
    platform String
    "aranges"

    dwarfSection :: Platform -> String -> SDoc
    dwarfSection :: Platform -> String -> SDoc
    dwarfSection Platform
    platform String
    name =
      case Platform -> OS
    platformOS Platform
    platform of
        OS
    os | OS -> Bool
    osElfTarget OS
    os
           -> String -> SDoc
    text String
    "\t.section .debug_" SDoc -> SDoc -> SDoc
    <> String -> SDoc
    text String
    name SDoc -> SDoc -> SDoc
    <> String -> SDoc
    text String
    ",\"\","
              SDoc -> SDoc -> SDoc
    <> Platform -> String -> SDoc
    sectionType Platform
    platform String
    "progbits"
           | OS -> Bool
    osMachOTarget OS
    os
           -> String -> SDoc
    text String
    "\t.section __DWARF,__debug_" SDoc -> SDoc -> SDoc
    <> String -> SDoc
    text String
    name SDoc -> SDoc -> SDoc
    <> String -> SDoc
    text String
    ",regular,debug"
           | Bool
    otherwise
           -> String -> SDoc
    text String
    "\t.section .debug_" SDoc -> SDoc -> SDoc
    <> String -> SDoc
    text String
    name SDoc -> SDoc -> SDoc
    <> String -> SDoc
    text String
    ",\"dr\""

    -- * Dwarf section labels
    dwarfInfoLabel, dwarfAbbrevLabel, dwarfLineLabel, dwarfFrameLabel :: PtrString
    dwarfInfoLabel :: PtrString
    dwarfInfoLabel   = String -> PtrString
    sLit String
    ".Lsection_info"
    dwarfAbbrevLabel :: PtrString
    dwarfAbbrevLabel = String -> PtrString
    sLit String
    ".Lsection_abbrev"
    dwarfLineLabel :: PtrString
    dwarfLineLabel   = String -> PtrString
    sLit String
    ".Lsection_line"
    dwarfFrameLabel :: PtrString
    dwarfFrameLabel  = String -> PtrString
    sLit String
    ".Lsection_frame"

    -- | Mapping of registers to DWARF register numbers
    dwarfRegNo :: Platform -> Reg -> Word8
    dwarfRegNo :: Platform -> Reg -> Word8
    dwarfRegNo Platform
    p Reg
    r = case Platform -> Arch
    platformArch Platform
    p of
      Arch
    ArchX86
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    eax  -> Word8
    0
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    ecx  -> Word8
    1  -- yes, no typo
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    edx  -> Word8
    2
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    ebx  -> Word8
    3
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    esp  -> Word8
    4
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    ebp  -> Word8
    5
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    esi  -> Word8
    6
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    edi  -> Word8
    7
      Arch
    ArchX86_64
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    rax  -> Word8
    0
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    rdx  -> Word8
    1 -- this neither. The order GCC allocates registers in?
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    rcx  -> Word8
    2
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    rbx  -> Word8
    3
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    rsi  -> Word8
    4
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    rdi  -> Word8
    5
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    rbp  -> Word8
    6
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    rsp  -> Word8
    7
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    r8   -> Word8
    8
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    r9   -> Word8
    9
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    r10  -> Word8
    10
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    r11  -> Word8
    11
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    r12  -> Word8
    12
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    r13  -> Word8
    13
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    r14  -> Word8
    14
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    r15  -> Word8
    15
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    xmm0 -> Word8
    17
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    xmm1 -> Word8
    18
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    xmm2 -> Word8
    19
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    xmm3 -> Word8
    20
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    xmm4 -> Word8
    21
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    xmm5 -> Word8
    22
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    xmm6 -> Word8
    23
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    xmm7 -> Word8
    24
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    xmm8 -> Word8
    25
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    xmm9 -> Word8
    26
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    xmm10 -> Word8
    27
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    xmm11 -> Word8
    28
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    xmm12 -> Word8
    29
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    xmm13 -> Word8
    30
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    xmm14 -> Word8
    31
        | Reg
    r Reg -> Reg -> Bool
    forall a. Eq a => a -> a -> Bool
    == Reg
    xmm15 -> Word8
    32
      ArchPPC_64 PPC_64ABI
    _ -> RegNo -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (RegNo -> Word8) -> RegNo -> Word8
    forall a b. (a -> b) -> a -> b
    $ Reg -> RegNo
    toRegNo Reg
    r
      Arch
    _other -> String -> Word8
    forall a. HasCallStack => String -> a
    error String
    "dwarfRegNo: Unsupported platform or unknown register!"

    -- | Virtual register number to use for return address.
    dwarfReturnRegNo :: Platform -> Word8
    dwarfReturnRegNo :: Platform -> Word8
    dwarfReturnRegNo Platform
    p
      -- We "overwrite" IP with our pseudo register - that makes sense, as
      -- when using this mechanism gdb already knows the IP anyway. Clang
      -- does this too, so it must be safe.
      = case Platform -> Arch
    platformArch Platform
    p of
        Arch
    ArchX86    -> Word8
    8  -- eip
        Arch
    ArchX86_64 -> Word8
    16 -- rip
        ArchPPC_64 PPC_64ABI
    ELF_V2 -> Word8
    65 -- lr (link register)
        Arch
    _other     -> String -> Word8
    forall a. HasCallStack => String -> a
    error String
    "dwarfReturnRegNo: Unsupported platform!"