module Bindings.Bfd.Symbol (
Symbol
, Symbol'
, SymbolName
, getBase
, getBfd
, getFlags
, Bindings.Bfd.Symbol.getFlavour
, Bindings.Bfd.Symbol.getName
, setName
, getSection
, setSection
, Bindings.Bfd.Symbol.getOutputSection
, getSize
, getValue
, setValue
, getValue'
, Bindings.Bfd.Symbol.print
) where
import Data.Bits
import Data.Word
import Foreign.C
import Foreign.Ptr
import Foreign.Storable
import System.Posix.IO
import Bindings.Bfd as Bfd
import Bindings.Bfd.Flavour
import Bindings.Bfd.Misc
import Bindings.Bfd.Section as Section
import Bindings.Bfd.Symbol.Flags as SymbolFlags
import Bindings.Bfd.Target
type SymbolName = String
type Symbol = Ptr Symbol'
data Symbol' = Bfd Bfd
| Name CString
| Value Vma
| Flags Int
| Section Section
deriving (Show)
instance Storable Symbol' where
sizeOf _ = ((32))
alignment = sizeOf
peekByteOff buf off
| off == ((0)) =
do
val <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) buf :: IO Bfd
return $ Bfd val
| off == ((4)) =
do
val <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) buf :: IO Word
return $ Bindings.Bfd.Symbol.Name $ wordPtrToPtr $ fromIntegral val
| off == ((8)) =
do
val <- ((\hsc_ptr -> peekByteOff hsc_ptr 8)) buf
return $ Value val
| off == ((16)) =
do
val <- ((\hsc_ptr -> peekByteOff hsc_ptr 16)) buf :: IO CUInt
return $ Bindings.Bfd.Symbol.Flags $ fromIntegral val
| off == ((20)) =
do
val <- ((\hsc_ptr -> peekByteOff hsc_ptr 20)) buf
return $ Section val
| otherwise = error $ "internal error: Bfd.Symbol.peekByteOffset " ++ show off
pokeByteOff buf off val
| off == ((4)) =
((\hsc_ptr -> pokeByteOff hsc_ptr 4)) buf (unSymbol'Name val)
| off == ((8)) =
((\hsc_ptr -> pokeByteOff hsc_ptr 8)) buf (unSymbol'Value val)
| off == ((20)) =
((\hsc_ptr -> pokeByteOff hsc_ptr 20)) buf (unSymbol'Section val)
| otherwise = error $ "internal error: Bfd.Symbol.pokeByteOff " ++ show off
unSymbol'TheBfd
:: Symbol'
-> Bfd
unSymbol'TheBfd (Bfd b) = b
unSymbol'TheBfd _ = error "unSymbol'TheBfd"
unSymbol'Name
:: Symbol'
-> CString
unSymbol'Name (Bindings.Bfd.Symbol.Name s) = s
unSymbol'Name _ = error "unSymbol'Name"
unSymbol'Value
:: Symbol'
-> Vma
unSymbol'Value (Value v) = v
unSymbol'Value _ = error "unSymbol'Value"
unSymbol'Flags
:: Symbol'
-> Int
unSymbol'Flags (Bindings.Bfd.Symbol.Flags f) = f
unSymbol'Flags _ = error "unSymbol'Flags"
unSymbol'Section
:: Symbol'
-> Section
unSymbol'Section (Section s) = s
unSymbol'Section _ = error "unSymbol'Section"
getBase
:: Symbol
-> IO Vma
getBase sym =
do
sect <- getSection sym
getVma sect
getBfd
:: Symbol
-> IO Bfd
getBfd sym =
do
bfd <- peekByteOff sym ((0))
return $ unSymbol'TheBfd bfd
getFlags
:: Symbol
-> IO [SymbolFlags.Flags]
getFlags sym =
do
flags <- peekByteOff sym ((16))
let
flags' = filter f $ enumFrom Local
where
f e = unSymbol'Flags flags .&. (bit $ fromEnum e) /= 0
return flags'
getFlavour
:: Symbol
-> IO Flavour
getFlavour sym =
do
flags <- getFlags sym
case Synthetic `elem` flags of
True -> return Unknown
False ->
do
bfd <- getBfd sym
Bfd.getFlavour bfd
getName
:: Symbol
-> IO SymbolName
getName sym =
do
s' <- peekByteOff sym ((4))
peekCString $ unSymbol'Name s'
setName
:: Symbol
-> SymbolName
-> IO ()
setName sym name =
do
cs <- newCString name
pokeByteOff sym ((4)) $ Bindings.Bfd.Symbol.Name cs
getSection
:: Symbol
-> IO Section
getSection sym =
do
sect <- peekByteOff sym ((20))
return $ unSymbol'Section sect
setSection
:: Symbol
-> Section
-> IO ()
setSection sym sect = pokeByteOff sym ((20)) $ Section sect
getOutputSection
:: Symbol
-> IO Section
getOutputSection sym =
do
sect <- getSection sym
Section.getOutputSection sect
getSize
:: Symbol
-> Bfd
-> IO Int
getSize sym bfd =
do
str <- Bindings.Bfd.Symbol.print sym bfd
let
size = read $ "0x" ++ (head $ tail $ reverse $ words str)
return size
getValue
:: Symbol
-> IO Vma
getValue sym =
do
v <- peekByteOff sym ((8))
return $ unSymbol'Value v
setValue
:: Symbol
-> Vma
-> IO ()
setValue sym vma = pokeByteOff sym ((8)) (Value vma)
getValue'
:: Symbol
-> IO Vma
getValue' sym =
do
base <- getBase sym
val <- getValue sym
return $ base + val
print
:: Symbol
-> Bfd
-> IO String
print sym bfd =
do
(pipeRead, pipeWrite) <- createPipe
setFdOption pipeRead NonBlockingRead False
let
pipeWrite' = fromIntegral pipeWrite
mode <- newCString "w"
fpWrite <- c_fdopen pipeWrite' mode
xvec <- getTarget bfd
f <- getPrintSymbol xvec bfd fpWrite sym
f
_ <- c_fflush fpWrite
(s,_) <- fdRead pipeRead 80
closeFd pipeRead
closeFd pipeWrite
return s