module Binary.Read where
import Binary.Generic
import Binary.Elf
import Binary.Macho
import qualified Data.ByteString as BS
import System.Directory (doesFileExist)
read_binary :: String -> String -> IO (Maybe Binary)
read_binary :: String -> String -> IO (Maybe Binary)
read_binary String
dirname String
name = do
let filename :: String
filename = String
dirname String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
name
Bool
exists <- String -> IO Bool
doesFileExist String
filename
if Bool
exists then do
ByteString
content <- String -> IO ByteString
BS.readFile String
filename
if (ByteString -> [Word8]
BS.unpack (ByteString -> [Word8]) -> ByteString -> [Word8]
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
BS.take Int
4 ByteString
content) [Word8] -> [Word8] -> Bool
forall a. Eq a => a -> a -> Bool
== [Word8
0x7f, Word8
0x45, Word8
0x4C, Word8
0x46] then do
let elf :: Elf
elf = ByteString -> Elf
elf_read_file ByteString
content
Maybe Binary -> IO (Maybe Binary)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Binary -> IO (Maybe Binary))
-> Maybe Binary -> IO (Maybe Binary)
forall a b. (a -> b) -> a -> b
$ Binary -> Maybe Binary
forall a. a -> Maybe a
Just (Binary -> Maybe Binary) -> Binary -> Maybe Binary
forall a b. (a -> b) -> a -> b
$ NamedElf -> Binary
forall b. BinaryClass b => b -> Binary
Binary (NamedElf -> Binary) -> NamedElf -> Binary
forall a b. (a -> b) -> a -> b
$ Elf
-> String
-> String
-> SectionsInfo
-> SymbolTable
-> Set Relocation
-> NamedElf
NamedElf Elf
elf String
dirname String
name (Elf -> SectionsInfo
elf_get_sections_info Elf
elf) (Elf -> SymbolTable
elf_get_symbol_table Elf
elf) (Elf -> Set Relocation
elf_get_relocs Elf
elf)
else
Maybe Binary -> IO (Maybe Binary)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Binary
forall a. Maybe a
Nothing
else do
Bool
exists1 <- String -> IO Bool
doesFileExist (String
filename String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
".dump")
Bool
exists2 <- String -> IO Bool
doesFileExist (String
filename String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
".data")
Bool
exists3 <- String -> IO Bool
doesFileExist (String
filename String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
".sections")
Bool
exists4 <- String -> IO Bool
doesFileExist (String
filename String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
".symbols")
Bool
exists5 <- String -> IO Bool
doesFileExist (String
filename String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
".entry")
if [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and [Bool
exists1,Bool
exists2,Bool
exists3,Bool
exists4,Bool
exists5] then do
Macho
macho <- String -> String -> IO Macho
macho_read_file String
dirname String
name
Maybe Binary -> IO (Maybe Binary)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Binary -> IO (Maybe Binary))
-> Maybe Binary -> IO (Maybe Binary)
forall a b. (a -> b) -> a -> b
$ Binary -> Maybe Binary
forall a. a -> Maybe a
Just (Binary -> Maybe Binary) -> Binary -> Maybe Binary
forall a b. (a -> b) -> a -> b
$ Macho -> Binary
forall b. BinaryClass b => b -> Binary
Binary (Macho -> Binary) -> Macho -> Binary
forall a b. (a -> b) -> a -> b
$ Macho
macho
else
Maybe Binary -> IO (Maybe Binary)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Binary
forall a. Maybe a
Nothing