{-# LINE 1 "src/Bindings/Bfd/Disassembler/Info.hsc" #-}
-- This file is part of Bindings-bfd.
{-# LINE 2 "src/Bindings/Bfd/Disassembler/Info.hsc" #-}
--
-- Copyright (C) 2010 Michael Nelson
--
-- Bindings-bfd is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Lesser General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- Bindings-bfd is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU Lesser General Public License for more details.

-- You should have received a copy of the GNU Lesser General Public License
-- along with Bindings-bfd.  If not, see <http://www.gnu.org/licenses/>.

module Bindings.Bfd.Disassembler.Info where

import Foreign.C
import Foreign.Marshal
import Foreign.Ptr
import Foreign.Storable

import System.Posix.IO
import System.Posix.Types

import Bindings.Bfd.Misc


{-# LINE 31 "src/Bindings/Bfd/Disassembler/Info.hsc" #-}


type FPrintfFn = FunPtr (File -> CString -> IO CInt)


data Info = Info Info0 Fd
     deriving (Eq)

type Info0 = Ptr Info'

data Info' = Machine{- {
                          fprintfFunc            :: FunPtr (Ptr Void, CString)
                        , stream                 :: Ptr Void
                        , flavour                :: Flavour
                        , arch                   :: Architecture
                        , mach                   :: Machine
                        , endian                 :: Endian
                        , endianCode             :: Endian
                        , insnSets               :: Void Ptr
                        , section                :: Maybe Section
                        , symbols                :: [Symbol]
                        , numSymbols             :: Int
                        , symtab                 :: [Symbol]
                        , symtabPos              :: Int
                        , symtabSize             :: Int
                        , flags                  :: Flags
                        , privateData            :: Ptr Void
                        , readMemoryFunc         :: FunPtr (CInt, Vma, Info)
                        , printAddressFunc       :: FunPtr (Vma, Info)
                        , symbolAtAddressFunc    :: FunPtr (Vma, Info)
                        , symbolIsValidFunc      :: FunPtr (Symbol, Info)
                        , buffer                 :: Ptr CChar
                        , bufferVma              :: Vma
                        , bufferLength           :: Int
                        , bytesPerLine           :: Int
                        , bytesPerChunk          :: Int
                        , displayEndian          :: Endian
                        , octetsPerByte          :: Int
                        , skipZeros              :: Int
                        , skipZerosAtEnd         :: Int
                        , disassemblerNeedRelocs :: Bool
                        , insnInfoValid          :: Bool
                        , branchDelayInsn        :: Int
                        , dataSize               :: Int
                        , insnType               :: Type
                        , target                 :: Vma
                        , target2                :: Vma
                        , disassemblerOptions    :: String

             }
-}

instance Storable Info' where
   sizeOf _ = (160)
{-# LINE 85 "src/Bindings/Bfd/Disassembler/Info.hsc" #-}
   alignment = sizeOf
   pokeByteOff buf off val
      | off == ((76)) =
{-# LINE 88 "src/Bindings/Bfd/Disassembler/Info.hsc" #-}
            ((\hsc_ptr -> pokeByteOff hsc_ptr 76)) buf val
{-# LINE 89 "src/Bindings/Bfd/Disassembler/Info.hsc" #-}
      | off == ((88)) = 
{-# LINE 90 "src/Bindings/Bfd/Disassembler/Info.hsc" #-}
            ((\hsc_ptr -> pokeByteOff hsc_ptr 88)) buf val
{-# LINE 91 "src/Bindings/Bfd/Disassembler/Info.hsc" #-}
      | off == ((92)) = 
{-# LINE 92 "src/Bindings/Bfd/Disassembler/Info.hsc" #-}
            ((\hsc_ptr -> pokeByteOff hsc_ptr 92)) buf val
{-# LINE 93 "src/Bindings/Bfd/Disassembler/Info.hsc" #-}
      | off == ((100)) = 
{-# LINE 94 "src/Bindings/Bfd/Disassembler/Info.hsc" #-}
            ((\hsc_ptr -> pokeByteOff hsc_ptr 100)) buf val
{-# LINE 95 "src/Bindings/Bfd/Disassembler/Info.hsc" #-}
      | off == ((156)) =
{-# LINE 96 "src/Bindings/Bfd/Disassembler/Info.hsc" #-}
            ((\hsc_ptr -> pokeByteOff hsc_ptr 156)) buf val 
{-# LINE 97 "src/Bindings/Bfd/Disassembler/Info.hsc" #-}
   pokeByteOff _   off _ = error $ "Info.pokeByteOff: " ++ show off     
   peekByteOff _ _ = error $ "Info.peekByteOff undefined"

mk
   :: IO Info
mk =
   do
      (pipeRead, pipeWrite) <- createPipe
      setFdOption pipeRead NonBlockingRead True
      let
         pipeWrite' = fromIntegral pipeWrite
      mode <- newCString "w"
      fpWrite <- c_fdopen pipeWrite' mode
      i <- malloc :: IO Info0
      c_init_disassemble_info i fpWrite c_bfd_disassembler_info_fprintf -- structure zeroed here
      pokeByteOff i ((76)) c_bfd_disassembler_info_print_address
{-# LINE 113 "src/Bindings/Bfd/Disassembler/Info.hsc" #-}
      return $ Info i pipeRead

setMachine
   :: Info
   -> Int
   -> IO ()
setMachine (Info info _) mach = pokeByteOff info ((20)) mach
{-# LINE 120 "src/Bindings/Bfd/Disassembler/Info.hsc" #-}

setBuffer 
   :: Info
   -> String
   -> Vma
   -> IO ()
setBuffer (Info info _) str vma =
   do
      str' <- newCAStringLen str
      pokeByteOff info ((88)) $ fst str'
{-# LINE 130 "src/Bindings/Bfd/Disassembler/Info.hsc" #-}
      pokeByteOff info ((100)) $ snd str'
{-# LINE 131 "src/Bindings/Bfd/Disassembler/Info.hsc" #-}
      pokeByteOff info ((92)) vma
{-# LINE 132 "src/Bindings/Bfd/Disassembler/Info.hsc" #-}

setOptions
   :: Info
   -> String
   -> IO ()
setOptions (Info info _) str =
   do
      str' <- newCString str
      pokeByteOff info ((156)) str'
{-# LINE 141 "src/Bindings/Bfd/Disassembler/Info.hsc" #-}

foreign import ccall unsafe "dis-asm.h init_disassemble_info" c_init_disassemble_info
   :: Info0
   -> File
   -> FPrintfFn
   -> IO ()

foreign import ccall unsafe "cbits/disassembler.h &_bfd_disassembler_info_fprintf" c_bfd_disassembler_info_fprintf
   :: FPrintfFn

foreign import ccall unsafe "cbits/disassembler.h &_bfd_disassembler_info_print_address" c_bfd_disassembler_info_print_address
   :: FunPtr (Vma' -> Info0 -> IO ())