mirror of
https://github.com/GaloisInc/macaw.git
synced 2024-11-24 00:42:28 +03:00
Update for android compatibility
This commit is contained in:
parent
bb66fd64ec
commit
a99d999fd0
@ -34,7 +34,7 @@ library
|
|||||||
binary-symbols >= 0.1.3,
|
binary-symbols >= 0.1.3,
|
||||||
bytestring,
|
bytestring,
|
||||||
containers >= 0.5.8.1,
|
containers >= 0.5.8.1,
|
||||||
elf-edit >= 0.34.1,
|
elf-edit >= 0.35,
|
||||||
galois-dwarf,
|
galois-dwarf,
|
||||||
IntervalMap >= 0.5,
|
IntervalMap >= 0.5,
|
||||||
lens >= 4.7,
|
lens >= 4.7,
|
||||||
|
@ -53,6 +53,7 @@ module Data.Macaw.Memory
|
|||||||
, MemWidth(..)
|
, MemWidth(..)
|
||||||
, MemWord
|
, MemWord
|
||||||
, memWord
|
, memWord
|
||||||
|
, memWordValue
|
||||||
, memWordToUnsigned
|
, memWordToUnsigned
|
||||||
, memWordToSigned
|
, memWordToSigned
|
||||||
, addrRead
|
, addrRead
|
||||||
|
@ -67,6 +67,7 @@ import Data.ElfEdit
|
|||||||
, ElfSymbolTableEntry
|
, ElfSymbolTableEntry
|
||||||
)
|
)
|
||||||
import qualified Data.ElfEdit as Elf
|
import qualified Data.ElfEdit as Elf
|
||||||
|
import Data.Foldable
|
||||||
import Data.IntervalMap.Strict (Interval(..), IntervalMap)
|
import Data.IntervalMap.Strict (Interval(..), IntervalMap)
|
||||||
import qualified Data.IntervalMap.Strict as IMap
|
import qualified Data.IntervalMap.Strict as IMap
|
||||||
import Data.Map.Strict (Map)
|
import Data.Map.Strict (Map)
|
||||||
@ -173,13 +174,6 @@ data MemLoadWarning
|
|||||||
| MultipleSectionsWithName !SectionName
|
| MultipleSectionsWithName !SectionName
|
||||||
| MultipleDynamicSegments
|
| MultipleDynamicSegments
|
||||||
| OverlappingLoadableSegments
|
| OverlappingLoadableSegments
|
||||||
| RelocationParseFailure !String
|
|
||||||
| DynamicRelaAndRelPresent
|
|
||||||
-- ^ Issued if the dynamic section contains table for DT_REL and
|
|
||||||
-- DT_RELA.
|
|
||||||
| SectionRelaAndRelPresent !BS.ByteString
|
|
||||||
-- ^ @SectionRelaAndRelPresent nm@ is issued if we encounter
|
|
||||||
-- both section ".rela$nm" and ".rel$nm".
|
|
||||||
| UnsupportedSection !SectionName
|
| UnsupportedSection !SectionName
|
||||||
| UnknownDefinedSymbolBinding !SymbolName Elf.ElfSymbolBinding
|
| UnknownDefinedSymbolBinding !SymbolName Elf.ElfSymbolBinding
|
||||||
| UnknownDefinedSymbolType !SymbolName Elf.ElfSymbolType
|
| UnknownDefinedSymbolType !SymbolName Elf.ElfSymbolType
|
||||||
@ -189,6 +183,12 @@ data MemLoadWarning
|
|||||||
| ExpectedSectionSymbolLocal
|
| ExpectedSectionSymbolLocal
|
||||||
| InvalidSectionSymbolIndex !Elf.ElfSectionIndex
|
| InvalidSectionSymbolIndex !Elf.ElfSectionIndex
|
||||||
| UnsupportedProcessorSpecificSymbolIndex !SymbolName !ElfSectionIndex
|
| UnsupportedProcessorSpecificSymbolIndex !SymbolName !ElfSectionIndex
|
||||||
|
|
||||||
|
| MultipleRelocationTables
|
||||||
|
-- ^ Issued if the file contains multiple relocation tables.
|
||||||
|
| RelocationParseFailure !String
|
||||||
|
| MultipleRelocationsAtAddr !Word64
|
||||||
|
-- ^ Multiple relocations at the given offset
|
||||||
| IgnoreRelocation !Integer !String !RelocationError
|
| IgnoreRelocation !Integer !String !RelocationError
|
||||||
-- ^ @IgnoreRelocation idx tp err@ warns we ignored the location at index @idx@ due to @err@.
|
-- ^ @IgnoreRelocation idx tp err@ warns we ignored the location at index @idx@ due to @err@.
|
||||||
--
|
--
|
||||||
@ -208,14 +208,6 @@ instance Show MemLoadWarning where
|
|||||||
"Found multiple dynamic segments; choosing first one."
|
"Found multiple dynamic segments; choosing first one."
|
||||||
show OverlappingLoadableSegments =
|
show OverlappingLoadableSegments =
|
||||||
"File segments containing overlapping addresses; skipping relocations."
|
"File segments containing overlapping addresses; skipping relocations."
|
||||||
show (RelocationParseFailure msg) =
|
|
||||||
"Error parsing relocations: " ++ msg
|
|
||||||
show DynamicRelaAndRelPresent =
|
|
||||||
"PT_DYNAMIC segment contains contain offsets for both DT_REL and DT_RELA relocation tables; "
|
|
||||||
++ " Using only DT_RELA relocations."
|
|
||||||
show (SectionRelaAndRelPresent (BSC.unpack -> nm)) =
|
|
||||||
"File contains both .rela" ++ nm ++ " and .rel" ++ nm
|
|
||||||
++ " sections; Using only .rela" ++ nm ++ " sections."
|
|
||||||
show (UnsupportedSection nm) =
|
show (UnsupportedSection nm) =
|
||||||
"Do not support section " ++ BSC.unpack nm
|
"Do not support section " ++ BSC.unpack nm
|
||||||
show (UnknownDefinedSymbolBinding nm bnd) =
|
show (UnknownDefinedSymbolBinding nm bnd) =
|
||||||
@ -238,8 +230,15 @@ instance Show MemLoadWarning where
|
|||||||
"Expected section symbol to have a valid index instead of " ++ show idx ++ "."
|
"Expected section symbol to have a valid index instead of " ++ show idx ++ "."
|
||||||
show (UnsupportedProcessorSpecificSymbolIndex nm idx) =
|
show (UnsupportedProcessorSpecificSymbolIndex nm idx) =
|
||||||
"Could not resolve symbol index " ++ show idx ++ " for symbol " ++ BSC.unpack nm ++ "."
|
"Could not resolve symbol index " ++ show idx ++ " for symbol " ++ BSC.unpack nm ++ "."
|
||||||
|
show MultipleRelocationTables =
|
||||||
|
"File contains multiple relocation tables; these are being merged."
|
||||||
|
show (RelocationParseFailure msg) =
|
||||||
|
"Error parsing relocations: " ++ msg
|
||||||
show (IgnoreRelocation idx typeName err) =
|
show (IgnoreRelocation idx typeName err) =
|
||||||
"Ignoring relocation " ++ show idx ++ " with type " ++ typeName ++ ": " ++ show err
|
"Ignoring relocation " ++ show idx ++ " with type " ++ typeName ++ ": " ++ show err
|
||||||
|
show (MultipleRelocationsAtAddr addr) =
|
||||||
|
"Multiple relocations modify " ++ showHex addr "."
|
||||||
|
|
||||||
|
|
||||||
data MemLoaderState w = MLS { _mlsMemory :: !(Memory w)
|
data MemLoaderState w = MLS { _mlsMemory :: !(Memory w)
|
||||||
, mlsEndianness :: !Endianness
|
, mlsEndianness :: !Endianness
|
||||||
@ -723,7 +722,7 @@ relaTargetARM64 :: Endianness
|
|||||||
-> Maybe SegmentIndex
|
-> Maybe SegmentIndex
|
||||||
-- ^ Index of segment for dynamic relocations
|
-- ^ Index of segment for dynamic relocations
|
||||||
-> SymbolTable -- ^ Symbol table
|
-> SymbolTable -- ^ Symbol table
|
||||||
-> Elf.RelEntry Elf.ARM64_RelocationType -- ^ Relocaiton entry
|
-> Elf.RelEntry Elf.AArch64_RelocationType -- ^ Relocaiton entry
|
||||||
-> MemWord 64
|
-> MemWord 64
|
||||||
-- ^ Addend of symbol
|
-- ^ Addend of symbol
|
||||||
-> RelFlag
|
-> RelFlag
|
||||||
@ -867,29 +866,65 @@ relocFromRel end symtab resolver idx r =
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
relocMapFromRelAndRela :: (Elf.IsRelocationType tp, w ~ Elf.RelocationWidth tp)
|
|
||||||
=> Elf.ElfData
|
-- | Maps address that relocations apply to to the relocation information.
|
||||||
-- ^ Endianness
|
type RelocMap w = Map (MemWord w) (RelocEntry (MemLoader w) w)
|
||||||
-> RelocationResolver tp
|
|
||||||
-> SymbolTable
|
-- | Add a relocation entry to the map.
|
||||||
-- ^ Map from symbol indices to associated symbol
|
addRelocEntry :: RelocMap w
|
||||||
-> Maybe L.ByteString
|
-> (MemWord w, RelocEntry (MemLoader w) w)
|
||||||
-- ^ Buffer containing relocation entries in Rel format
|
-> MemLoader w (RelocMap w)
|
||||||
-> Maybe L.ByteString
|
addRelocEntry m (addr, e) =
|
||||||
-- ^ Buffer containing relocation entries in Rela format
|
case Map.insertLookupWithKey (\_k _new old -> old) addr e m of
|
||||||
-> MemLoader w (Map (MemWord w) (RelocEntry (MemLoader w) w))
|
(Nothing, m') -> pure m'
|
||||||
relocMapFromRelAndRela _dta _resolver _symtab Nothing Nothing = do
|
(Just _, _) -> do
|
||||||
pure Map.empty
|
addWarning $ MultipleRelocationsAtAddr (memWordValue addr)
|
||||||
relocMapFromRelAndRela dta resolver symtab _ (Just relaBuffer) = do
|
pure m
|
||||||
|
|
||||||
|
addRelocEntries :: RelocMap w
|
||||||
|
-> [(MemWord w, RelocEntry (MemLoader w) w)]
|
||||||
|
-> MemLoader w (RelocMap w)
|
||||||
|
addRelocEntries = foldlM addRelocEntry
|
||||||
|
|
||||||
|
|
||||||
|
-- | Add rela relocation entries to map.
|
||||||
|
addRelaEntries :: (Elf.IsRelocationType tp, w ~ Elf.RelocationWidth tp)
|
||||||
|
=> RelocMap w
|
||||||
|
-> Elf.ElfData
|
||||||
|
-- ^ Endianness
|
||||||
|
-> RelocationResolver tp
|
||||||
|
-> SymbolTable
|
||||||
|
-- ^ Map from symbol indices to associated symbol
|
||||||
|
-> Maybe L.ByteString
|
||||||
|
-- ^ Buffer containing relocation entries in Rela format
|
||||||
|
-> MemLoader w (RelocMap w)
|
||||||
|
addRelaEntries m _ _ _ Nothing =
|
||||||
|
pure m
|
||||||
|
addRelaEntries m dta resolver symtab (Just relaBuffer) = do
|
||||||
w <- uses mlsMemory memAddrWidth
|
w <- uses mlsMemory memAddrWidth
|
||||||
reprConstraints w $ do
|
reprConstraints w $ do
|
||||||
case Elf.elfRelaEntries dta relaBuffer of
|
case Elf.elfRelaEntries dta relaBuffer of
|
||||||
Left msg -> do
|
Left msg -> do
|
||||||
addWarning (RelocationParseFailure msg)
|
addWarning (RelocationParseFailure msg)
|
||||||
pure Map.empty
|
pure m
|
||||||
Right entries -> do
|
Right entries -> do
|
||||||
pure $ Map.fromList $ zipWith (relocFromRela symtab resolver) [0..] entries
|
addRelocEntries m $
|
||||||
relocMapFromRelAndRela dta resolver symtab (Just relBuffer) Nothing = do
|
zipWith (relocFromRela symtab resolver) [0..] entries
|
||||||
|
|
||||||
|
-- | Add rel relocation entries to map.
|
||||||
|
addRelEntries :: (Elf.IsRelocationType tp, w ~ Elf.RelocationWidth tp)
|
||||||
|
=> RelocMap w
|
||||||
|
-> Elf.ElfData
|
||||||
|
-- ^ Endianness
|
||||||
|
-> RelocationResolver tp
|
||||||
|
-> SymbolTable
|
||||||
|
-- ^ Map from symbol indices to associated symbol
|
||||||
|
-> Maybe L.ByteString
|
||||||
|
-- ^ Buffer containing relocation entries in Rel format
|
||||||
|
-> MemLoader w (RelocMap w)
|
||||||
|
addRelEntries m _ _ _ Nothing =
|
||||||
|
pure m
|
||||||
|
addRelEntries m dta resolver symtab (Just relBuffer) = do
|
||||||
w <- uses mlsMemory memAddrWidth
|
w <- uses mlsMemory memAddrWidth
|
||||||
reprConstraints w $ do
|
reprConstraints w $ do
|
||||||
case Elf.elfRelEntries dta relBuffer of
|
case Elf.elfRelEntries dta relBuffer of
|
||||||
@ -897,7 +932,8 @@ relocMapFromRelAndRela dta resolver symtab (Just relBuffer) Nothing = do
|
|||||||
addWarning (RelocationParseFailure msg)
|
addWarning (RelocationParseFailure msg)
|
||||||
pure Map.empty
|
pure Map.empty
|
||||||
Right entries -> do
|
Right entries -> do
|
||||||
pure $ Map.fromList $ zipWith (relocFromRel (toEndianness dta) symtab resolver) [0..] entries
|
addRelocEntries m $
|
||||||
|
zipWith (relocFromRel (toEndianness dta) symtab resolver) [0..] entries
|
||||||
|
|
||||||
-- | This checks a computation that returns a dynamic error or succeeds.
|
-- | This checks a computation that returns a dynamic error or succeeds.
|
||||||
runDynamic :: Either Elf.DynamicError a -> MemLoader w a
|
runDynamic :: Either Elf.DynamicError a -> MemLoader w a
|
||||||
@ -927,27 +963,31 @@ dynamicRelocationMap hdr ph contents =
|
|||||||
-- Find th dynamic section from the contents.
|
-- Find th dynamic section from the contents.
|
||||||
dynSection <- runDynamic $
|
dynSection <- runDynamic $
|
||||||
Elf.dynamicEntries (Elf.headerData hdr) (Elf.headerClass hdr) virtMap dynContents
|
Elf.dynamicEntries (Elf.headerData hdr) (Elf.headerClass hdr) virtMap dynContents
|
||||||
|
let dta = Elf.headerData hdr
|
||||||
|
SomeRelocationResolver resolver <- getRelocationResolver hdr
|
||||||
let symtab = dynamicSymbolTable dynSection
|
let symtab = dynamicSymbolTable dynSection
|
||||||
|
-- Parse relocations
|
||||||
|
|
||||||
mRelBuffer <- runDynamic $ Elf.dynRelBuffer dynSection
|
mRelBuffer <- runDynamic $ Elf.dynRelBuffer dynSection
|
||||||
mRelaBuffer <- runDynamic $ Elf.dynRelaBuffer dynSection
|
mRelaBuffer <- runDynamic $ Elf.dynRelaBuffer dynSection
|
||||||
SomeRelocationResolver resolver <- getRelocationResolver hdr
|
relocs0 <- addRelaEntries Map.empty dta resolver symtab mRelaBuffer
|
||||||
|
relocs1 <- addRelEntries relocs0 dta resolver symtab mRelBuffer
|
||||||
|
|
||||||
when (isJust mRelBuffer && isJust mRelaBuffer) $ do
|
when (isJust mRelBuffer && isJust mRelaBuffer) $ do
|
||||||
addWarning $ DynamicRelaAndRelPresent
|
addWarning $ MultipleRelocationTables
|
||||||
let dta = Elf.headerData hdr
|
|
||||||
loadtimeRelocs <-
|
case Elf.dynPLTRel dynSection of
|
||||||
relocMapFromRelAndRela dta resolver symtab mRelBuffer mRelaBuffer
|
Left e -> do
|
||||||
pltRelocs <-
|
addWarning $ RelocationParseFailure (show e)
|
||||||
case Elf.dynPLTRel dynSection of
|
pure $! relocs1
|
||||||
Left e -> do
|
Right Elf.PLTEmpty -> do
|
||||||
addWarning $ RelocationParseFailure (show e)
|
pure $! relocs1
|
||||||
pure $! Map.empty
|
Right (Elf.PLTRel entries) -> do
|
||||||
Right Elf.PLTEmpty -> do
|
addRelocEntries relocs1 $
|
||||||
pure $! Map.empty
|
zipWith (relocFromRel (toEndianness dta) symtab resolver) [0..] entries
|
||||||
Right (Elf.PLTRel entries) -> do
|
Right (Elf.PLTRela entries) -> do
|
||||||
pure $! Map.fromList $ zipWith (relocFromRel (toEndianness dta) symtab resolver) [0..] entries
|
addRelocEntries relocs1 $
|
||||||
Right (Elf.PLTRela entries) -> do
|
zipWith (relocFromRela symtab resolver) [0..] entries
|
||||||
pure $! Map.fromList $ zipWith (relocFromRela symtab resolver) [0..] entries
|
|
||||||
pure $ Map.union loadtimeRelocs pltRelocs
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
-- Elf segment loading
|
-- Elf segment loading
|
||||||
@ -1152,9 +1192,11 @@ insertAllocatedSection hdr symtab sectionMap regIdx nm = do
|
|||||||
-- Create memory segment
|
-- Create memory segment
|
||||||
SomeRelocationResolver resolver <- getRelocationResolver hdr
|
SomeRelocationResolver resolver <- getRelocationResolver hdr
|
||||||
when (isJust mRelBuffer && isJust mRelaBuffer) $ do
|
when (isJust mRelBuffer && isJust mRelaBuffer) $ do
|
||||||
addWarning $ SectionRelaAndRelPresent nm
|
addWarning $ MultipleRelocationTables
|
||||||
relocMap <-
|
relocMap <- do
|
||||||
relocMapFromRelAndRela (Elf.headerData hdr) resolver symtab mRelBuffer mRelaBuffer
|
let dta = Elf.headerData hdr
|
||||||
|
m1 <- addRelaEntries Map.empty dta resolver symtab mRelaBuffer
|
||||||
|
addRelEntries m1 dta resolver symtab mRelBuffer
|
||||||
seg <-
|
seg <-
|
||||||
memSegment relocMap regIdx 0 Nothing (fromIntegral base) flags bytes (fromIntegral secSize)
|
memSegment relocMap regIdx 0 Nothing (fromIntegral base) flags bytes (fromIntegral secSize)
|
||||||
-- Load memory segment.
|
-- Load memory segment.
|
||||||
|
Loading…
Reference in New Issue
Block a user