{-# LINE 1 "src/Bindings/Bfd/Target.hsc" #-}
-- This file is part of Bindings-bfd.
{-# LINE 2 "src/Bindings/Bfd/Target.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.Target (
   -- * Types
     Target
   , Target'
   , TargetName
   -- * Functions
   -- ** Platform
   , list
   , setDefault
   -- ** Target
   , getByteorder
   , getHeaderByteorder
   , getObjectFlags
   , getSectionFlags
   , Bindings.Bfd.Target.getFlavour
   , getName
   -- ** Symtabs
   , getSymtabUpperBound
   , canonicalizeSymtab
   , getDynamicSymtabUpperBound
   , canonicalizeDynamicSymtab
   , getSyntheticSymtab
   -- ** Relocations
   , getDynamicRelocUpperBound
   , canonicalizeDynamicReloc
   , getPrintSymbol
) where

import Data.Bits
import Data.Word

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

import {-# SOURCE #-} Bindings.Bfd
import                Bindings.Bfd.Endian
import                Bindings.Bfd.Flags         as BfdFlags
import                Bindings.Bfd.Flavour
import                Bindings.Bfd.Misc
import {-# SOURCE #-} Bindings.Bfd.Relocation
import                Bindings.Bfd.Section.Flags as SectionFlags
import {-# SOURCE #-} Bindings.Bfd.Symbol        as Symbol
import {-# SOURCE #-} Bindings.Bfd.SymbolTable


{-# LINE 65 "src/Bindings/Bfd/Target.hsc" #-}


type TargetName = String

type Target = Ptr Target'

data Target' = Name                       TargetName
             | Flavour                    Flavour
             | Byteorder                  Endian
             | HeaderByteorder            Endian
             | ObjectFlags                [BfdFlags.Flags]
             | SectionFlags               [SectionFlags.Flags]
             | GetSymtabUpperBound        (FunPtr (Bfd -> IO CLong))
             | CanonicalizeSymtab         (FunPtr (Bfd -> Ptr Symbol -> IO CLong))
             | PrintSymbol                (FunPtr (Bfd -> File -> Symbol -> CUInt -> IO ()))
             | GetDynamicSymtabUpperBound (FunPtr (Bfd -> IO CLong))
             | CanonicalizeDynamicSymtab  (FunPtr (Bfd -> Ptr Symbol -> IO CLong))
             | GetSyntheticSymtab         (FunPtr (Bfd -> CLong -> Ptr Symbol -> CLong -> Ptr Symbol -> Ptr Symbol -> IO CLong))
             | GetDynamicRelocUpperBound  (FunPtr (Bfd -> IO CLong))
             | CanonicalizeDynamicReloc   (FunPtr (Bfd -> Ptr (Ptr Relocation) -> Ptr Symbol -> IO CLong))
     deriving (Show)

instance Storable Target' where
   sizeOf _ = (420)
{-# LINE 89 "src/Bindings/Bfd/Target.hsc" #-}
   alignment = sizeOf
   peekByteOff buf off
      | off == ((0)) =
{-# LINE 92 "src/Bindings/Bfd/Target.hsc" #-}
         do
            val <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) buf
{-# LINE 94 "src/Bindings/Bfd/Target.hsc" #-}
            s   <- peekCString val
            return $ Bindings.Bfd.Target.Name s
      | off == ((4)) =
{-# LINE 97 "src/Bindings/Bfd/Target.hsc" #-}
         do
            val <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) buf :: IO CUInt
{-# LINE 99 "src/Bindings/Bfd/Target.hsc" #-}
            return $ Flavour $ toEnum $ fromIntegral val
      | off == ((8)) =
{-# LINE 101 "src/Bindings/Bfd/Target.hsc" #-}
         do
            val <- ((\hsc_ptr -> peekByteOff hsc_ptr 8)) buf :: IO CUInt
{-# LINE 103 "src/Bindings/Bfd/Target.hsc" #-}
            return $ Byteorder $ toEnum $ fromIntegral val
      | off == ((12)) =
{-# LINE 105 "src/Bindings/Bfd/Target.hsc" #-}
         do
            val <- ((\hsc_ptr -> peekByteOff hsc_ptr 12)) buf :: IO CUInt
{-# LINE 107 "src/Bindings/Bfd/Target.hsc" #-}
            return $ HeaderByteorder $ toEnum $ fromIntegral val
      | off == ((16)) =
{-# LINE 109 "src/Bindings/Bfd/Target.hsc" #-}
         do
            val <- ((\hsc_ptr -> peekByteOff hsc_ptr 16)) buf :: IO CUInt
{-# LINE 111 "src/Bindings/Bfd/Target.hsc" #-}
            let
               flags = filter f $ enumFrom HasReloc
                  where
                     f e = val .&. (bit $ fromEnum e) /= 0
            return $ ObjectFlags flags
      | off == ((20)) =
{-# LINE 117 "src/Bindings/Bfd/Target.hsc" #-}
         do
            val <- ((\hsc_ptr -> peekByteOff hsc_ptr 20)) buf :: IO CUInt
{-# LINE 119 "src/Bindings/Bfd/Target.hsc" #-}
            let
               flags = filter f $ enumFrom Alloc
                  where
                     f e = val .&. (bit $ fromEnum e) /= 0
            return $ SectionFlags flags
      | off == ((252)) =
{-# LINE 125 "src/Bindings/Bfd/Target.hsc" #-}
         do
            val <- ((\hsc_ptr -> peekByteOff hsc_ptr 252)) buf :: IO Word
{-# LINE 127 "src/Bindings/Bfd/Target.hsc" #-}
            return $ GetSymtabUpperBound $ castPtrToFunPtr $ wordPtrToPtr $ fromIntegral val
      | off == ((256)) =
{-# LINE 129 "src/Bindings/Bfd/Target.hsc" #-}
         do
            val <- ((\hsc_ptr -> peekByteOff hsc_ptr 256)) buf :: IO Word
{-# LINE 131 "src/Bindings/Bfd/Target.hsc" #-}
            return $ CanonicalizeSymtab $ castPtrToFunPtr $ wordPtrToPtr $ fromIntegral val
      | off == ((264)) =
{-# LINE 133 "src/Bindings/Bfd/Target.hsc" #-}
         do
            val <- ((\hsc_ptr -> peekByteOff hsc_ptr 264)) buf :: IO Word
{-# LINE 135 "src/Bindings/Bfd/Target.hsc" #-}
            return $ PrintSymbol $ castPtrToFunPtr $ wordPtrToPtr $ fromIntegral val
      | off == ((392)) =
{-# LINE 137 "src/Bindings/Bfd/Target.hsc" #-}
         do
            val <- ((\hsc_ptr -> peekByteOff hsc_ptr 392)) buf :: IO Word
{-# LINE 139 "src/Bindings/Bfd/Target.hsc" #-}
            return $ GetDynamicSymtabUpperBound $ castPtrToFunPtr $ wordPtrToPtr $ fromIntegral val
      | off == ((396)) =
{-# LINE 141 "src/Bindings/Bfd/Target.hsc" #-}
         do
            val <- ((\hsc_ptr -> peekByteOff hsc_ptr 396)) buf :: IO Word
{-# LINE 143 "src/Bindings/Bfd/Target.hsc" #-}
            return $ CanonicalizeDynamicSymtab $ castPtrToFunPtr $ wordPtrToPtr $ fromIntegral val
      | off == ((400)) =
{-# LINE 145 "src/Bindings/Bfd/Target.hsc" #-}
         do
            val <- ((\hsc_ptr -> peekByteOff hsc_ptr 400)) buf :: IO Word
{-# LINE 147 "src/Bindings/Bfd/Target.hsc" #-}
            return $ GetSyntheticSymtab $ castPtrToFunPtr $ wordPtrToPtr $ fromIntegral val
      | off == ((404)) =
{-# LINE 149 "src/Bindings/Bfd/Target.hsc" #-}
         do
            val <- ((\hsc_ptr -> peekByteOff hsc_ptr 404)) buf :: IO Word
{-# LINE 151 "src/Bindings/Bfd/Target.hsc" #-}
            return $ GetDynamicRelocUpperBound $ castPtrToFunPtr $ wordPtrToPtr $ fromIntegral val
      | off == ((408)) =
{-# LINE 153 "src/Bindings/Bfd/Target.hsc" #-}
         do
            val <- ((\hsc_ptr -> peekByteOff hsc_ptr 408)) buf :: IO Word
{-# LINE 155 "src/Bindings/Bfd/Target.hsc" #-}
            return $ CanonicalizeDynamicReloc $ castPtrToFunPtr $ wordPtrToPtr $ fromIntegral val
      | otherwise = error $ "internal error: Bfd.Target.peekByteOff " ++ show off


list
   :: IO [TargetName]
list = 
   do
      let
         pts = c_bfd_target_list
      ps <- peekArray0 nullPtr pts
      mapM peekCString ps

setDefault
   :: TargetName
   -> IO Bool
setDefault tn =
   do
      s <- newCString tn
      r <- c_bfd_set_default_target s
      return $ toBool r


getByteorder
   :: Target
   -> IO Endian
getByteorder targ =
   do
      bo <- peekByteOff targ ((8))
{-# LINE 184 "src/Bindings/Bfd/Target.hsc" #-}
      return $ unTarget'Byteorder bo

getHeaderByteorder
   :: Target
   -> IO Endian
getHeaderByteorder targ =
   do
      bo <- peekByteOff targ ((12))
{-# LINE 192 "src/Bindings/Bfd/Target.hsc" #-}
      return $ unTarget'HeaderByteorder bo

getObjectFlags
   :: Target
   -> IO [BfdFlags.Flags]
getObjectFlags targ =
   do
      f <- peekByteOff targ ((16))
{-# LINE 200 "src/Bindings/Bfd/Target.hsc" #-}
      return $ unTarget'ObjectFlags f

getSectionFlags
   :: Target
   -> IO [SectionFlags.Flags]
getSectionFlags targ =
   do
      f <- peekByteOff targ ((20))
{-# LINE 208 "src/Bindings/Bfd/Target.hsc" #-}
      return $ unTarget'SectionFlags f

getFlavour
   :: Target
   -> IO Flavour
getFlavour targ =
   do
      flav <- peekByteOff targ ((4))
{-# LINE 216 "src/Bindings/Bfd/Target.hsc" #-}
      return $ unTarget'Flavour flav

getName
   :: Target
   -> IO TargetName
getName targ =
   do
      tn <- peekByteOff targ ((0))
{-# LINE 224 "src/Bindings/Bfd/Target.hsc" #-}
      let
         tn' = unTarget'Name tn
      return tn'


getSymtabUpperBound
   :: Target
   -> Bfd
   -> IO Int
getSymtabUpperBound targ bfd =
   do
      fn <- peekByteOff targ ((252))
{-# LINE 236 "src/Bindings/Bfd/Target.hsc" #-}
      r <- d_Bfd_CLong (unTarget'GetSymtabUpperBound fn) bfd
      return $ fromIntegral r

canonicalizeSymtab
   :: Target
   -> Bfd
   -> Ptr Symbol
   -> IO Int
canonicalizeSymtab targ bfd ps =
   do
      fn <- peekByteOff targ ((256))
{-# LINE 247 "src/Bindings/Bfd/Target.hsc" #-}
      r <- d_Bfd_PtrSymbol_CLong (unTarget'CanonicalizeSymtab fn) bfd ps
      return $ fromIntegral r

getDynamicSymtabUpperBound
   :: Target
   -> Bfd
   -> IO Int
getDynamicSymtabUpperBound targ bfd =
   do
      fn <- peekByteOff targ ((392))
{-# LINE 257 "src/Bindings/Bfd/Target.hsc" #-}
      r <- d_Bfd_CLong (unTarget'GetDynamicSymtabUpperBound fn) bfd
      return $ fromIntegral r

canonicalizeDynamicSymtab
   :: Target
   -> Bfd
   -> Ptr Symbol
   -> IO Int
canonicalizeDynamicSymtab targ bfd ps =
   do
      fn <- peekByteOff targ ((396))
{-# LINE 268 "src/Bindings/Bfd/Target.hsc" #-}
      r <- d_Bfd_PtrSymbol_CLong (unTarget'CanonicalizeDynamicSymtab fn) bfd ps
      return $ fromIntegral r

getSyntheticSymtab
   :: Target
   -> Bfd
   -> SymbolTable
   -> SymbolTable
   -> Ptr Symbol
   -> IO Int
getSyntheticSymtab targ bfd sst dst synth =
   do
      fn <- peekByteOff targ ((400))
{-# LINE 281 "src/Bindings/Bfd/Target.hsc" #-}
      r <- d_Bfd_CLong_PtrSymbol_CLong_PtrSymbol_PtrSymbol_CLong (fn' fn) bfd sts stp dts dtp synth
      return $ fromIntegral r
   where
      fn' = unTarget'GetSyntheticSymtab
      sts = fromIntegral $ tableSize sst
      stp = tablePtr sst
      dts = fromIntegral $ tableSize dst
      dtp = tablePtr dst

getDynamicRelocUpperBound
   :: Target
   -> Bfd
   -> IO Int
getDynamicRelocUpperBound targ bfd =
   do
      fn <- peekByteOff targ ((404))
{-# LINE 297 "src/Bindings/Bfd/Target.hsc" #-}
      r <- d_Bfd_CLong (unTarget'GetDynamicRelocUpperBound fn) bfd
      return $ fromIntegral r

canonicalizeDynamicReloc
   :: Target
   -> Bfd
   -> Ptr (Ptr Relocation)
   -> Ptr Symbol
   -> IO Int
canonicalizeDynamicReloc targ bfd rels syms =
   do
      fn <- peekByteOff targ ((408))
{-# LINE 309 "src/Bindings/Bfd/Target.hsc" #-}
      r <- d_Bfd_PtrPtrRelocation_PtrSymbol_CLong (unTarget'CanonicalizeDynamicReloc fn) bfd rels syms
      return $ fromIntegral r


unTarget'Name
   :: Target'
   -> TargetName
unTarget'Name (Bindings.Bfd.Target.Name s) = s
unTarget'Name _                            = error "unTarget'Name"

unTarget'Flavour
   :: Target'
   -> Flavour
unTarget'Flavour (Flavour f) = f
unTarget'Flavour _           = error "unTarget'Flavour"

unTarget'Byteorder
   :: Target'
   -> Endian
unTarget'Byteorder (Byteorder b) = b
unTarget'Byteorder _             = error "unTarget'Byteorder"

unTarget'HeaderByteorder
   :: Target'
   -> Endian
unTarget'HeaderByteorder (HeaderByteorder b) = b
unTarget'HeaderByteorder _                   = error "unTarget'HeaderByteorder"

unTarget'ObjectFlags
   :: Target'
   -> [BfdFlags.Flags]
unTarget'ObjectFlags (ObjectFlags b) = b
unTarget'ObjectFlags _               = error "unTarget'ObjectFlags"

unTarget'SectionFlags
   :: Target'
   -> [SectionFlags.Flags]
unTarget'SectionFlags (SectionFlags b) = b
unTarget'SectionFlags _                = error "unTarget'SectionFlags"

unTarget'GetSymtabUpperBound
   :: Target'
   -> FunPtr (Bfd -> IO CLong)
unTarget'GetSymtabUpperBound (GetSymtabUpperBound fn) = fn
unTarget'GetSymtabUpperBound _                        = error "unTarget'GetSymtabUpperBound"

unTarget'CanonicalizeSymtab
   :: Target'
   -> FunPtr (Bfd -> Ptr Symbol -> IO CLong)
unTarget'CanonicalizeSymtab (CanonicalizeSymtab fn) = fn
unTarget'CanonicalizeSymtab _                       = error "unTarget'CanonicalizeSymtab"

unTarget'GetDynamicSymtabUpperBound
   :: Target'
   -> FunPtr (Bfd -> IO CLong)
unTarget'GetDynamicSymtabUpperBound (GetDynamicSymtabUpperBound fn) = fn
unTarget'GetDynamicSymtabUpperBound _                               = error "unTarget'GetDynamicSymtabUpperBound"

unTarget'CanonicalizeDynamicSymtab
   :: Target'
   -> FunPtr (Bfd -> Ptr Symbol -> IO CLong)
unTarget'CanonicalizeDynamicSymtab (CanonicalizeDynamicSymtab fn) = fn
unTarget'CanonicalizeDynamicSymtab _                              = error "unTarget'CanonicalizeDynamicSymtab"

unTarget'GetSyntheticSymtab
   :: Target'
   -> FunPtr (Bfd -> CLong -> Ptr Symbol -> CLong -> Ptr Symbol -> Ptr Symbol -> IO CLong)
unTarget'GetSyntheticSymtab (GetSyntheticSymtab fn) = fn
unTarget'GetSyntheticSymtab _                       = error "unTarget'GetSyntheticSymtab"

unTarget'GetDynamicRelocUpperBound
   :: Target'
   -> FunPtr (Bfd -> IO CLong)
unTarget'GetDynamicRelocUpperBound (GetDynamicRelocUpperBound fn) = fn
unTarget'GetDynamicRelocUpperBound _                              = error "unTarget'GetDynamicRelocUpperBound"

unTarget'CanonicalizeDynamicReloc
   :: Target'
   -> FunPtr (Bfd -> Ptr (Ptr Relocation) -> Ptr Symbol -> IO CLong)
unTarget'CanonicalizeDynamicReloc (CanonicalizeDynamicReloc fn) = fn
unTarget'CanonicalizeDynamicReloc _                             = error "unTarget'CanonicalizeDynamicReloc"

unXVec2
   :: Target'
   -> FunPtr (Bfd -> File -> Symbol -> CUInt -> IO ())
unXVec2 (PrintSymbol fn) = fn
unXVec2 x                = error $ "internal error: unXVec2 " ++ show x


getPrintSymbol
   :: Target
   -> Bfd
   -> File
   -> Symbol
   -> IO (IO ())
getPrintSymbol targ bfd file sym =
   do 
      fn <- peekByteOff targ ((264))
{-# LINE 407 "src/Bindings/Bfd/Target.hsc" #-}
      let
         f = d_Bfd_File_Symbol_CUInt_Void (unXVec2 fn) bfd file sym 2
      return f


foreign import ccall unsafe "bfd.h bfd_target_list" c_bfd_target_list
   :: Ptr CString

foreign import ccall unsafe "bfd.h bfd_set_default_target" c_bfd_set_default_target
   :: CString
   -> IO CInt

foreign import ccall unsafe "dynamic" d_Bfd_CLong
   :: FunPtr (Bfd -> IO CLong)
   -> (Bfd -> IO CLong)

foreign import ccall unsafe "dynamic" d_Bfd_CLong_PtrSymbol_CLong_PtrSymbol_PtrSymbol_CLong
   :: FunPtr (Bfd -> CLong -> Ptr Symbol -> CLong -> Ptr Symbol -> Ptr Symbol -> IO CLong) 
   -> (Bfd -> CLong -> Ptr Symbol -> CLong -> Ptr Symbol -> Ptr Symbol -> IO CLong)

foreign import ccall unsafe "dynamic" d_Bfd_PtrSymbol_CLong
   :: FunPtr (Bfd -> Ptr Symbol -> IO CLong)
   -> (Bfd -> Ptr Symbol -> IO CLong)

foreign import ccall unsafe "dynamic" d_Bfd_PtrPtrRelocation_PtrSymbol_CLong
   :: FunPtr (Bfd -> Ptr (Ptr Relocation) -> Ptr Symbol -> IO CLong) 
   -> (Bfd -> Ptr (Ptr Relocation) -> Ptr Symbol -> IO CLong)

foreign import ccall unsafe "dynamic" d_Bfd_File_Symbol_CUInt_Void
   :: FunPtr (Bfd -> File -> Symbol -> CUInt -> IO ()) 
   -> (Bfd -> File -> Symbol -> CUInt -> IO ())