{-# OPTIONS_HADDOCK hide #-}


-- Parser that can be used to read the output of objdump applied to X86 binaries
-- Run objdump on Ubuntu as follows:
--
--
--  UBUNTU:
--      TODO
--
-- MACOS:
--      otool -I -v #DIR#/#BINARY# | grep '^0x' | tr -s ' ' | cut -d ' ' -f1,3
--
-- Example input:
--
-- 0x00000001001ac528 _strcasecmp

module Parser.ParserSymbols where

import Text.Parsec.Token
import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Number
import qualified Data.IntMap as IM
import Generic.Binary


isWhiteSpace :: Char -> Bool
isWhiteSpace Char
'\t' = Bool
True
isWhiteSpace Char
'\f' = Bool
True
isWhiteSpace Char
'\v' = Bool
True
isWhiteSpace Char
' ' = Bool
True
isWhiteSpace Char
_ = Bool
False 

whitespace :: ParsecT [Char] u Identity Char
whitespace = (Char -> Bool) -> ParsecT [Char] u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
(Char -> Bool) -> ParsecT s u m Char
satisfy Char -> Bool
isWhiteSpace ParsecT [Char] u Identity Char
-> [Char] -> ParsecT [Char] u Identity Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> [Char] -> ParsecT s u m a
<?> [Char]
"white space"
whitespaces :: ParsecT [Char] u Identity ()
whitespaces = ParsecT [Char] u Identity Char -> ParsecT [Char] u Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany ParsecT [Char] u Identity Char
forall u. ParsecT [Char] u Identity Char
whitespace ParsecT [Char] u Identity ()
-> [Char] -> ParsecT [Char] u Identity ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> [Char] -> ParsecT s u m a
<?> [Char]
"white spaces"


hexnum_with_0x :: ParsecT [Char] u Identity Key
hexnum_with_0x = do
  [Char] -> ParsecT [Char] u Identity [Char]
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m [Char]
string [Char]
"0x"
  ParsecT [Char] u Identity Key
forall i st. Integral i => CharParser st i
hexnum

symb :: ParsecT [Char] u Identity (Key, Symbol)
symb = do
  Key
a <- ParsecT [Char] u Identity Key
forall u. ParsecT [Char] u Identity Key
hexnum_with_0x
  ParsecT [Char] u Identity ()
forall u. ParsecT [Char] u Identity ()
whitespaces
  [Char]
s <- ParsecT [Char] u Identity Char -> ParsecT [Char] u Identity [Char]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ([Char] -> ParsecT [Char] u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
[Char] -> ParsecT s u m Char
noneOf [Char]
"\n")
  ParsecT [Char] u Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
newline
  (Key, Symbol) -> ParsecT [Char] u Identity (Key, Symbol)
forall (m :: * -> *) a. Monad m => a -> m a
return (Key
a,[Char] -> Symbol
Relocated_Function [Char]
s)
 

symbols :: ParsecT [Char] u Identity (IntMap Symbol)
symbols = do
  [(Key, Symbol)]
ss <- ParsecT [Char] u Identity (Key, Symbol)
-> ParsecT [Char] u Identity [(Key, Symbol)]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT [Char] u Identity (Key, Symbol)
forall u. ParsecT [Char] u Identity (Key, Symbol)
symb
  ParsecT [Char] u Identity ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof
  IntMap Symbol -> ParsecT [Char] u Identity (IntMap Symbol)
forall (m :: * -> *) a. Monad m => a -> m a
return (IntMap Symbol -> ParsecT [Char] u Identity (IntMap Symbol))
-> IntMap Symbol -> ParsecT [Char] u Identity (IntMap Symbol)
forall a b. (a -> b) -> a -> b
$ [(Key, Symbol)] -> IntMap Symbol
forall a. [(Key, a)] -> IntMap a
IM.fromList [(Key, Symbol)]
ss

-- The parse function.
-- Takes as input a filename f and produces a list of instructions
-- to lists of instructions.
parse_symbols  :: String -> IO (Either ParseError (IM.IntMap Symbol))
parse_symbols :: [Char] -> IO (Either ParseError (IntMap Symbol))
parse_symbols [Char]
f = Parser (IntMap Symbol)
-> [Char] -> IO (Either ParseError (IntMap Symbol))
forall a. Parser a -> [Char] -> IO (Either ParseError a)
parseFromFile Parser (IntMap Symbol)
forall u. ParsecT [Char] u Identity (IntMap Symbol)
symbols [Char]
f