{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.Macaw.Memory.ElfLoader.PLTStubs
( PLTStubInfo(..)
, pltStubSymbols
, noPLTStubInfo
, NoRelocationType(..)
) where
import qualified Data.ByteString.Char8 as BSC
import qualified Data.ElfEdit as EE
import Data.Foldable (Foldable(..))
import qualified Data.Map as Map
import Data.Maybe ( fromMaybe, listToMaybe )
import Data.Word ( Word32 )
import GHC.TypeLits ( Nat )
import qualified Data.Macaw.Memory as DMM
import qualified Data.Macaw.Memory.LoadCommon as MML
data PLTStubInfo reloc = PLTStubInfo
{ forall reloc. PLTStubInfo reloc -> Integer
pltFunSize :: Integer
, forall reloc. PLTStubInfo reloc -> Integer
pltStubSize :: Integer
, forall reloc. PLTStubInfo reloc -> Integer
pltGotStubSize :: Integer
}
pltStubSymbols
:: forall reloc w
. ( w ~ EE.RelocationWidth reloc
, DMM.MemWidth w
, EE.IsRelocationType reloc
)
=> PLTStubInfo reloc
-> MML.LoadOptions
-> EE.ElfHeaderInfo w
-> Map.Map (DMM.MemWord w) (EE.VersionedSymbol (EE.ElfWordType w))
pltStubSymbols :: forall reloc (w :: Nat).
(w ~ RelocationWidth reloc, MemWidth w, IsRelocationType reloc) =>
PLTStubInfo reloc
-> LoadOptions
-> ElfHeaderInfo w
-> Map (MemWord w) (VersionedSymbol (ElfWordType w))
pltStubSymbols PLTStubInfo reloc
pltStubInfo LoadOptions
loadOptions ElfHeaderInfo w
ehi =
ElfClass w
-> (ElfWidthConstraints w =>
Map (MemWord w) (VersionedSymbol (ElfWordType w)))
-> Map (MemWord w) (VersionedSymbol (ElfWordType w))
forall (w :: Nat) a.
ElfClass w -> (ElfWidthConstraints w => a) -> a
EE.elfClassInstances ElfClass w
elfClass ((ElfWidthConstraints w =>
Map (MemWord w) (VersionedSymbol (ElfWordType w)))
-> Map (MemWord w) (VersionedSymbol (ElfWordType w)))
-> (ElfWidthConstraints w =>
Map (MemWord w) (VersionedSymbol (ElfWordType w)))
-> Map (MemWord w) (VersionedSymbol (ElfWordType w))
forall a b. (a -> b) -> a -> b
$
[(MemWord w, VersionedSymbol (ElfWordType w))]
-> Map (MemWord w) (VersionedSymbol (ElfWordType w))
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(MemWord w, VersionedSymbol (ElfWordType w))]
-> Map (MemWord w) (VersionedSymbol (ElfWordType w)))
-> [(MemWord w, VersionedSymbol (ElfWordType w))]
-> Map (MemWord w) (VersionedSymbol (ElfWordType w))
forall a b. (a -> b) -> a -> b
$ [(MemWord w, VersionedSymbol (ElfWordType w))]
-> Maybe [(MemWord w, VersionedSymbol (ElfWordType w))]
-> [(MemWord w, VersionedSymbol (ElfWordType w))]
forall a. a -> Maybe a -> a
fromMaybe [] (Maybe [(MemWord w, VersionedSymbol (ElfWordType w))]
-> [(MemWord w, VersionedSymbol (ElfWordType w))])
-> Maybe [(MemWord w, VersionedSymbol (ElfWordType w))]
-> [(MemWord w, VersionedSymbol (ElfWordType w))]
forall a b. (a -> b) -> a -> b
$ do
VirtAddrMap w
vam <- ByteString -> [Phdr w] -> Maybe (VirtAddrMap w)
forall (t :: Type -> Type) (w :: Nat).
(Foldable t, Integral (ElfWordType w)) =>
ByteString -> t (Phdr w) -> Maybe (VirtAddrMap w)
EE.virtAddrMap ByteString
elfBytes [Phdr w]
elfPhdrs
ByteString
dynBytes <- case (Phdr w -> Bool) -> [Phdr w] -> [Phdr w]
forall a. (a -> Bool) -> [a] -> [a]
filter (\Phdr w
p -> Phdr w -> PhdrType
forall (w :: Nat). Phdr w -> PhdrType
EE.phdrSegmentType Phdr w
p PhdrType -> PhdrType -> Bool
forall a. Eq a => a -> a -> Bool
== PhdrType
EE.PT_DYNAMIC) [Phdr w]
elfPhdrs of
[Phdr w
dynPhdr] -> ByteString -> Maybe ByteString
forall a. a -> Maybe a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (FileRange (ElfWordType w) -> ByteString -> ByteString
forall w. Integral w => FileRange w -> ByteString -> ByteString
EE.slice (Phdr w -> FileRange (ElfWordType w)
forall (w :: Nat). Phdr w -> FileRange (ElfWordType w)
EE.phdrFileRange Phdr w
dynPhdr) ByteString
elfBytes)
[Phdr w]
_ -> Maybe ByteString
forall a. Maybe a
Nothing
DynamicSection w
dynSec <- case ElfData
-> ElfClass w
-> ByteString
-> Either DynamicError (DynamicSection w)
forall (w :: Nat).
ElfData
-> ElfClass w
-> ByteString
-> Either DynamicError (DynamicSection w)
EE.dynamicEntries (Elf w -> ElfData
forall (w :: Nat). Elf w -> ElfData
EE.elfData Elf w
elf) ElfClass w
elfClass ByteString
dynBytes of
Left DynamicError
_dynErr -> Maybe (DynamicSection w)
forall a. Maybe a
Nothing
Right DynamicSection w
dynSec -> DynamicSection w -> Maybe (DynamicSection w)
forall a. a -> Maybe a
forall (m :: Type -> Type) a. Monad m => a -> m a
return DynamicSection w
dynSec
VersionDefMap
vdefm <- case DynamicSection w
-> VirtAddrMap w -> Either DynamicError VersionDefMap
forall (w :: Nat).
DynamicSection w
-> VirtAddrMap w -> Either DynamicError VersionDefMap
EE.dynVersionDefMap DynamicSection w
dynSec VirtAddrMap w
vam of
Left DynamicError
_dynErr -> Maybe VersionDefMap
forall a. Maybe a
Nothing
Right VersionDefMap
vm -> VersionDefMap -> Maybe VersionDefMap
forall a. a -> Maybe a
forall (m :: Type -> Type) a. Monad m => a -> m a
return VersionDefMap
vm
VersionDefMap
vreqm <- case DynamicSection w
-> VirtAddrMap w -> Either DynamicError VersionDefMap
forall (w :: Nat).
DynamicSection w
-> VirtAddrMap w -> Either DynamicError VersionDefMap
EE.dynVersionReqMap DynamicSection w
dynSec VirtAddrMap w
vam of
Left DynamicError
_dynErr -> Maybe VersionDefMap
forall a. Maybe a
Nothing
Right VersionDefMap
vm -> VersionDefMap -> Maybe VersionDefMap
forall a. a -> Maybe a
forall (m :: Type -> Type) a. Monad m => a -> m a
return VersionDefMap
vm
let pltAddrs :: [(MemWord w, VersionedSymbol (ElfWordType w))]
pltAddrs = case Integral (ElfWordType w) =>
DynamicSection w
-> VirtAddrMap w
-> VersionDefMap
-> VersionDefMap
-> Maybe [(MemWord w, VersionedSymbol (ElfWordType w))]
DynamicSection w
-> VirtAddrMap w
-> VersionDefMap
-> VersionDefMap
-> Maybe [(MemWord w, VersionedSymbol (ElfWordType w))]
extractPltAddrs DynamicSection w
dynSec VirtAddrMap w
vam VersionDefMap
vdefm VersionDefMap
vreqm of
Maybe [(MemWord w, VersionedSymbol (ElfWordType w))]
Nothing -> []
Just [(MemWord w, VersionedSymbol (ElfWordType w))]
addrs -> [(MemWord w, VersionedSymbol (ElfWordType w))]
addrs
let pltGotAddrs :: [(MemWord w, VersionedSymbol (ElfWordType w))]
pltGotAddrs = case Integral (ElfWordType w) =>
DynamicSection w
-> VirtAddrMap w
-> VersionDefMap
-> VersionDefMap
-> Maybe [(MemWord w, VersionedSymbol (ElfWordType w))]
DynamicSection w
-> VirtAddrMap w
-> VersionDefMap
-> VersionDefMap
-> Maybe [(MemWord w, VersionedSymbol (ElfWordType w))]
extractPltGotAddrs DynamicSection w
dynSec VirtAddrMap w
vam VersionDefMap
vdefm VersionDefMap
vreqm of
Maybe [(MemWord w, VersionedSymbol (ElfWordType w))]
Nothing -> []
Just [(MemWord w, VersionedSymbol (ElfWordType w))]
addrs -> [(MemWord w, VersionedSymbol (ElfWordType w))]
addrs
[(MemWord w, VersionedSymbol (ElfWordType w))]
-> Maybe [(MemWord w, VersionedSymbol (ElfWordType w))]
forall a. a -> Maybe a
forall (m :: Type -> Type) a. Monad m => a -> m a
return ([(MemWord w, VersionedSymbol (ElfWordType w))]
pltAddrs [(MemWord w, VersionedSymbol (ElfWordType w))]
-> [(MemWord w, VersionedSymbol (ElfWordType w))]
-> [(MemWord w, VersionedSymbol (ElfWordType w))]
forall a. [a] -> [a] -> [a]
++ [(MemWord w, VersionedSymbol (ElfWordType w))]
pltGotAddrs)
where
([ElfParseError]
_, Elf w
elf) = ElfHeaderInfo w -> ([ElfParseError], Elf w)
forall (w :: Nat). ElfHeaderInfo w -> ([ElfParseError], Elf w)
EE.getElf ElfHeaderInfo w
ehi
elfPhdrs :: [Phdr w]
elfPhdrs = ElfHeaderInfo w -> [Phdr w]
forall (w :: Nat). ElfHeaderInfo w -> [Phdr w]
EE.headerPhdrs ElfHeaderInfo w
ehi
elfBytes :: ByteString
elfBytes = ElfHeaderInfo w -> ByteString
forall (w :: Nat). ElfHeaderInfo w -> ByteString
EE.headerFileContents ElfHeaderInfo w
ehi
elfClass :: ElfClass w
elfClass = Elf w -> ElfClass w
forall (w :: Nat). Elf w -> ElfClass w
EE.elfClass Elf w
elf
pltStubAddress :: forall relOrRela
. EE.DynamicSection w
-> EE.VirtAddrMap w
-> EE.VersionDefMap
-> EE.VersionReqMap
-> (relOrRela reloc -> Word32)
-> [EE.VersionedSymbol (EE.ElfWordType w)]
-> relOrRela reloc
-> [EE.VersionedSymbol (EE.ElfWordType w)]
pltStubAddress :: forall (relOrRela :: Type -> Type).
DynamicSection w
-> VirtAddrMap w
-> VersionDefMap
-> VersionDefMap
-> (relOrRela reloc -> Word32)
-> [VersionedSymbol (ElfWordType w)]
-> relOrRela reloc
-> [VersionedSymbol (ElfWordType w)]
pltStubAddress DynamicSection w
dynSec VirtAddrMap w
vam VersionDefMap
vdefm VersionDefMap
vreqm relOrRela reloc -> Word32
getRelSymIdx [VersionedSymbol (ElfWordType w)]
accum relOrRela reloc
rel
| Right VersionedSymbol (ElfWordType w)
entry <- DynamicSection w
-> VirtAddrMap w
-> VersionDefMap
-> VersionDefMap
-> Word32
-> Either DynamicError (VersionedSymbol (ElfWordType w))
forall (w :: Nat).
DynamicSection w
-> VirtAddrMap w
-> VersionDefMap
-> VersionDefMap
-> Word32
-> Either DynamicError (VersionedSymbol (ElfWordType w))
EE.dynSymEntry DynamicSection w
dynSec VirtAddrMap w
vam VersionDefMap
vdefm VersionDefMap
vreqm (relOrRela reloc -> Word32
getRelSymIdx relOrRela reloc
rel) =
VersionedSymbol (ElfWordType w)
entry VersionedSymbol (ElfWordType w)
-> [VersionedSymbol (ElfWordType w)]
-> [VersionedSymbol (ElfWordType w)]
forall a. a -> [a] -> [a]
: [VersionedSymbol (ElfWordType w)]
accum
| Bool
otherwise = [VersionedSymbol (ElfWordType w)]
accum
buildAssocList :: forall versym
. [(Integer, versym)]
-> Integer
-> Integer
-> [(DMM.MemWord w, versym)]
buildAssocList :: forall versym.
[(Integer, versym)] -> Integer -> Integer -> [(MemWord w, versym)]
buildAssocList [(Integer, versym)]
nameRelaMap Integer
baseAddr Integer
stubSize =
let loadOffset :: Integer
loadOffset = Word64 -> Integer
forall a. Integral a => a -> Integer
toInteger (Word64 -> Integer) -> Word64 -> Integer
forall a b. (a -> b) -> a -> b
$ Word64 -> Maybe Word64 -> Word64
forall a. a -> Maybe a -> a
fromMaybe Word64
0 (LoadOptions -> Maybe Word64
MML.loadOffset LoadOptions
loadOptions) in
[ (Word64 -> MemWord w
forall (w :: Nat). MemWidth w => Word64 -> MemWord w
DMM.memWord (Integer -> Word64
forall a. Num a => Integer -> a
fromInteger Integer
addr), versym
versym)
| (Integer
idx, versym
versym) <- [(Integer, versym)]
nameRelaMap
, let addr :: Integer
addr = Integer
loadOffset Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
baseAddr Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
idx Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
stubSize
]
extractPltAddrs :: Integral (EE.ElfWordType w)
=> EE.DynamicSection w
-> EE.VirtAddrMap w
-> EE.VersionDefMap
-> EE.VersionReqMap
-> Maybe [(DMM.MemWord w, EE.VersionedSymbol (EE.ElfWordType w))]
extractPltAddrs :: Integral (ElfWordType w) =>
DynamicSection w
-> VirtAddrMap w
-> VersionDefMap
-> VersionDefMap
-> Maybe [(MemWord w, VersionedSymbol (ElfWordType w))]
extractPltAddrs DynamicSection w
dynSec VirtAddrMap w
vam VersionDefMap
vdefm VersionDefMap
vreqm = do
SomeRel [relOrRela reloc]
rels relOrRela reloc -> Word32
getRelSymIdx <- case forall tp.
IsRelocationType tp =>
DynamicSection (RelocationWidth tp)
-> VirtAddrMap (RelocationWidth tp)
-> Either DynamicError (PLTEntries tp)
EE.dynPLTRel @reloc DynamicSection w
DynamicSection (RelocationWidth reloc)
dynSec VirtAddrMap w
VirtAddrMap (RelocationWidth reloc)
vam of
Right (EE.PLTRela [RelaEntry reloc]
relas) -> SomeRel reloc -> Maybe (SomeRel reloc)
forall a. a -> Maybe a
forall (m :: Type -> Type) a. Monad m => a -> m a
return ([RelaEntry reloc] -> (RelaEntry reloc -> Word32) -> SomeRel reloc
forall (relOrRela :: Type -> Type) reloc.
[relOrRela reloc] -> (relOrRela reloc -> Word32) -> SomeRel reloc
SomeRel [RelaEntry reloc]
relas RelaEntry reloc -> Word32
forall tp. RelaEntry tp -> Word32
EE.relaSym)
Right (EE.PLTRel [RelEntry reloc]
rels) -> SomeRel reloc -> Maybe (SomeRel reloc)
forall a. a -> Maybe a
forall (m :: Type -> Type) a. Monad m => a -> m a
return ([RelEntry reloc] -> (RelEntry reloc -> Word32) -> SomeRel reloc
forall (relOrRela :: Type -> Type) reloc.
[relOrRela reloc] -> (relOrRela reloc -> Word32) -> SomeRel reloc
SomeRel [RelEntry reloc]
rels RelEntry reloc -> Word32
forall tp. RelEntry tp -> Word32
EE.relSym)
Either DynamicError (PLTEntries reloc)
_ -> Maybe (SomeRel reloc)
forall a. Maybe a
Nothing
let revNameRelaMap :: [VersionedSymbol (ElfWordType w)]
revNameRelaMap = ([VersionedSymbol (ElfWordType w)]
-> relOrRela reloc -> [VersionedSymbol (ElfWordType w)])
-> [VersionedSymbol (ElfWordType w)]
-> [relOrRela reloc]
-> [VersionedSymbol (ElfWordType w)]
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: Type -> Type) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (DynamicSection w
-> VirtAddrMap w
-> VersionDefMap
-> VersionDefMap
-> (relOrRela reloc -> Word32)
-> [VersionedSymbol (ElfWordType w)]
-> relOrRela reloc
-> [VersionedSymbol (ElfWordType w)]
forall (relOrRela :: Type -> Type).
DynamicSection w
-> VirtAddrMap w
-> VersionDefMap
-> VersionDefMap
-> (relOrRela reloc -> Word32)
-> [VersionedSymbol (ElfWordType w)]
-> relOrRela reloc
-> [VersionedSymbol (ElfWordType w)]
pltStubAddress DynamicSection w
dynSec VirtAddrMap w
vam VersionDefMap
vdefm VersionDefMap
vreqm relOrRela reloc -> Word32
getRelSymIdx) [] [relOrRela reloc]
rels
let nameRelaMap :: [(Integer, VersionedSymbol (ElfWordType w))]
nameRelaMap = [Integer]
-> [VersionedSymbol (ElfWordType w)]
-> [(Integer, VersionedSymbol (ElfWordType w))]
forall a b. [a] -> [b] -> [(a, b)]
zip [Integer
0..] ([VersionedSymbol (ElfWordType w)]
-> [VersionedSymbol (ElfWordType w)]
forall a. [a] -> [a]
reverse [VersionedSymbol (ElfWordType w)]
revNameRelaMap)
ElfSection (ElfWordType w)
pltSec <- [ElfSection (ElfWordType w)] -> Maybe (ElfSection (ElfWordType w))
forall a. [a] -> Maybe a
listToMaybe (ByteString -> Elf w -> [ElfSection (ElfWordType w)]
forall (w :: Nat).
ByteString -> Elf w -> [ElfSection (ElfWordType w)]
EE.findSectionByName (String -> ByteString
BSC.pack String
".plt") Elf w
elf)
let pltBase :: ElfWordType w
pltBase = ElfSection (ElfWordType w) -> ElfWordType w
forall w. ElfSection w -> w
EE.elfSectionAddr ElfSection (ElfWordType w)
pltSec
let pltFunSz :: Integer
pltFunSz = PLTStubInfo reloc -> Integer
forall reloc. PLTStubInfo reloc -> Integer
pltFunSize PLTStubInfo reloc
pltStubInfo
let pltStubSz :: Integer
pltStubSz = PLTStubInfo reloc -> Integer
forall reloc. PLTStubInfo reloc -> Integer
pltStubSize PLTStubInfo reloc
pltStubInfo
[(MemWord w, VersionedSymbol (ElfWordType w))]
-> Maybe [(MemWord w, VersionedSymbol (ElfWordType w))]
forall a. a -> Maybe a
forall (m :: Type -> Type) a. Monad m => a -> m a
return ([(MemWord w, VersionedSymbol (ElfWordType w))]
-> Maybe [(MemWord w, VersionedSymbol (ElfWordType w))])
-> [(MemWord w, VersionedSymbol (ElfWordType w))]
-> Maybe [(MemWord w, VersionedSymbol (ElfWordType w))]
forall a b. (a -> b) -> a -> b
$ [(Integer, VersionedSymbol (ElfWordType w))]
-> Integer
-> Integer
-> [(MemWord w, VersionedSymbol (ElfWordType w))]
forall versym.
[(Integer, versym)] -> Integer -> Integer -> [(MemWord w, versym)]
buildAssocList [(Integer, VersionedSymbol (ElfWordType w))]
nameRelaMap (Integer
pltFunSz Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ ElfWordType w -> Integer
forall a. Integral a => a -> Integer
toInteger ElfWordType w
pltBase) Integer
pltStubSz
extractPltGotAddrs :: Integral (EE.ElfWordType w)
=> EE.DynamicSection w
-> EE.VirtAddrMap w
-> EE.VersionDefMap
-> EE.VersionReqMap
-> Maybe [(DMM.MemWord w, EE.VersionedSymbol (EE.ElfWordType w))]
extractPltGotAddrs :: Integral (ElfWordType w) =>
DynamicSection w
-> VirtAddrMap w
-> VersionDefMap
-> VersionDefMap
-> Maybe [(MemWord w, VersionedSymbol (ElfWordType w))]
extractPltGotAddrs DynamicSection w
dynSec VirtAddrMap w
vam VersionDefMap
vdefm VersionDefMap
vreqm = do
[RelaEntry reloc]
relsGot <- case forall tp.
IsRelocationType tp =>
DynamicSection (RelocationWidth tp)
-> VirtAddrMap (RelocationWidth tp)
-> Either DynamicError [RelaEntry tp]
EE.dynRelaEntries @reloc DynamicSection w
DynamicSection (RelocationWidth reloc)
dynSec VirtAddrMap w
VirtAddrMap (RelocationWidth reloc)
vam of
Right [RelaEntry reloc]
relas -> [RelaEntry reloc] -> Maybe [RelaEntry reloc]
forall a. a -> Maybe a
forall (m :: Type -> Type) a. Monad m => a -> m a
return [RelaEntry reloc]
relas
Left DynamicError
_ -> Maybe [RelaEntry reloc]
forall a. Maybe a
Nothing
let revNameRelaMapGot :: [VersionedSymbol (ElfWordType w)]
revNameRelaMapGot = ([VersionedSymbol (ElfWordType w)]
-> RelaEntry reloc -> [VersionedSymbol (ElfWordType w)])
-> [VersionedSymbol (ElfWordType w)]
-> [RelaEntry reloc]
-> [VersionedSymbol (ElfWordType w)]
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: Type -> Type) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (DynamicSection w
-> VirtAddrMap w
-> VersionDefMap
-> VersionDefMap
-> (RelaEntry reloc -> Word32)
-> [VersionedSymbol (ElfWordType w)]
-> RelaEntry reloc
-> [VersionedSymbol (ElfWordType w)]
forall (relOrRela :: Type -> Type).
DynamicSection w
-> VirtAddrMap w
-> VersionDefMap
-> VersionDefMap
-> (relOrRela reloc -> Word32)
-> [VersionedSymbol (ElfWordType w)]
-> relOrRela reloc
-> [VersionedSymbol (ElfWordType w)]
pltStubAddress DynamicSection w
dynSec VirtAddrMap w
vam VersionDefMap
vdefm VersionDefMap
vreqm RelaEntry reloc -> Word32
forall tp. RelaEntry tp -> Word32
EE.relaSym) [] [RelaEntry reloc]
relsGot
let nameRelaMapGot :: [(Integer, VersionedSymbol (ElfWordType w))]
nameRelaMapGot = [Integer]
-> [VersionedSymbol (ElfWordType w)]
-> [(Integer, VersionedSymbol (ElfWordType w))]
forall a b. [a] -> [b] -> [(a, b)]
zip [Integer
0..] ([VersionedSymbol (ElfWordType w)]
-> [VersionedSymbol (ElfWordType w)]
forall a. [a] -> [a]
reverse [VersionedSymbol (ElfWordType w)]
revNameRelaMapGot)
ElfSection (ElfWordType w)
pltGotSec <- [ElfSection (ElfWordType w)] -> Maybe (ElfSection (ElfWordType w))
forall a. [a] -> Maybe a
listToMaybe (ByteString -> Elf w -> [ElfSection (ElfWordType w)]
forall (w :: Nat).
ByteString -> Elf w -> [ElfSection (ElfWordType w)]
EE.findSectionByName (String -> ByteString
BSC.pack String
".plt.got") Elf w
elf)
let pltGotBase :: ElfWordType w
pltGotBase = ElfSection (ElfWordType w) -> ElfWordType w
forall w. ElfSection w -> w
EE.elfSectionAddr ElfSection (ElfWordType w)
pltGotSec
let pltGotStubSz :: Integer
pltGotStubSz = PLTStubInfo reloc -> Integer
forall reloc. PLTStubInfo reloc -> Integer
pltGotStubSize PLTStubInfo reloc
pltStubInfo
[(MemWord w, VersionedSymbol (ElfWordType w))]
-> Maybe [(MemWord w, VersionedSymbol (ElfWordType w))]
forall a. a -> Maybe a
forall (m :: Type -> Type) a. Monad m => a -> m a
return ([(MemWord w, VersionedSymbol (ElfWordType w))]
-> Maybe [(MemWord w, VersionedSymbol (ElfWordType w))])
-> [(MemWord w, VersionedSymbol (ElfWordType w))]
-> Maybe [(MemWord w, VersionedSymbol (ElfWordType w))]
forall a b. (a -> b) -> a -> b
$ [(Integer, VersionedSymbol (ElfWordType w))]
-> Integer
-> Integer
-> [(MemWord w, VersionedSymbol (ElfWordType w))]
forall versym.
[(Integer, versym)] -> Integer -> Integer -> [(MemWord w, versym)]
buildAssocList [(Integer, VersionedSymbol (ElfWordType w))]
nameRelaMapGot (ElfWordType w -> Integer
forall a. Integral a => a -> Integer
toInteger ElfWordType w
pltGotBase) Integer
pltGotStubSz
data SomeRel reloc where
SomeRel :: [relOrRela reloc] -> (relOrRela reloc -> Word32) -> SomeRel reloc
data NoRelocationType (w :: Nat) = NoRelocationType
deriving Int -> NoRelocationType w -> ShowS
[NoRelocationType w] -> ShowS
NoRelocationType w -> String
(Int -> NoRelocationType w -> ShowS)
-> (NoRelocationType w -> String)
-> ([NoRelocationType w] -> ShowS)
-> Show (NoRelocationType w)
forall (w :: Nat). Int -> NoRelocationType w -> ShowS
forall (w :: Nat). [NoRelocationType w] -> ShowS
forall (w :: Nat). NoRelocationType w -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall (w :: Nat). Int -> NoRelocationType w -> ShowS
showsPrec :: Int -> NoRelocationType w -> ShowS
$cshow :: forall (w :: Nat). NoRelocationType w -> String
show :: NoRelocationType w -> String
$cshowList :: forall (w :: Nat). [NoRelocationType w] -> ShowS
showList :: [NoRelocationType w] -> ShowS
Show
noRelocationTypeError :: a
noRelocationTypeError :: forall a. a
noRelocationTypeError = String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$
String
"Attempting to use dynamic relocations on an architecture " String -> ShowS
forall a. [a] -> [a] -> [a]
++
String
"that has not yet been configured to use them."
instance Show (EE.ElfWordType w) => EE.IsRelocationType (NoRelocationType w) where
type RelocationWidth (NoRelocationType w) = w
relaWidth :: NoRelocationType w
-> ElfClass (RelocationWidth (NoRelocationType w))
relaWidth = NoRelocationType w -> ElfClass w
NoRelocationType w
-> ElfClass (RelocationWidth (NoRelocationType w))
forall a. a
noRelocationTypeError
toRelocType :: Word32 -> NoRelocationType w
toRelocType = Word32 -> NoRelocationType w
forall a. a
noRelocationTypeError
isRelative :: NoRelocationType w -> Bool
isRelative = NoRelocationType w -> Bool
forall a. a
noRelocationTypeError
relocTargetBits :: NoRelocationType w -> Int
relocTargetBits = NoRelocationType w -> Int
forall a. a
noRelocationTypeError
noPLTStubInfo :: String -> PLTStubInfo (NoRelocationType w)
noPLTStubInfo :: forall (w :: Nat). String -> PLTStubInfo (NoRelocationType w)
noPLTStubInfo String
arch = String -> PLTStubInfo (NoRelocationType w)
forall a. HasCallStack => String -> a
error (String -> PLTStubInfo (NoRelocationType w))
-> String -> PLTStubInfo (NoRelocationType w)
forall a b. (a -> b) -> a -> b
$
String
"The " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
arch String -> ShowS
forall a. [a] -> [a] -> [a]
++
String
" architecture has not yet been configured to support PLT stubs."